3

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?

horin
  • 1,664
  • 6
  • 23
  • 52

1 Answers1

4

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?

Xavier Rubio Jansana
  • 6,388
  • 1
  • 27
  • 50
  • This also isn't a problem since I have temporarily solved this by checking Phone permission in app manager and if I test it using PackageManager says that READ_PHONE_STATE is granted – horin Feb 09 '17 at 09:35
  • Have you tried to Force stop your app after manually checking the permission and restart it again to make sure when the call is done the permission is already set? – Xavier Rubio Jansana Feb 09 '17 at 09:42
  • yes I have done it. As I said I do check permission state before registering receiver and system says that it is granted – horin Feb 09 '17 at 09:43
  • Then, maybe you can try using a PhoneStateListener https://developer.android.com/reference/android/telephony/PhoneStateListener.html Also this answer may provide some additional help https://stackoverflow.com/questions/31949063/action-phone-state-changed-not-called-on-network-cell-changes – Xavier Rubio Jansana Feb 09 '17 at 09:47
  • well I have tried PhoneStateListener inside activity and it works but the problem is that I want this to work inside service which is not possible with PhoneStateListener since it is not mentioned for background use. Thats why I tried to use simple BroadcastReceiver but still dont know why it is not firing – horin Feb 09 '17 at 09:51
  • there were absolutely no logs. Right now I have tried making a call and it fired receiver so PHONE_STATE works when I make a call but I would like it to work on signal strength change etc. – horin Feb 09 '17 at 10:08
  • From Android documentation "Broadcast intent action indicating that the **call state** on the device has changed." https://developer.android.com/reference/android/telephony/TelephonyManager.html#ACTION_PHONE_STATE_CHANGED So, this is only valid for call state (ringing, hang up, etc.) not for signal strength. It makes sense, as the notification will keep firing as the user moves around, draining user's battery. For that you have to use PhoneStateListener, I'm afraid. An option will be polling every few seconds, as the signal will change for sure (just by environmental changes this will happen). – Xavier Rubio Jansana Feb 09 '17 at 10:20
  • So there is no way to register phoneStateListener inside service? I have tried to not use time polling but as far as I can see if I register PhoneStateListener in service it simply gets unregistered after few secs – horin Feb 09 '17 at 10:25
  • Probably what's happening is that the service gets stopped after a few seconds, stopping also PhoneStateListener. As I said, it 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 https://stackoverflow.com/questions/1967136/how-to-get-cell-service-signal-strength-in-android. – Xavier Rubio Jansana Feb 09 '17 at 10:37