I have been writing a simple flash light app that has an on/off toggle button. The app starts and I click the 'on' button the flash comes on a stays on until I click the 'off' button, but if I click the 'on' button a second time the flash does not light up and I can't figure out why.
It is a simple app and here's the code:
package com.redcricket.flashlife;
import java.io.IOException;
import java.util.Collection;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.CompoundButton;
import android.widget.Toast;
import android.widget.ToggleButton;
public class FlashlightActivity extends Activity implements
SurfaceHolder.Callback {
private static String TAG = "flashlight";
private ToggleButton toggleButton1;
boolean cameraOpened;
private boolean hasSurface;
static Camera cam = null;
@Override
public void onPause() {
Log.i(TAG, "[32] onPause()");
super.onPause();
if (cam != null) {
Log.i("flashlight", "[35] onPause() cam not null. Calling stopPreview and release cam. Setting cam to null.");
cam.stopPreview();
cam.release();
cam = null;
}
}
public void turnFlashOn() {
Log.i(TAG, "[42] turnFlashOn()");
if (cam == null) {
cam = Camera.open();
Log.i(TAG, "[64] turnFlashOn() cam was null. Camera.open() called");
}
if (cam != null) {
Log.i(TAG, "[67] turnFlashOn() cam nit null. calling setDesiredCameraParameters(cam).");
setDesiredCameraParameters(cam);
Log.i(TAG, "[69] turnFlashOn() before startPreview");
/*
* step 6
* http://developer.android.com/reference/android/hardware/Camera.html
*/
cam.startPreview();
Log.i(TAG,"[75] turnFlashOn() after startPreview");
cam.autoFocus(new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
Log.i(TAG,
"[80] turnFlashOn() onAutoFocus success = true");
} else {
Log.i(TAG,
"[83] turnFlashOn() onAutoFocus success = false");
}
}
});
//Log.i(TAG,"[69] turnFlashOn() after cam.autoFocus TAKEPIC");
//cam.takePicture(null, null, null, null);
}
}
void setDesiredCameraParameters(Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Log.i("flashlight",
"[77] FlashlightActivity.java setDestiredVcmaeria paramers");
if (parameters == null) {
Log.w(TAG,
"Device error: no camera parameters are available. Proceeding without configuration.");
return;
}
Log.i(TAG, "[84] Initial camera parameters: " + parameters.flatten());
// SharedPreferences prefs =
// PreferenceManager.getDefaultSharedPreferences(context);
initializeTorch(parameters);
camera.setParameters(parameters);
}
private void initializeTorch(Camera.Parameters parameters) {
Log.i(TAG, "[95] initializeTorch()");
doSetTorch(parameters);
}
private void doSetTorch(Camera.Parameters parameters) {
Log.i(TAG, "[100] dosetTorch()");
String flashMode;
flashMode = findSettableValue(parameters.getSupportedFlashModes(),
Camera.Parameters.FLASH_MODE_TORCH);
Log.i(TAG, "[104] doSetTorch() flashmode is " + flashMode);
// ,
// Camera.Parameters.FLASH_MODE_ON,
// Camera.Parameters.FOCUS_MODE_INFINITY);
if (flashMode != null) {
Log.i(TAG, "[109] openDriver() called parameters.setFlashMode( " + flashMode + ")");
parameters.setFlashMode(flashMode);
}
}
private static String findSettableValue(Collection<String> supportedValues,
String... desiredValues) {
Log.i(TAG, "[117] findSettableValue() Supported values: " + supportedValues);
String result = null;
if (supportedValues != null) {
for (String desiredValue : desiredValues) {
if (supportedValues.contains(desiredValue)) {
result = desiredValue;
Log.i("flashlight", "[123] findSettableValue() result set to : " + desiredValue);
break;
}
}
}
Log.i("flashlight", "[128] findSettableValue() Settable value: " + result);
return result;
}
public void turnFlashOff() {
Log.i("flashlight", "[133] turnFlashOff()");
if (cam != null) {
Log.i("flashlight", "[135] turnFlashOff() cam is not null.");
cam.stopPreview();
cam.release();
cam = null;
}
}
public void addListenerOnButton() {
Log.i("flashlight", "[143] addListenerOnButton()");
toggleButton1 = (ToggleButton) findViewById(R.id.toggleButton1);
toggleButton1.setOnCheckedChangeListener(
new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.i("flashlight", "[148] onCheckedChanged() isChecked = " + isChecked);
if (isChecked) {
turnFlashOn();
} else {
turnFlashOff();
}
}
});
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "[163] onCreate() hasSurface is " + hasSurface );
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) {
// The activity was paused but not stopped, so the surface still
// exists. Therefore
// surfaceCreated() won't be called, so init the camera here.
Log.i(TAG, "[174] onCreate() calling initCamera() hasSurface is " + hasSurface );
initCamera(surfaceHolder);
} else {
Log.i(TAG, "[177] does not have surface, so install callback and wait for surfaceCreated() to init the camera");
// Install the callback and wait for surfaceCreated() to init the
// camera.
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
if (this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
cam = Camera.open();
Log.i(TAG, "[202] onCreate(). Camera.open() called");
addListenerOnButton();
} else {
Toast.makeText(getApplicationContext(),
"This device does not have flash bulb.\nExitting.", 60)
.show();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.i(TAG, "[196] surfaceCreated() hasSurface is " + hasSurface );
if (holder == null) {
Log.e(TAG,
"*** WARNING *** surfaceCreated() gave us a null surface!");
}
if (!hasSurface) {
hasSurface = true;
Log.i("flashlight", "[201] surfaceCreated() set hasSurface to true.");
initCamera(holder);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i("flashlight", "[209] surfaceDestroyed()");
hasSurface = false;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.i("flashlight", "[216] surfaceChanged(holder,format,width,height)");
}
@Override
protected void onDestroy() {
Log.i("flashlight", "[220] onDestroy()");
try {
cam.stopPreview();
cam.setPreviewCallback(null);
try {
cam.release();
} catch (Exception e) {
}
cam = null;
} catch (Exception e) {
}
super.onDestroy();
}
/* new stuff */
private void initCamera(SurfaceHolder surfaceHolder) {
Log.i(TAG, "[236] initCamera() trying to call openDriver(holder)");
try {
openDriver(surfaceHolder);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Opens the camera driver and initializes the hardware parameters.
*
* @param holder
* The surface object which the camera will draw preview frames
* into.
* @throws IOException
* Indicates the camera driver failed to open.
*/
public synchronized void openDriver(SurfaceHolder holder)
throws IOException {
Log.i(TAG, "[256] openDriver() top");
Camera theCamera = cam;
if (theCamera == null) {
Log.i(TAG, "[278] openDriver()");
theCamera = Camera.open();
Log.i(TAG, "[280] openDriver() Camera.open() called");
if (theCamera == null) {
Log.i(TAG, "[263] openDriver()");
throw new IOException();
}
cam = theCamera;
}
/*
* do this as per
* http://developer.android.com/reference/android/hardware/Camera.html
* step 5
*/
Log.i(TAG, "[281] openDriver() calling setPreviewDisplay(holder)");
theCamera.setPreviewDisplay(holder);
}
public synchronized boolean isOpen() {
return cam != null;
}
/**
* Closes the camera driver if still in use.
*/
public synchronized void closeDriver() {
Log.i(TAG, "[285] closeDriver()");
if (cam != null) {
cam.release();
cam = null;
}
}
/* end new stuff */
}
Here's the logcat with my comments inline:
[163] onCreate() hasSurface is false
[177] does not have surface, so install callback and wait for surfaceCreated() to init the camera
[202] onCreate(). Camera.open() called
[143] addListenerOnButton()
[196] surfaceCreated() hasSurface is false
[201] surfaceCreated() set hasSurface to true.
[236] initCamera() trying to call openDriver(holder)
[256] openDriver() top
[281] openDriver() calling setPreviewDisplay(holder)
[216] surfaceChanged(holder,format,width,height)
[148] onCheckedChanged() isChecked = true
[42] turnFlashOn()
[67] turnFlashOn() cam nit null. calling setDesiredCameraParameters(cam).
[77] FlashlightActivity.java setDestiredVcmaeria paramers
[84] Initial camera parameters: very long line
[95] initializeTorch()
[100] dosetTorch()
[117] findSettableValue() Supported values: [off, on, auto, torch]
[123] findSettableValue() result set to : torch
[128] findSettableValue() Settable value: torch
[104] doSetTorch() flashmode is torch
[109] openDriver() called parameters.setFlashMode( torch)
[69] turnFlashOn() before startPreview
[75] turnFlashOn() after startPreview
[80] turnFlashOn() onAutoFocus success = true
Hurray! The light is on! So I click the off button.
[148] onCheckedChanged() isChecked = false
[133] turnFlashOff()
[135] turnFlashOff() cam is not null.
Hurray! The light goes off. So now I click the on button.
[148] onCheckedChanged() isChecked = true
[42] turnFlashOn()
[64] turnFlashOn() cam was null. Camera.open() called
[67] turnFlashOn() cam nit null. calling setDesiredCameraParameters(cam).
[77] FlashlightActivity.java setDestiredVcmaeria paramers
[84] Initial camera parameters: very long line
[95] initializeTorch()
[100] dosetTorch()
[117] findSettableValue() Supported values: [off, on, auto, torch]
[123] findSettableValue() result set to : torch
[128] findSettableValue() Settable value: torch
[104] doSetTorch() flashmode is torch
[109] openDriver() called parameters.setFlashMode( torch)
[69] turnFlashOn() before startPreview
[75] turnFlashOn() after startPreview
Boo! No light :(
[148] onCheckedChanged() isChecked = false
[133] turnFlashOff()
[135] turnFlashOff() cam is not null.
[32] onPause()
[209] surfaceDestroyed()