我已经构建了一个应用程序,当您触摸预览时拍摄照片.
我可以拍摄很多照片,但有时候,当我触摸预览拍摄照片时,没有快门音,整个应用程序冻结.此外,在此之后,如果我尝试启动内置相机应用程序,我会收到一条消息,指出相机不能使用.
我可以拍摄很多照片,但有时候,当我触摸预览拍摄照片时,没有快门音,整个应用程序冻结.此外,在此之后,如果我尝试启动内置相机应用程序,我会收到一条消息,指出相机不能使用.
我不知道这个行为的原因,它是随机发生的,当它发生时,我必须重新启动设备(Samsung 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(); } }; }
请帮忙,我正在尝试几天,了解问题在哪里,没有成功
的Eyal
解决方法
我不知道是什么原因导致这个错误,如果从发生此错误的时间发布了loggcat输出,这将真的有帮助.
但是,我可以做一些gusesses.看起来相机被锁定(内置相机不起作用).如果您的应用程序强制关闭,相机锁定可能是由于Samsung相机HAL中的错误处理引起的.特别是在像Galaxy S这样的老旧手机中,他们在处理错误或者不是标准的API调用时都没有做最好的工作.
以下是可能导致此行为的一些建议:
>你应该添加一个护照来拍摄.现在,如果您触摸屏幕并拍摄照片,则可以在照片拍摄完成之前再次触摸屏幕.所以,camera.takePicture()将被调用两次.第二个会失败.这是我最好的猜测.
添加一些布尔值isTakingPicture = false变量然后:
public boolean onTouch(View v,MotionEvent event) { if (!isTakingPicture) { camera.takePicture(shutterCallback,jpegCallback); isTakingPicture = true; } return false; } ... public void onPictureTaken(byte[] data,Camera camera) { isTakingPicture = false; ...
>你使用previewCallback做什么?我在这里没有任何有用的东西.有时候,预览回调有时会导致一些痛苦,尽管你的代码对我来说看起来不错.你可以试试删除它,并检查是否有帮助.