在我的应用程序中,我正在捕捉图像。除非手机在预览运行时进入休眠状态,否则一切正常。不太确定如何处理它,我认为最好只是防止手机在此过程中自动进入休眠状态。我不知道该怎么做。如果我这样做会阻止手机在我按下电源按钮时进入 hibernate 状态吗?也许这里有更深层次的问题。
日志:
08-28 16:17:10.879: WARN/dalvikvm(9652): threadid=3: thread exiting with uncaught exception (group=0x4001b390) 08-28 16:17:10.879: ERROR/AndroidRuntime(9652): Uncaught handler: thread main exiting due to uncaught exception 08-28 16:17:10.879: ERROR/AndroidRuntime(9652): java.lang.RuntimeException: Method called after release() 08-28 16:17:10.879: ERROR/AndroidRuntime(9652): at android.hardware.Camera.setHasPreviewCallback(Native Method) 08-28 16:17:10.879: ERROR/AndroidRuntime(9652): at android.hardware.Camera.access$600(Camera.java:58) 08-28 16:17:10.879: ERROR/AndroidRuntime(9652): at android.hardware.Camera$EventHandler.handleMessage(Camera.java:339) 08-28 16:17:10.879: ERROR/AndroidRuntime(9652): at android.os.Handler.dispatchMessage(Handler.java:99) 08-28 16:17:10.879: ERROR/AndroidRuntime(9652): at android.os.Looper.loop(Looper.java:123) 08-28 16:17:10.879: ERROR/AndroidRuntime(9652): at android.app.ActivityThread.main(ActivityThread.java:4595) 08-28 16:17:10.879: ERROR/AndroidRuntime(9652): at java.lang.reflect.Method.invokeNative(Native Method) 08-28 16:17:10.879: ERROR/AndroidRuntime(9652): at java.lang.reflect.Method.invoke(Method.java:521) 08-28 16:17:10.879: ERROR/AndroidRuntime(9652): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 08-28 16:17:10.879: ERROR/AndroidRuntime(9652): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 08-28 16:17:10.879: ERROR/AndroidRuntime(9652): at dalvik.system.NativeStart.main(Native Method)
takephoto activity:
public class takephoto extends Activity {
private static final String TAG = "GrowJournalDemo";
Preview preview; // <1>
Button buttonClick; // <2>
String journ_id;
String plant_id;
// private String plantid = ((resource) this.getApplication()).getplantId();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.photo);
preview = new Preview(this); // <3>
((FrameLayout) findViewById(R.id.preview)).addView(preview); // <4>
String journalid = ((resource) this.getApplication()).getjournalName();
plant_id = ((resource) this.getApplication()).getplantId();
journ_id = journalid;
buttonClick = (Button) findViewById(R.id.buttonClick);
buttonClick.setOnClickListener(new OnClickListener() {
public void onClick(View v) { // <5>
// preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback);
preview.camera.autoFocus(new Camera.AutoFocusCallback() {
Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() {
public void onShutter() {
// Play your sound here.
}
};
public void onAutoFocus(boolean success, Camera camera) {
preview.camera.takePicture(null, null, jpegCallback);
}
});
}
});
Log.d(TAG, "onCreate'd");
}
// Called when shutter is opened
ShutterCallback shutterCallback = new ShutterCallback() { // <6>
public void onShutter() {
Log.d(TAG, "onShutter'd");
}
};
// Handles data for raw picture
PictureCallback rawCallback = new PictureCallback() { // <7>
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken - raw");
}
};
// Handles data for jpeg picture
PictureCallback jpegCallback = new PictureCallback() { // <8>
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
android.os.Environment.getExternalStorageState();
// create a File object for the parent directory
File PhotoDirectory = new File(
android.os.Environment.getExternalStorageDirectory()+
"/GrowJournalPhotos/"+journ_id+"/"+plant_id+"/");
// have the object build the directory structure, if needed.
PhotoDirectory.mkdirs();
// create a File object for the output file
File outputFile = new File(PhotoDirectory, "photo.jpg");
// now attach the OutputStream to the file object, instead of a String representation
outStream = new FileOutputStream(outputFile);
outStream.write(data);
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
setResult(RESULT_OK);
finish();
} catch (FileNotFoundException e) { // <10>
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Log.d(TAG, "onPictureTaken - jpeg");
}
};
}
预览表面 View :
public class Preview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "Preview";
SurfaceHolder mHolder; // <2>
public Camera camera; // <3>
Preview(Context context) {
super(context);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder(); // <4>
mHolder.addCallback(this); // <5>
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // <6>
}
// Called once the holder is ready
public void surfaceCreated(SurfaceHolder holder) { // <7>
// The Surface has been created, acquire the camera and tell it where
// to draw.
camera = Camera.open(); // <8>
try {
camera.setPreviewDisplay(holder); // <9>
camera.setPreviewCallback(new PreviewCallback() { // <10>
// Called for each frame previewed
public void onPreviewFrame(byte[] data, Camera camera) { // <11>
Log.d(TAG, "onPreviewFrame called at: " + System.currentTimeMillis());
Preview.this.invalidate(); // <12>
}
});
} catch (IOException e) { // <13>
e.printStackTrace();
}
}
// Called when the holder is destroyed
public void surfaceDestroyed(SurfaceHolder holder) { // <14>
camera.stopPreview();
camera.release();
camera = null;
}
// Called when holder has changed
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // <15>
camera.startPreview();
}
}
我添加了一个唤醒锁来防止手机变暗,我觉得这是一个临时解决方案,因为当通过电源按钮强制设备进入休眠状态时仍然存在强制关闭。
最佳答案
为什么要为每个预览帧调用 invalidate()?相机显示应该在没有它的情况下更新。
要么完全删除预览回调(因为你似乎没有做任何其他事情),要么在你释放之前尝试在 onResume() 中设置 camera.setPreviewCallback(null)
以便它释放相机资源后不会尝试调用它。您遇到异常是因为您在释放相机后试图在某处访问它。
关于java - 从 sleep 中返回时相机强制关闭。安卓,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3592283/