0

Hey guys I'm working on a flashlight app using an online tutorial. I've made few changes to the app. I wanted the flashlight to stay on if the user goes to the home-screen or locks the screen. However when I do this and open default camera app and then open my flashlight app again, the flashlight doesn't work anymore.

Steps to reproduce error:

  1. Turn on App(Turns flash automatically)
  2. Press Homescreen button(Flash stays on)
  3. Open default camera app(Flash turns off)
  4. Open flashlight app again(The on/off button doesn't work, flash stays off)

My code:

package ali.simpleflaslight;

import android.app.Activity;
import android.os.Bundle;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.view.View;
import android.widget.ImageButton;

public class MainActivity extends Activity {

  ImageButton btnSwitch;
  private Camera camera;
  private boolean isFlashOn;
  private boolean hasFlash;
  Parameters params;
  MediaPlayer mp;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      try {
        //================================== Flash Switch Button =============================//
        btnSwitch = (ImageButton) findViewById(R.id.btnSwitch);
        //================================== First Check =====================================//
        hasFlash = getApplicationContext().getPackageManager()
          .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);

        if (!hasFlash) {
          AlertDialog alert = new AlertDialog.Builder(MainActivity.this)
            .create();
          alert.setTitle("Error");
          alert.setMessage("Sorry, your device doesn't support a flashlight!");
          alert.setButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
              // closing the application
              finish();
            }
          });
          alert.show();
          return;
        }
        getCamera();
        toggleButtonImage();
        btnSwitch.setOnClickListener(new View.OnClickListener() {@
          Override
          public void onClick(View v) {
            if (isFlashOn) {
              // turn off flash
              turnOffFlash();
            } else {
              // turn on flash
              turnOnFlash();
            }
          }
        });
      } catch (Exception e) {}
    }
    //====================================== Getting Camera Parameters ===========================//
  private void getCamera() {
      try {
        if (camera == null) {
          try {
            camera = Camera.open();
            params = camera.getParameters();
          } catch (Exception e) {}
        }
      } catch (Exception e) {}
    }
    //====================================== Turning On Flash ====================================//
  private void turnOnFlash() {
      try {
        if (!isFlashOn) {
          if (camera == null || params == null) {
            return;
          }
          //Play Sound
          playSound();

          params = camera.getParameters();
          params.setFlashMode(Parameters.FLASH_MODE_TORCH);
          camera.setParameters(params);
          camera.startPreview();
          isFlashOn = true;

          //Changing Button/Switch Image
          toggleButtonImage();
        }
      } catch (Exception e) {}
    }
    //====================================== Turning Off Flash ===================================//
  private void turnOffFlash() {
      try {
        if (isFlashOn) {
          if (camera == null || params == null) {
            return;
          }
          //Play Sound
          playSound();

          params = camera.getParameters();
          params.setFlashMode(Parameters.FLASH_MODE_OFF);
          camera.setParameters(params);
          camera.stopPreview();
          isFlashOn = false;

          //Changing Button/Switch Image
          toggleButtonImage();
        }
      } catch (Exception e) {}
    }
    //====================================== Toggle Image ========================================//
  private void toggleButtonImage() {
      try {
        if (isFlashOn) {
          btnSwitch.setImageResource(R.drawable.btn_switch_on);
        } else {
          btnSwitch.setImageResource(R.drawable.btn_switch_off);
        }
      } catch (Exception e) {}
    }
    //====================================== Play Sound ==========================================//
  private void playSound() {
    try {
      if (isFlashOn) {
        mp = MediaPlayer.create(MainActivity.this, R.raw.light_switch_off);
      } else {
        mp = MediaPlayer.create(MainActivity.this, R.raw.light_switch_on);
      }
      mp.setOnCompletionListener(new OnCompletionListener() {

        @Override
        public void onCompletion(MediaPlayer mp) {
          // TODO Auto-generated method stub
          mp.release();
        }
      });
      mp.start();
    } catch (Exception e) {}
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
  }

  @Override
  protected void onPause() {
    super.onPause();
    //================================== On Pause Turn Off The Flash =========================//
    //turnOffFlash();

  }

  @Override
  protected void onRestart() {
    super.onRestart();
  }

  @Override
  protected void onResume() {
    super.onResume();
    //================================== On Resume Turn On The Flash =========================//
    if (hasFlash) {
      turnOnFlash();
    }
  }

  @Override
  protected void onStart() {
    super.onStart();
    //================================== On Starting The App Get The Camera Params============//
    getCamera();
  }

  @Override
  protected void onStop() {
    super.onStop();
    // on stop release the camera
    /*if (camera != null) {
        camera.release();
        camera = null;
    }*/
  }
}

The app stops working after I comment the code in onStop. It is surprising to see that all the top flashlight apps in Playstore that do support the background flash, stop working if the steps above are followed with them. For me however the app just stops doing anything since I have try catch phrases, I guess. Is there any solution to this?

Edit:

Error after putting getCamera before onResume(and doing the same steps as above):

05 - 08 19: 41: 10.955 4378 - 4378 / ali.simpleflaslight W / System.err﹕ java.lang.RuntimeException: getParameters failed(empty parameters)
05 - 08 19: 41: 10.955 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at android.hardware.Camera.native_getParameters(Native Method)
05 - 08 19: 41: 10.955 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at android.hardware.Camera.getParameters(Camera.java: 2075)
05 - 08 19: 41: 10.955 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at ali.simpleflaslight.MainActivity.turnOffFlash(MainActivity.java: 114)
05 - 08 19: 41: 10.956 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at ali.simpleflaslight.MainActivity.access$100(MainActivity.java: 15)
05 - 08 19: 41: 10.956 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at ali.simpleflaslight.MainActivity$2.onClick(MainActivity.java: 56)
05 - 08 19: 41: 10.956 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at android.view.View.performClick(View.java: 4764)
05 - 08 19: 41: 10.956 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at android.view.View$PerformClick.run(View.java: 19833)
05 - 08 19: 41: 10.956 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at android.os.Handler.handleCallback(Handler.java: 739)
05 - 08 19: 41: 10.956 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at android.os.Handler.dispatchMessage(Handler.java: 95)
05 - 08 19: 41: 10.956 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at android.os.Looper.loop(Looper.java: 135)
05 - 08 19: 41: 10.956 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at android.app.ActivityThread.main(ActivityThread.java: 5292)
05 - 08 19: 41: 10.956 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at java.lang.reflect.Method.invoke(Native Method)
05 - 08 19: 41: 10.956 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at java.lang.reflect.Method.invoke(Method.java: 372)
05 - 08 19: 41: 10.956 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java: 908)
05 - 08 19: 41: 10.956 4378 - 4378 / ali.simpleflaslight W / System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 703)
Muhammad Ali
  • 3,478
  • 5
  • 19
  • 30

1 Answers1

0

Firstly, you have try / catch blocks where the catch(Exception e) block does absolutely nothing - NEVER do that - it's probably one of the worst ways to program for exceptions. At the very least add e.printStackTrace() into the catch block and then monitor logcat for exceptions - I'm pretty sure you'll find some being logged.

Secondly, only one app can use the camera at a time. Best practice is to release() the camera in onPause() method and open() it again in onResume(). As you want the flashlight to stay on, then it might be considered acceptable for you not to release() the camera - the built-in camera will almost certainly follow best practice and your flashlight will be going off when it calls open() and it will then release() leaving the camera in a 'reset' stage.

Try removing the call to getCamera() from your onCreate(...) method and put it in onResume() instead (before calling turnOnFlash().

Squonk
  • 48,735
  • 19
  • 103
  • 135