Reputation: 2491
I'm building a simple app that has BroadcastReciever
that listens to PHONE_STATE:
<receiver android:name=".PhoneStateBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
In the BroadcastReciever
's onRecieve()
I start a service when the state is OFFHOOK
and stop the service when the state is IDLE
:
public class PhoneStateBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
String state = bundle.getString(TelephonyManager.EXTRA_STATE);
if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
context.startService(new Intent(context, ProximityService.class));
}
else if(state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
context.stopService(new Intent(context, ProximityService.class));
}
}
}
In the service I'm registering proximity sensor listener, and creating a WakeLock
so the screen will turn off well while on call.
After the call ends I stop the service, and in its onDestroy()
I'm unregistering the listener and release the WakeLock
.
But it seems that something is not releasing out there because I see a huge battery drain from my app (30%).
I put a Log when the listener unregistering and also on the WakeLock
release, and I can see that the WakeLock
is released and the listener is unregistered successfully (I can also see the Log from SensorManager
that the listener is unregistered).
What am I missing here? That's really annoying.
Some code of the service:
public int onStartCommand(Intent intent, int flags, int startId){
Log.d("CALL", "Service started");
// Get an instance of the sensor service, and use that to get an instance of
// a particular sensor.
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
mAudioManager = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
mPowerMngr = (PowerManager) getSystemService(Context.POWER_SERVICE);
try{
mWakeLock = mPowerMngr.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, "Proximity");
if (!mWakeLock.isHeld()) {
Log.d("CALL", "Wake lock acquired");
mWakeLock.acquire();
}
}
catch (Exception e){
mWakeLock = null;
}
return START_STICKY;
}
public void onDestroy(){
super.onDestroy();
mSensorManager.unregisterListener(this);
if (mWakeLock != null) {
if (mWakeLock.isHeld()) {
Log.d("CALL", "Wake lock released");
mWakeLock.release();
}
}
Log.d("CALL", "Service stopped");
}
The log I see:
09-30 03:35:09.120: D/SensorManager(21565): unregisterListener:: disable all sensors for this listener, listener = com.eladaharon.android.proximity.ProximityService@41a31a18
09-30 03:35:09.125: D/CALL(21565): Wake lock released
09-30 03:35:09.125: D/CALL(21565): Service stopped
Thanks a lot! Elad
Upvotes: 2
Views: 1763
Reputation: 4821
If your service is receiving multiple intents, your code will create a new WakeLock
each time onStartCommand
is executed. You would be releasing only the last WakeLock
and leaking the others, which would explain the battery drain. Logcat will normally provide helpful messages in this situation.
Since your service remains running for a time, you could check whether mWakeLock
is initialized before calling newWakeLock()
.
Upvotes: 1