Android 相机 - 有时当我拍照时,应用程序冻结并且相机无法使用
Posted
技术标签:
【中文标题】Android 相机 - 有时当我拍照时,应用程序冻结并且相机无法使用【英文标题】:Android Camera - Sometimes when i take photos, the app freezes and the camera is non-usable 【发布时间】:2012-03-29 01:20:50 【问题描述】:我已经构建了一个应用程序,当您触摸预览时会拍照。 我可以拍很多照片,但有时当我触摸预览拍照时,没有快门声,整个应用程序冻结。此外,在此之后,如果我尝试启动内置相机应用程序,我会收到无法使用相机的消息。
我不知道这种行为的原因,它是随机发生的,当它发生时,我必须重新启动设备(三星 Galaxy S)才能再次使用相机。
在 DDM 中,崩溃后我可以看到以下行:keyDispatchingTimedOut
以下是相关代码: CameraActivity 类:
public class CameraActivity extends Activity
private static final String TAG = "CameraDemo";
Preview preview;
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
preview = new Preview(this);
((FrameLayout) findViewById(R.id.preview)).addView(preview);
((FrameLayout) findViewById(R.id.preview)).setOnTouchListener(preview);
Log.d(TAG, "Camera Activity Created.");
预习课:
class Preview extends SurfaceView implements SurfaceHolder.Callback, OnTouchListener
private static final String TAG = "Preview";
SurfaceHolder mHolder;
public Camera camera;
Context ctx;
boolean previewing = false;
Preview(Context context)
super(context);
ctx = context;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// Called once the holder is ready
public void surfaceCreated(SurfaceHolder holder)
// The Surface has been created, acquire the camera and tell it where
// to draw.
camera = Camera.open();
// Called when the holder is destroyed
public void surfaceDestroyed(SurfaceHolder holder)
if (camera != null)
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
// Called when holder has changed
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
if(previewing)
camera.stopPreview();
previewing = false;
if (camera != null)
try
camera.setDisplayOrientation(90);
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new PreviewCallback()
// Called for each frame previewed
public void onPreviewFrame(byte[] data, Camera camera)
Log.d(TAG, "onPreviewFrame called at: " + System.currentTimeMillis());
Preview.this.invalidate();
);
camera.startPreview();
previewing = true;
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
public boolean onTouch(View v, MotionEvent event)
camera.takePicture(shutterCallback, rawCallback, jpegCallback);
return false;
// Called when shutter is opened
ShutterCallback shutterCallback = new ShutterCallback()
public void onShutter()
Log.d(TAG, "onShutter'd");
;
// Handles data for raw picture
PictureCallback rawCallback = new PictureCallback()
public void onPictureTaken(byte[] data, Camera camera)
Log.d(TAG, "onPictureTaken - raw");
;
// Handles data for jpeg picture
PictureCallback jpegCallback = new PictureCallback()
public void onPictureTaken(byte[] data, Camera camera)
FileOutputStream outStream = null;
try
// Write to SD Card
outStream = new FileOutputStream(String.format("/sdcard/TVguide/Detection/detected.jpg", System.currentTimeMillis())); // <9>
outStream.write(data);
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
catch (FileNotFoundException e) // <10>
//Toast.makeText(ctx, "Exception #2", Toast.LENGTH_LONG).show();
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
finally
Log.d(TAG, "onPictureTaken - jpeg");
Toast.makeText(ctx, "SAVED", Toast.LENGTH_SHORT).show();
camera.startPreview();
;
请帮忙,我正在尝试几天来了解问题出在哪里,但没有成功
艾尔
【问题讨论】:
我也建议将图片保存到 sd 卡,以便在后台线程中制作,而不是在主 UI 线程中。 【参考方案1】:我在三星 Galaxy SII 上测试我的应用程序时遇到了这个问题。您只需在拍照前删除预览回调即可:
mCamera.setPreviewCallback(null);
mCamera.takePicture(null, null, mPictureCallback);
【讨论】:
在 HTC Sensation 上,我的自定义相机应用程序在全屏空间显示预览。当用户点击屏幕时,会调用焦点。当焦点完成并成功时,我调用 mCamera.takePicture 。有时它可以工作,我得到保存 JPG 数据的回调,其他时候它只是停留在 takePicture 中,没有超时也没有任何调试消息。这太烦人了,每次都要重启手机,不知道问题出在哪里。 SettingsPreviewCallback 到 null 没有帮助。还有其他想法吗?【参考方案2】:我不知道导致该错误的原因,如果您从发生此错误的时间发布 loggcat 输出,它真的会有所帮助。
但是,我可以做一些猜测。看起来相机被锁定(内置相机不起作用)。如果您的应用程序强制关闭,则相机锁定可能是由三星相机 HAL 中的错误错误处理引起的。尤其是在 Galaxy S 等较旧的手机中,它们在处理错误或不标准的 API 调用方面做得并不好。
以下是可能导致此行为的一些建议:
你应该为拍照添加一个警卫。现在,如果您触摸屏幕并拍照,您可以在拍照完成之前再次触摸屏幕。因此,camera.takePicture() 将被调用两次。第二个会失败。这是我最好的猜测。
添加一些boolean isTakingPicture = false
变量然后:
public boolean onTouch(View v, MotionEvent event)
if (!isTakingPicture)
camera.takePicture(shutterCallback, rawCallback, jpegCallback);
isTakingPicture = true;
return false;
...
public void onPictureTaken(byte[] data, Camera camera)
isTakingPicture = false;
...
您使用 previewCallback 做什么?我在这里没有做任何有用的事情。预览回调有时会引起一些痛苦,尽管您的代码对我来说看起来不错。您可以随时尝试删除它并检查是否有帮助。
【讨论】:
太棒了!第一个解决方案没有帮助,但第二个解决方案(删除 previewCallback)解决了问题 嗯,也许在分配给相机的 SurfaceView 上调用 invalidate() 是问题所在。我从来没有尝试过,我无法想象有任何阅读可以做到这一点。不过,我认为您也应该应用第一个解决方案,以防止潜在的错误。【参考方案3】:我遇到了此处报告的类似问题。在 LG p705 和三星 Galaxy Trend 上,拍照后,预览被冻结,相机无法再使用,直到手机重新启动。然而,在 Galaxy S3 上,即使在拍摄了多张照片后,预览也会继续正常显示。
在调试时,我注意到当按下相机按钮拍照时,相关的侦听器类收到了多个调用。我不确定为什么它会被调用两次,即使按钮只单击一次。在任何情况下,由于 Tomasz 建议使用布尔变量,第二次调用会在第一次尝试进行时跳过拍照。也感谢 Eyal 的提问。 :)
【讨论】:
以上是关于Android 相机 - 有时当我拍照时,应用程序冻结并且相机无法使用的主要内容,如果未能解决你的问题,请参考以下文章