Reputation: 1135
I have a simple flash light app that works well but when the user closes the app the app crashes. I presume the problem is with the wakelock.
When the flash is on the the wakelock is turned on, when the flash is turned off the wakelock is turned off. This works fine but as soon as the user presses back or home the app crashes.
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)
MainActivity:
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();
}
}
Upvotes: 3
Views: 1857
Reputation: 38223
In onDestroy
you're trying to release a wakelock which you already released in onPause
. This should work:
if (wakeLock.isHeld()) {
wakeLock.release();
}
Upvotes: 4