问题
I have a receiver which waits for TelephonyManager.ACTION_PHONE_STATE_CHANGED
:
public void onReceive(Context context, Intent intent) {
String theAction = intent.getAction();
if (theAction != null && theAction.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
CONTEXT = context;
startListening();
}
When it gets it, I register the listener (for orientation sensor):
public void startListening() {
sensorManager = (SensorManager) CONTEXT.getSystemService(Context.SENSOR_SERVICE);
List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
if (sensors.size() > 0) {
sensor = sensors.get(0);
running = sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_FASTEST);
}
}
And then, in the Listener's onSensorChanged()
method:
public void onSensorChanged(SensorEvent event) {
if(running) {
sensorManager.unregisterListener(this);
// do some not significant stuff here
}
And now the problem: I get a phone call, receiver starts, then listener starts and everything works as designed. But, later on, when I look at the battery stats, my app is listed as the one with 2-3% of drain. And this percentage is increasing even though there are no calls - hence the receiver is not working.
Where does this battery drain come from? The activity which starts the receiver is not working (and it is single checkbox anyway). I suppose, that the listener may not get unregistered by sensorManager.unregisterListener(this);
, but it shoudl work - I unregister the listener when it received the first event, it makes sense.
How could I solve the problem?
回答1:
Where does this battery drain come from?
Never never never never never never never never have something in a manifest-registered BroadcastReceiver
live beyond onReceive()
. IOW, you cannot safely register a SensorListener
from a manifest-registered BroadcastReceiver
.
Please have your BroadcastReceiver
delegate work to a Service
(via startService()
), where in onStartCommand()
you register the SensorListener
. When you get a sensor reading, or after a timeout (hint: phones don't always change orientation), or in onDestroy()
(if Android decides to shut down your service), unregister the listener and call stopSelf()
to shut down the service.
来源:https://stackoverflow.com/questions/6883664/broadcastreceiver-with-a-listener-drains-battery-when-not-in-use