0

I am trying to create an flash light application which contains strobe function. I have successfully achieved flash light on/off effect but I am running into trouble with strobe effect. Whenever I try to create the strobe effect the application crashes. If I remove that, it works fine.

I have one activity with a seekbar at the top and the on/off switch at the center. What I want to achieve is that if the user clicks on/off button the flash light should toggle on/off if the seekbar at the top is at 0. If the user increase the value in seekbar the flash light should start to strobe accordingly and if the user move the value back to 0 flashlight should remain constant. Please help me fix the error.

LOG CAT

07-23 16:54:12.610: W/dalvikvm(21210): threadid=11: thread exiting with uncaught exception (group=0x40c15a68)
07-23 16:54:12.610: E/AndroidRuntime(21210): FATAL EXCEPTION: Thread-2373
07-23 16:54:12.610: E/AndroidRuntime(21210): java.lang.RuntimeException: Fail to connect to camera service
07-23 16:54:12.610: E/AndroidRuntime(21210):    at android.hardware.Camera.native_setup(Native Method)
07-23 16:54:12.610: E/AndroidRuntime(21210):    at android.hardware.Camera.<init>(Camera.java:365)
07-23 16:54:12.610: E/AndroidRuntime(21210):    at android.hardware.Camera.open(Camera.java:340)
07-23 16:54:12.610: E/AndroidRuntime(21210):    at com.shyam.flashlight.StrobeController.run(StrobeController.java:29)
07-23 16:54:12.610: E/AndroidRuntime(21210):    at java.lang.Thread.run(Thread.java:856)

FlashLight.java

public class FlashLight extends Activity {

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

StrobeController runner;
Thread bw;

@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_flash_light);

    btnSwitch = (ImageButton) findViewById(R.id.btnSwitch);

    runner = StrobeController.getInstance();

    bw = new Thread(runner);
    bw.start();

    hasFlash = getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);

    if (!hasFlash) {
        AlertDialog alert = new AlertDialog.Builder(FlashLight.this).create();
        alert.setTitle("Error");
        alert.setMessage("Sorry, your device doesn't support flash light!");
        alert.setButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                finish();
            }
        });
        alert.show();
        return;
    }

    getCamera();

    toggleButtonImage();

    btnSwitch.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            /*if (isFlashOn) {
                turnOffFlash();
            } else {
                turnOnFlash();
            }*/

            if (isFlashOn) {
                bw = new Thread(runner);
                bw.start();
                isFlashOn = false;
            } else {
                isFlashOn = true;
                runner.requestStop = true;
            }

        }
    });

    final SeekBar skbar = (SeekBar) findViewById(R.id.volume_bar);
    skbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) { }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) { }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            runner.delay = 101 - progress;
            runner.delayoff = 101 - progress;
        }
    });

}

private void getCamera() {
    if (camera == null) {
        try {
            camera = Camera.open();
            params = camera.getParameters();
        } catch (RuntimeException e) {
            Log.e("Camera Error. Failed to Open. Error: ", e.getMessage());
        }
    }
}

private void turnOnFlash() {
    if (!isFlashOn) {
        if (camera == null || params == null) {
            return;
        }

        playSound();

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

        toggleButtonImage();
    }
}

private void turnOffFlash() {
    if (isFlashOn) {
        if (camera == null || params == null) {
            return;
        }

        playSound();

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

        toggleButtonImage();
    }
}

private void playSound() {
    if (isFlashOn) {
        mp = MediaPlayer.create(FlashLight.this, R.raw.light_switch_off);
    } else {
        mp = MediaPlayer.create(FlashLight.this, R.raw.light_switch_on);
    }
    mp.setOnCompletionListener(new OnCompletionListener() {

        @Override
        public void onCompletion(MediaPlayer mp) {
            mp.release();
        }
    });
    mp.start();
}

private void toggleButtonImage() {
    if (isFlashOn) {
        btnSwitch.setImageResource(R.drawable.btn_switch_on);
    } else {
        btnSwitch.setImageResource(R.drawable.btn_switch_off);
    }
}

@Override
public void onBackPressed() {
    super.onBackPressed();

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

    if (camera != null) {
        camera.release();
        camera = null;
    }
    Log.d("Camera", "Back Pressed");
}

}

StrobeController.java

public class StrobeController implements Runnable {

protected StrobeController() { }

public static StrobeController getInstance() {
    return (instance == null ? instance = new StrobeController() : instance);
}

private static StrobeController instance;
public volatile boolean requestStop = false;
public volatile boolean isRunning = false;
public volatile int delay = 10;
public volatile int delayoff = 500;
public volatile String errorMessage = "";

@Override
public void run() {
    if (isRunning)
        return;

    requestStop = false;
    isRunning = true;

    Camera cam = Camera.open();

    Parameters pon = cam.getParameters(), poff = cam.getParameters();

    pon.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
    poff.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);

    while (!requestStop) {
        try {
            cam.setParameters(pon);
            Thread.sleep(delay);
            cam.setParameters(poff);
            Thread.sleep(delayoff);
        } catch (InterruptedException ex) {

        } catch (RuntimeException ex) {
            requestStop = true;
            errorMessage = "Error setting camera flash status. Your device may be unsupported.";
        }
    }

    cam.release();

    isRunning = false;
    requestStop = false;
}

}
android_newbie
  • 667
  • 2
  • 14
  • 32

1 Answers1

1

I notice the exception is being thrown at line 29:

at com.shyam.flashlight.StrobeController.run(StrobeController.java:29)

Is line 29 Camera cam = Camera.open();?

You have the correct permissions as described here? Also, are you trying to open a null camera? Look at what line 29 is in StrobeController class.

D-Dᴙum
  • 7,689
  • 8
  • 58
  • 97