如何知道我是不是在 Android 上通话?

Posted

技术标签:

【中文标题】如何知道我是不是在 Android 上通话?【英文标题】:How to know whether I am in a call on Android?如何知道我是否在 Android 上通话? 【发布时间】:2011-08-22 09:08:29 【问题描述】:

我想知道我是否在通话中。

如果我正在通话,请启动服务(服务部分很清楚)。我该怎么做?

在接听电话时,我需要拨打服务电话...我不知道该怎么做?有什么帮助吗?

【问题讨论】:

您是指“电话”、“方法呼叫”还是其他呼叫? (求偶?谢幕?Lauren Bacall?:-)) 【参考方案1】:

你需要广播接收器...

在清单中声明广播接收器...

<receiver android:name=".PhoneStateBroadcastReceiver">
        <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE"/>     
        </intent-filter>
</receiver>

同时声明使用权限...

<uses-permission android:name="android.permission.READ_PHONE_STATE" />  

广播接收器类 ...

package x.y;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

public class PhoneStateBroadcastReceiver extends BroadcastReceiver

    @Override
    public void onReceive(Context context, Intent intent) 

        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        telephonyManager.listen(new CustomPhoneStateListener(context), PhoneStateListener.LISTEN_CALL_STATE);

    


还有一个自定义电话状态监听器的类...

package x.y;
import android.content.Context;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

public class CustomPhoneStateListener extends PhoneStateListener 

    //private static final String TAG = "PhoneStateChanged";
    Context context; //Context to make Toast if required 
    public CustomPhoneStateListener(Context context) 
        super();
        this.context = context;
    

    @Override
    public void onCallStateChanged(int state, String incomingNumber) 
        super.onCallStateChanged(state, incomingNumber);

        switch (state) 
        case TelephonyManager.CALL_STATE_IDLE:
            //when Idle i.e no call
            Toast.makeText(context, "Phone state Idle", Toast.LENGTH_LONG).show();
            break;
        case TelephonyManager.CALL_STATE_OFFHOOK:
            //when Off hook i.e in call
            //Make intent and start your service here
            Toast.makeText(context, "Phone state Off hook", Toast.LENGTH_LONG).show();
            break;
        case TelephonyManager.CALL_STATE_RINGING:
            //when Ringing
            Toast.makeText(context, "Phone state Ringing", Toast.LENGTH_LONG).show();
            break;
        default:
            break;
        
    

【讨论】:

安装此应用程序和手机接听电话时出现一个问题...在调试模式下,控件不会进入 onReceive vaibhav ..在 CALL_STATE_RINGING 之后:我放了 system.out.println("rining") 我放了一个断点..并在电话中调试..我从另一部电话打来...状态是响铃..断点是否应该被击中.?它不会发生.. 第一次电话响起时检查 logcat case TelephonyManager.CALL_STATE_RINGING:它打印 logcat 一次...第二次调用它打印两次...第三次...它是这样的 这是因为您正在泄漏侦听器。 启动 Android O 需要获取应用权限才能读取手机状态【参考方案2】:

TelephonyManager.getCallState() 返回其中之一

CALL_STATE_IDLE CALL_STATE_OFFHOOK CALL_STATE_RINGING

如果这符合您的要求,那么它的代码比 Pied Piper 更全面的解决方案要少得多。

【讨论】:

我认为这是一个更好的解决方案。在第一种情况下,每次电话状态更改都会添加一个新侦听器。 +1 我不知道这种方法存在。但是这种方法只有在我们想知道特定时间的通话状态时才有帮助,但对于始终监控电话状态没有帮助。 ((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE)).getCallState() 新手【参考方案3】:

您只能知道来电,但不能修改。 :( 看到这个 why 2.3 version of android does not hava android.permission.MODIFY_PHONE_STATE ? and what is the solution for this?

【讨论】:

【参考方案4】:

毫无疑问,这是一个老问题。但它作为谷歌的第一个结果弹出。因此,我决定添加另一个有用的方法。

当手机状态改变时,系统发送TelephonyManager.ACTION_PHONE_STATE_CHANGED广播。此广播有一个额外的状态,可以使用TelephonyManager.EXTRA_STATE 提取。

额外的状态可以有三种选择:

EXTRA_STATE_IDLE EXTRA_STATE_OFFHOOK EXTRA_STATE_RINGING

您可以设计一个广播接收器来处理所有这些问题:

public class PhoneStateReceiver extends BroadcastReceiver 

    @Override
    public void onReceive(Context context, Intent intent)

        if (intent.getAction().equals(TelephonyManager.ACTION_CALL_STATE_CHANGED)

            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);

            if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)

                // No call currently active.

             else if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)

                // A call is ringing

             else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)

                // Call has been answered.

            
        
    

您可以在此处阅读更多信息:

https://developer.android.com/reference/android/telephony/TelephonyManager#ACTION_PHONE_STATE_CHANGED

注意:广播接收器将在后台触发,从 Android O+ 开始,您无法从后台进程启动后台服务。考虑使用context.startForegroundService(intent) 启动前台服务。在服务的onStartCommand(...),调用startForeground(...)。否则,系统会引发致命异常。但是,在 Android O 之下,您可以安全地使用context.startService(intent) 而不是startForegroundService(...)

【讨论】:

以上是关于如何知道我是不是在 Android 上通话?的主要内容,如果未能解决你的问题,请参考以下文章

如何在android手机上合并两个gsm和voip通话

如何在 Android 网络浏览器上通过 agora 使用通话声音而不是媒体声音?

使用 ALSA/CAF 进行 Android 通话录音

在android中流式传输通话语音?

语音通话开始时如何开始?

使用webrtc for android,如何在视频通话中保存图片?