Friday 7 March 2014

Detect No-Sleep Issues in Android Applications

A wakelock is a software mechanism to control the power state of the host device. The OS exports explicit power management handles and APIs to specify when a particular component needs to stay on, or awake, until it is explicitly released from duty.
The wakelock mechanism is implemented in two levels: user and kernel. The figure shows the internal design of Android wakelock implementation. The user wakelock can be utilized by either high-level OS services or applications and is provided by the power management service. It allows an application to control the power state of the device. A kernel wakelock is held by the OS kernel or a driver. A user wakelock is mapped to a kernel wakelock. Any active kernel-level wakelock prevents the system from being suspended to ACPI S3 (suspended to RAM) state, which is the highest power saving state for mobile devices.

Different Levels Wake Locks

FULL_WAKE_LOCK -  Keep the screen at full brightness, keyboard back-light illuminated, and the CPU running.
SCREEN_BRIGHT_WAKE_LOCK - Keeps the screen at full brightness and the CPU running.
SCREEN_DIM_WAKE_LOCK - Keeps the screen ON but lets it dim and the CPU running.
PARTIAL_WAKE_LOCK -  Keeps the CPU running

Android permission for Waklock
                 Since wake locks has huge impact on battery life your application needs to request WAKE_LOCK permission in order to create them.
 <uses-permission  android:name="android.permission.WAKE_LOCK"  />

Create Wake Locks
                 To create a wake lock call newWakeLock on the Power manger as follows:
PowerManager.WakeLock wakeLock ;
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
 wakeLock = pm.newWakeLock( PowerManager.SCREEN_DIM_WAKE_LOCK, "My wakelook");

Acquire and Release Wake Locks
                  After creating wake lock, acquire it by calling acquire() method. We can optionally specify timeout to set the maximum time wake lock should be held for. When you wanted the wake lock to end, call release()method. After which the system will manage the power state.
In the following example I have acquired SCREEN_DIM_WAKE_LOCK, switching it ON will acquire the wake lock and OFF will release the wake lock.




MainActivity.java
import android.os.Bundle;
import android.os.PowerManager;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {

  PowerManager.WakeLock wakeLock;

  @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
 }

  public void acquirewakeLock(View v) {

   PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
  wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK,
    "My wakelook");
  wakeLock.acquire();
  Toast acquire = Toast.makeText(getApplicationContext(), "Wake Lock ON",
    Toast.LENGTH_SHORT);
  acquire.show();
 }

  public void releaseWakelock(View v) {
  wakeLock.release();
  Toast release = Toast.makeText(getApplicationContext(),
    "Wake Lock OFF", Toast.LENGTH_SHORT);
  release.show();
 }

  @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.activity_main, menu);
  return true;
 }

}


Source Code of this Application
WakeLock_Android.zip