Java – Android application crashes when closing an application using wakelock.release().

Android application crashes when closing an application using wakelock.release()…. here is a solution to the problem.

Android application crashes when closing an application using wakelock.release().

I have a simple flashlight app that works fine, but when the user closes the app, the app crashes. I think the problem is with the wakelock.

The wakelock is turned on when the flash is

on, and the wakelock is turned off when the flash is off. This works fine, but the application crashes as soon as the user presses Back or Home.

My log data:

10-24 09:52:45.235: E/AndroidRuntime(6614): Process:
r1d.org.uk.flashlight, PID: 6614 10-24 09:52:45.235:
E/AndroidRuntime(6614): java.lang.RuntimeException: Unable to destroy
activity {r1d.org.uk.flashlight/r1d.org.uk.flashlight.MainActivity}:
java.lang.RuntimeException: WakeLock under-locked MyWakelockTag 10-24
09:52:45.235: E/AndroidRuntime(6614): at
android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3812)

Main Activity:

public class MainActivity extends Activity {

private ImageView lightToggle;
    private ImageButton lightSwitch;
    Camera camera = null;
    Parameters parameters;
    Boolean isOn = false;
    int lightON = R.drawable.on;
    int lightOFF = R.drawable.off;
    int switchON = R.drawable.switch_on;
    int switchOFF = R.drawable.switch_off;
    Boolean hasFlash;
    PowerManager powerManager;
    PowerManager.WakeLock wakeLock;

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        AdManager ads = new AdManager(this);
        lightToggle = (ImageView) findViewById(R.id.lightOn);
        lightSwitch = (ImageButton) findViewById(R.id.lightSwitch);
        Context context = this;
        hasFlash = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
        powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakelockTag");

if(!hasFlash){
            ContextThemeWrapper themedContext;
            if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES. HONEYCOMB ) {
                themedContext = new ContextThemeWrapper( MainActivity.this, android. R.style.Theme_Holo_Light_Dialog_NoActionBar );
            }
            else {
                themedContext = new ContextThemeWrapper( MainActivity.this, android. R.style.Theme_Light_NoTitleBar );
            }
            AlertDialog.Builder builder = new AlertDialog.Builder(themedContext);
            builder.setTitle(getResources().getString(R.string.notsupported))
                    .setMessage(getResources().getString(R.string.notsupportedinfo))
                    .setIcon(android. R.drawable.ic_dialog_alert)
                    .setNegativeButton(getResources().getString(R.string.ok), new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int i) {
                            dialog.cancel();
                        }
                    });
            builder.show();
        }
        turnOn();
        lightSwitch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(isOn){
                    turnOff();
                } else {
                    turnOn();
                }
            }
        });
    }
    private void turnOn(){
        lightToggle.setImageDrawable(getResources().getDrawable(lightON));
        lightSwitch.setImageDrawable(getResources().getDrawable(switchON));
        wakeLock.acquire();
        if(hasFlash) {
            camera = Camera.open();
            parameters = camera.getParameters();
            parameters.setFlashMode(Parameters.FLASH_MODE_TORCH); FLASH_MODE_ON
            camera.setParameters(parameters);
        }
        isOn = true;
    }
    private void turnOff(){
        lightToggle.setImageDrawable(getResources().getDrawable(lightOFF));
        lightSwitch.setImageDrawable(getResources().getDrawable(switchOFF));
        wakeLock.release();
        if(hasFlash) {
            parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
            camera.setParameters(parameters);
            camera.release();
            camera = null;
        }
        isOn = false;
    }
    @Override
    public void onDestroy() {
        turnOff();
        super.onDestroy();
    }
    @Override
    public void onPause(){
        turnOff();
        super.onPause();
    }
    @Override
    public void onResume(){
        turnOn();
        super.onResume();
    }
}

Solution

In onDestroy, you attempted to release a wakelock that you have already released in onPause. This should work :

if (wakeLock.isHeld()) {
    wakeLock.release();
}

Related Problems and Solutions