Android的手电筒应用程序停止工作 [英] Android Flashlight App stops working
问题描述
我一直在写有一个开/关切换按钮一个简单的闪光灯应用。应用程序启动时,我点击打开按钮闪光灯亮起,直到我点击关闭按钮停留,但如果我点击打开按钮,第二次闪光灯不亮,我不能找出原因。
这是一个简单的应用程序,这里的code:
包com.redcricket.flashlife;进口java.io.IOException异常;
进口java.util.Collection中;进口android.app.Activity;
进口android.content.pm.PackageManager;
进口android.hardware.Camera;
进口android.hardware.Camera.AutoFocusCallback;
进口android.os.Bundle;
进口android.util.Log;
进口android.view.SurfaceHolder;
进口android.view.SurfaceView;
进口android.widget.CompoundButton;
进口android.widget.Toast;
进口android.widget.ToggleButton;公共类FlashlightActivity扩展活动器具
SurfaceHolder.Callback { 私有静态字符串标记=手电筒
私人切换按钮toggleButton1;
布尔cameraOpened;
私人布尔hasSurface;
静态照相机CAM = NULL; @覆盖
公共无效的onPause(){
Log.i(TAG,[32]的onPause());
super.onPause();
如果(凸轮!= NULL){
Log.i(手电筒,[35]的onPause()凸轮NOT NULL调用停止preVIEW和释放凸轮凸轮设置为null。);
cam.stop preVIEW();
cam.release();
凸轮= NULL;
}
} 公共无效turnFlashOn(){
Log.i(TAG,[42] turnFlashOn());
如果(凸轮== NULL){
凸轮= Camera.open();
Log.i(TAG,[64] turnFlashOn()凸轮为空Camera.open()调用。);
}
如果(凸轮!= NULL){
Log.i(TAG,[67] turnFlashOn()凸轮尼特空调用setDesiredCameraParameters(CAM)。);
setDesiredCameraParameters(凸轮);
Log.i(TAG,[69] turnFlashOn()之前开始preVIEW);
/ *
*步骤6
* http://developer.android.com/reference/android/hardware/Camera.html
* /
cam.start preVIEW();
Log.i(TAG,[75] turnFlashOn()后启动preVIEW);
cam.autoFocus(新AutoFocusCallback(){
公共无效onAutoFocus(布尔成功,相机摄像头){
如果(成功){
Log.i(TAG,
[80] turnFlashOn()onAutoFocus成功=真正的);
}其他{
Log.i(TAG,
[83] turnFlashOn()onAutoFocus成功= FALSE);
}
}
});
//Log.i(TAG,\"[69] cam.autoFocus TAKEPIC)后turnFlashOn();
//cam.takePicture(null,NULL,NULL,NULL);
}
} 无效setDesiredCameraParameters(相机摄像机){
Camera.Parameters参数= camera.getParameters();
Log.i(手电筒
[77] FlashlightActivity.java setDestiredVcmaeria paramers);
如果(参数== NULL){
Log.w(TAG,
设备错误:没有摄像头参数都可以不用继续配置。);
返回;
} Log.i(TAG,[84]的初始相机参数:+ parameters.flatten()); //共享preferences preFS =
// preferenceManager.getDefaultShared preferences(背景); initializeTorch(参数);
camera.setParameters(参数);
} 私人无效initializeTorch(Camera.Parameters参数){
Log.i(TAG,[95] initializeTorch());
doSetTorch(参数);
} 私人无效doSetTorch(Camera.Parameters参数){
Log.i(TAG,[100] dosetTorch());
串flashMode; flashMode = findSettableValue(parameters.getSupportedFlashModes(),
Camera.Parameters.FLASH_MODE_TORCH);
Log.i(TAG[104] doSetTorch()flashmode是+ flashMode);
//
// Camera.Parameters.FLASH_MODE_ON,
// Camera.Parameters.FOCUS_MODE_INFINITY);
如果(flashMode!= NULL){
Log.i(TAG,[109] openDriver()称为parameters.setFlashMode(+ flashMode +));
parameters.setFlashMode(flashMode);
} } 私人静态字符串findSettableValue(收集和LT;弦乐> supportedValues,
串... desiredValues){
Log.i(TAG[117] findSettableValue()支持的值:+ supportedValues);
字符串结果= NULL;
如果(supportedValues!= NULL){
对于(字符串desiredValue:desiredValues){
如果(supportedValues.contains(desiredValue)){
结果= desiredValue;
Log.i(手电筒,[123] findSettableValue()的结果设置为:+ desiredValue);
打破;
}
}
}
Log.i(手电筒,[128] findSettableValue()可设定值:+结果);
返回结果;
} 公共无效turnFlashOff(){
Log.i(手电筒,[133] turnFlashOff());
如果(凸轮!= NULL){
Log.i(手电筒,[135] turnFlashOff()凸轮不为空);
cam.stop preVIEW();
cam.release();
凸轮= NULL;
}
} 公共无效addListenerOnButton(){
Log.i(手电筒,[143] addListenerOnButton());
toggleButton1 =(切换按钮)findViewById(R.id.toggleButton1);
toggleButton1.setOnCheckedChangeListener(
新CompoundButton.OnCheckedChangeListener(){
公共无效onCheckedChanged(CompoundButton buttonView,布尔器isChecked){
Log.i(手电筒,[148] onCheckedChanged器isChecked()=+器isChecked);
如果(器isChecked){
turnFlashOn();
}其他{
turnFlashOff();
}
}
});
} / **当第一次创建活动调用。 * /
@覆盖
公共无效的onCreate(捆绑savedInstanceState){
Log.i(TAG[163]的onCreate()hasSurface是+ hasSurface);
super.onCreate(savedInstanceState);
的setContentView(R.layout.main); SurfaceView surfaceView =(SurfaceView)findViewById(R.id. preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder(); 如果(hasSurface){
//活动暂停,但没有停止,所以表面仍
//存在。因此
// surfaceCreated()不会被调用,因此,init相机在这里。
Log.i(TAG[174]的onCreate()调用initCamera()hasSurface是+ hasSurface);
initCamera(surfaceHolder);
}其他{
Log.i(TAG[177]没有表面,使安装回调,等待surfaceCreated()给init相机);
//安装回调并等待surfaceCreated()给init
//摄像头。
surfaceHolder.addCallback(本);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
} 如果(this.getPackageManager()。hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)){
凸轮= Camera.open();
Log.i(TAG[202]的onCreate()Camera.open()调用。);
addListenerOnButton();
}其他{
Toast.makeText(getApplicationContext(),
这种设备不具有闪光灯。\\ nExitting,60)
。显示();
}
} @覆盖
公共无效surfaceCreated(SurfaceHolder持有人){
Log.i(TAG[196] surfaceCreated()hasSurface是+ hasSurface);
如果(持有者== NULL){
Log.e(TAG,
***警告*** surfaceCreated()给了我们一个空面!);
}
如果(!hasSurface){
hasSurface = TRUE;
Log.i(手电筒,[201] surfaceCreated()设置hasSurface为true。);
initCamera(保持器);
}
} @覆盖
公共无效surfaceDestroyed(SurfaceHolder持有人){
Log.i(手电筒,[209] surfaceDestroyed());
hasSurface = FALSE;
} @覆盖
公共无效surfaceChanged(SurfaceHolder架,INT格式,诠释的宽度,高度INT){
Log.i(手电筒,[216] surfaceChanged(保持器,格式,宽,高));
} @覆盖
保护无效的onDestroy(){
Log.i(手电筒,[220]的onDestroy());
尝试{
cam.stop preVIEW();
cam.set previewCallback(NULL);
尝试{
cam.release();
}赶上(例外五){
}
凸轮= NULL;
}赶上(例外五){
}
super.onDestroy();
} /* 新的东西 */
私人无效initCamera(SurfaceHolder surfaceHolder){
Log.i(TAG,[236] initCamera()尝试调用openDriver(保持)); 尝试{
openDriver(surfaceHolder);
}赶上(例外五){
e.printStackTrace();
}
} / **
*打开摄像头驱动程序并初始化硬件参数。
*
* @参数架
*表面对象,相机将吸引preVIEW帧
*成。
*引发IOException
*表示摄像头驱动程序未能打开。
* /
公共同步无效openDriver(SurfaceHolder持有人)
抛出IOException
Log.i(TAG[256] openDriver()顶部); 相机将theCamera =凸轮;
如果(将theCamera == NULL){
Log.i(TAG[278] openDriver());
将theCamera = Camera.open();
Log.i(TAG[280] openDriver()Camera.open()被称为);
如果(将theCamera == NULL){
Log.i(TAG[263] openDriver());
抛出新的IOException异常();
}
凸轮=将theCamera;
}
/ *
*做到这一点按
* http://developer.android.com/reference/android/hardware/Camera.html
*第5步
* /
Log.i(TAG[281] openDriver()调用set previewDisplay(持有人));
theCamera.set previewDisplay(支架);
} 公共同步布尔isOpen会(){
返回凸轮!= NULL;
} / **
*关闭摄像头驱动程序,如果一直沿用至今。
* /
公共同步无效closeDriver(){
Log.i(TAG[285] closeDriver());
如果(凸轮!= NULL){
cam.release();
凸轮= NULL;
}
} / *结束新的东西* /
}
下面是我的意见内嵌的logcat的:
[163]的onCreate()hasSurface是假的
[177]没有表面,使安装回调,等待surfaceCreated()给init相机
[202]的onCreate()。 Camera.open()呼吁
[143] addListenerOnButton()
[196] surfaceCreated()hasSurface是假
[201] surfaceCreated()设置hasSurface为true。
[236] initCamera()试图调用openDriver(持有者)
[256] openDriver()顶部
[281] openDriver()调用set previewDisplay(持有者)
[216] surfaceChanged(保持器,格式,宽度,高度)
[148] onCheckedChanged()=器isChecked真
[42] turnFlashOn()
[67] turnFlashOn()凸轮尼特空。调用setDesiredCameraParameters(凸轮)。
[77] FlashlightActivity.java setDestiredVcmaeria paramers
[84]初始相机参数:很长的行
[95] initializeTorch()
[100] dosetTorch()
[117] findSettableValue()支持的值:[关,开,汽车,火炬]
[123] findSettableValue()的结果设置为:火炬
[128] findSettableValue()可设定值:火炬
[104] doSetTorch()flashmode是火炬
[109] openDriver()称为parameters.setFlashMode(火炬)
[69] turnFlashOn()之前开始preVIEW
[75] turnFlashOn()后启动preVIEW
[80] turnFlashOn()onAutoFocus成功= TRUE
万岁!该灯亮!所以我点击关机按钮。
[148] onCheckedChanged()=器isChecked假
[133] turnFlashOff()
[135] turnFlashOff()凸轮不为空。
万岁!指示灯熄灭。所以现在我点击按钮。
[148] onCheckedChanged()=器isChecked真
[42] turnFlashOn()
[64] turnFlashOn()凸轮为空。 Camera.open()呼吁
[67] turnFlashOn()凸轮尼特空。调用setDesiredCameraParameters(凸轮)。
[77] FlashlightActivity.java setDestiredVcmaeria paramers
[84]初始相机参数:很长的行
[95] initializeTorch()
[100] dosetTorch()
[117] findSettableValue()支持的值:[关,开,汽车,火炬]
[123] findSettableValue()的结果设置为:火炬
[128] findSettableValue()可设定值:火炬
[104] doSetTorch()flashmode是火炬
[109] openDriver()称为parameters.setFlashMode(火炬)
[69] turnFlashOn()之前开始preVIEW
[75] turnFlashOn()后启动preVIEW
嘘!不亮:(
[148] onCheckedChanged()=器isChecked假
[133] turnFlashOff()
[135] turnFlashOff()凸轮不为空。
[32]的onPause()
[209] surfaceDestroyed()
啊!现在正在工作。我不得不修改我的turnFlashOn()方法,像这样:
公共无效turnFlashOn(){
Log.i(TAG,[42] turnFlashOn());
如果(凸轮== NULL){
Log.i(TAGturnFlashOn()步骤1);
凸轮= Camera.open();
Log.i(TAG,[64] turnFlashOn()凸轮为空Camera.open()调用。);
/* 新的东西 */
SurfaceView surfaceView =(SurfaceView)findViewById(R.id. preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
Log.i(TAG[174] turnFlashOn()调用initCamera(surfaceHolder)hasSurface是+ hasSurface);
initCamera(surfaceHolder);
/ *结束新的东西* /
}
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()
Ah! It is working now. I had to modify my turnFlashOn() method like so:
public void turnFlashOn() {
Log.i(TAG, "[42] turnFlashOn()");
if (cam == null) {
Log.i(TAG, "turnFlashOn() step 1");
cam = Camera.open();
Log.i(TAG, "[64] turnFlashOn() cam was null. Camera.open() called");
/* new stuff */
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
Log.i(TAG, "[174] turnFlashOn() calling initCamera(surfaceHolder) hasSurface is " + hasSurface );
initCamera(surfaceHolder);
/* end new stuff */
}
这篇关于Android的手电筒应用程序停止工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!