android - 无法检测到在 Android 中何时接听了拨出电话

标签 android broadcastreceiver

为了检测拨出电话何时被应答,我尝试创建一个 PhoneStateListener 并监听 TelephonyManagerCALL_STATE_RINGINGCALL_STATE_OFFHOOK CALL_STATE_IDLE,来自 this question ,但它似乎不起作用,如下所述。

首先,我在 list 中注册了以下权限:

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

然后,一个名为 OutCallLoggerBroadcastReceiver 捕获 NEW_OUTGOING_CALL 事件:

<receiver android:name=".listener.OutCallLogger">
    <intent-filter>
        <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
    </intent-filter>
</receiver>

接下来,我的 OutCallLogger 实现。我设置了一个名为 noCallListenerYet 的 bool 值,以避免在调用 onReceive() 时将新的 PhoneStateListener 附加到 TelephonyManager .

public class OutCallLogger extends BroadcastReceiver {

    private static boolean noCallListenerYet = true;

    @Override
    public void onReceive(final Context context, Intent intent) {
        number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
        if (noCallListenerYet) {
            final TelephonyManager tm = (TelephonyManager) context.getSystemService(
                    Context.TELEPHONY_SERVICE);
            tm.listen(new PhoneStateListener() {
                @Override
                public void onCallStateChanged(int state, String incomingNumber) {
                    switch (state) {
                        case TelephonyManager.CALL_STATE_RINGING:
                            Log.d(This.LOG_TAG, "RINGING");
                            break;
                        case TelephonyManager.CALL_STATE_OFFHOOK:
                            Log.d(This.LOG_TAG, "OFFHOOK");
                            break;
                        case TelephonyManager.CALL_STATE_IDLE:
                            Log.d(This.LOG_TAG, "IDLE");
                            break;
                        default:
                            Log.d(This.LOG_TAG, "Default: " + state);
                            break;
                    }
                }
            }, PhoneStateListener.LISTEN_CALL_STATE);
            noCallListenerYet = false;
        }
    }

}

现在,当我在我的设备中拨出电话时,CALL_STATE_RINGING 永远不会被调用。我总是只会在另一个打印输出“IDLE”到“OFFHOOK”时线路开始响铃,接听后没有声音,通话结束时再次打印“IDLE”。

我怎样才能可靠地检测到在 Android 中何时接听了拨出电话,或者这是否可能?

最佳答案

从 Android 5.0 开始,这对于系统应用程序是可能的。但是您需要使用隐藏的 Android API。

我让它像这样工作:

<uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" />
<receiver android:name=".listener.OutCallLogger">
    <intent-filter>
        <action android:name="android.intent.action.PRECISE_CALL_STATE" />
    </intent-filter>
</receiver>
public class OutCallLogger extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        switch (intent.getIntExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, -2) {
            case PreciseCallState.PRECISE_CALL_STATE_IDLE:
                Log.d(This.LOG_TAG, "IDLE");
                break;
            case PreciseCallState.PRECISE_CALL_STATE_DIALING:
                Log.d(This.LOG_TAG, "DIALING");
                break;
            case PreciseCallState.PRECISE_CALL_STATE_ALERTING:
                Log.d(This.LOG_TAG, "ALERTING");
                break;
            case PreciseCallState.PRECISE_CALL_STATE_ACTIVE:
                Log.d(This.LOG_TAG, "ACTIVE");
                break;
        }
    }
}

您可以在 PreciseCallState.java 中找到所有可能的通话状态以及Intent bundle 含在 TelephonyRegistry.java 中的所有额外内容.

关于android - 无法检测到在 Android 中何时接听了拨出电话,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13134331/

相关文章:

java - AndroidPdfViewer - 无法从 Assets 文件夹中打开 PDF 文档

android - 如何向 list 中的接收者发送自定义广播操作?

android - 如何始终收听短信android

android - 修复 Eclipse 调试认证错误的现有方法不起作用

android - 使用自定义可绘制对象的自定义开关显得很大

android - DialogFragment 中的 VideoView

Android.mk *** 缺少分隔符。停止。预建库的 LOCAL_SRC_FILES 应该只包含一个项目

android - 为什么 Android 会忽略通知的创建?

java - 如何在启动完成时发送通知?

android - 读取传入消息,直到读取验证短信