Search code examples
androidtelephonymanagerandroid-7.0-nougat

TelephonyManager's PhoneStateListener is not called on Nougat


I have made a sample app and the 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));

Works as expected, but when I add the above code to my much larger application the onCallStateChanged is only called when it is subscribed initially. No phone state changes are notified to me. On both projects the bottom log line "READ_PHONE_STATE = " was always granted and I'm targeting sdk 22 so no runtime permissions I think. In my larger app I have the code pasted in both the main activity and a long standing service, neither get state change events. They both work when I run my code on an android < 7.0 and I have no idea why. Don't see anything substantial in the warning or error logs.


Solution

  • As Vairavan mentioned in this answer, there was an internal change in how the PhoneStateListener is referenced:

    Local reference to PhoneStateListener is kept track internally only by a weak reference. This makes it eligible for garbage collection upon function exit and once the listener is finalized, apps will not receive any further updates. Solution is to keep a reference to PhoneStateListener via class member variable.

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