Elad92
Elad92

Reputation: 2491

My app drains battery even that I release wake lock

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

Answers (1)

acj
acj

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

Related Questions