L7ColWinters
L7ColWinters

Reputation: 1362

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.

Upvotes: 3

Views: 4452

Answers (2)

TheIT
TheIT

Reputation: 12219

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.

Upvotes: 4

user3099473
user3099473

Reputation: 31

Try registering your listener in onCreate method of your service. It's works for me.Find example code below :

    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");
        } 
    }
};

Upvotes: 3

Related Questions