Search code examples
androidbroadcastreceiverphone-state-listener

Phone state changed listener never fired


I am trying to create Phone state changed listener inside service. My service extends basic Service so no IntentService or anything like that.

Receiver is basic BroadcastReceiver which I register like this:

IntentFilter filter = new IntentFilter();
filter.addAction(TelephoneManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(receiver, filter);

However my receiver onReceive is never called. What am I missing? If I change filter action to Intent.ACTION_SCREEN_OFF for example, I am getting onReceive every time I turn screen off so I think that there is maybe some problem in my IntentFilter. I want to use this to listen for incoming calls, signal strength, cell id change and all that stuff. I have registered READ_PHONE_STATE permission in manifest so this should not be a problem. My device is Nexus 5X with Android 6.0.1

Any ideas?


Solution

  • From Android documentation, as you're trying to use a dangerous permission you need to request access to it. See here the difference between Dangerous and Normal permissions: Requesting Permissions - Normal and Dangerous Permissions.

    Information on how to request the permissions: Requesting Permissions at Run Time.

    A quick workaround will be to reduce your target API to 22 (something below 23), but that should be a temporary solution.

    About signal strength, it's not possible to get the information by registering ACTION_PHONE_STATE_CHANGED. From Android documentation the functionality is:

    Broadcast intent action indicating that the call state on the device has changed.

    So, this is only valid for call state (ringing, hang up, etc.) not for signal strength. This makes sense as the signal strength will be changing several times per second, and this big number of events per second will drain the battery very quickly.

    Maybe an option will be a two level approach: use PhoneStateListener from inside an Activity when your app is foreground, and use TelephonyManager.get*CellInfo() every few seconds when in background. See also this question: How to get cell service signal strength in Android?