I want to get the battery status of an Android device at regular intervals.
As it is a bad idea to poll for battery changes every couple of minutes, I wanted to use a repeating alarm, which goes off maybe once an hour, to call a class which gets the current battery status.
However my current implementation is giving me an exception:
android.content.ReceiverCallNotAllowedException: IntentReceiver components are not allowed to register to receive intents.
The class which is called when the alarm times out is as follows:
public class GetBatteryStatusTimeout extends BroadcastReceiver{
private static final String TAG = "GetBatteryStatusTimeout";
@Override
public void onReceive(Context context, Intent intent) {
BatteryDataManager batteryData = new BatteryDataManager(context);
batteryData.getStatus();
Log.e(TAG, "GetBatteryStatus timer expired, getting status");
}
}
The getStatus()
method calls the code to register for the sticky intent and get the battery status:
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING;
boolean fullyCharged = status == BatteryManager.BATTERY_STATUS_FULL;
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
It is the point at which I register for this receiver that the exception is thrown.
I understand what the exception is saying (I think!) but I am not calling the code to register for the sticky intent from within another receiver?
The alarm receiver calls another class which then registers the receiver for the battery changed intents.... but obviously this isn't allowed either?
What is the alternative?
Also the exception is only thrown on some devices, and the app works fine on others?