在Nougat上不调用TelephonyManager的PhoneStateListener

时间:2016-10-21 19:11:32

标签: android telephonymanager android-7.0-nougat

我制作了一个示例应用和PhoneStateListener

TelephonyManager telephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); //TelephonyManager object
    telephony.listen(new PhoneStateListener() {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            Log.i("brian", "call state = " + state + " incoming number " + incomingNumber);
            switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:
                    break;
                case TelephonyManager.CALL_STATE_RINGING:

                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:

                    break;
            }
        }
    }, PhoneStateListener.LISTEN_CALL_STATE); //Register our listener with TelephonyManager

    Log.i("brian", "READ_PHONE_STATE = " + ContextCompat.checkSelfPermission(this,
            Manifest.permission.READ_PHONE_STATE));

按预期工作,但是当我将上面的代码添加到我更大的应用程序时,onCallStateChanged仅在最初订阅时被调用。没有电话状态更改通知给我。在这两个项目中,底部日志行“READ_PHONE_STATE =”总是被授予,我的目标是sdk 22,所以我认为没有运行时权限。在我的大型应用程序中,我将代码粘贴在主要活动和长期服务中,既没有获得状态更改事件。当我在android<上运行我的代码时它们都工作。 7.0,我不知道为什么。在警告或错误日志中看不到任何实质内容。

2 个答案:

答案 0 :(得分:3)

尝试在服务的onCreate方法中注册您的侦听器。它对我有用。查看下面的示例代码:

    private TelephonyManager tm;

    @Override
    public void onCreate() {
        super.onCreate();

        //Set listener for TelephonyManager tm.
        tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        tm.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }


private PhoneStateListener phoneStateListener = new PhoneStateListener() {
    public void onCallStateChanged(int state, String incomingNumber) {

        if (state == TelephonyManager.CALL_STATE_RINGING) {
                    Log.i(LOG_TAG,"State : RING RING");

        }
        if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
                    Log.i(LOG_TAG,"State : OFFHOOK");
        }

        if (state == TelephonyManager.CALL_STATE_IDLE) {
                    Log.i(LOG_TAG,"State : IDLE");
        } 
    }
};

答案 1 :(得分:2)

正如Vairavan在this答案中提到的那样,PhoneStateListener的引用方式发生了内部变化:

  

仅通过以下方式在内部跟踪对PhoneStateListener的本地引用   薄弱的参考。这使得它有资格进行垃圾回收   函数退出,并且一旦侦听器完成,应用程序将不会   接收任何进一步的更新。解决方案是保留对   通过类成员变量的PhoneStateListener。

请参阅:https://github.com/aosp-mirror/platform_frameworks_base/commit/f5d7c587e86c64e657a15a12ad70e75d47c48d99#diff-5af2ac899de823cf60597e554bf67fe0