Android摄像头 - 有时候,当我把照片,应用程序冻结,相机无法使用的 [英] Android Camera - Sometimes when i take photos, the app freezes and the camera is non-usable

查看:154
本文介绍了Android摄像头 - 有时候,当我把照片,应用程序冻结,相机无法使用的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经建立了一个应用程序,它需要的照片,当你触摸的preVIEW。 我可以拍很多照片,但有时当我触摸preVIEW拍一张照片,没有快门声,整个应用程序冻结。此外,在此之后,如果我尝试推出推出内置摄像头的应用程序,我得到一个消息,相机无法使用。

I have built an application which takes photos when you touch the preview. I can take many photos, but sometimes when i touch the preview to take a photo, there is no shutter sound and the whole application freezes. Moreover, after that, if i try to launch launch the built-in camera application, i get a message that the camera can't be used.

我不知道这种行为的原因,它随机发生,当它发生了,我必须重新启动设备(三星Galaxy S),以便能够再次使用相机。

I don't know the reason for that behavior, it happens randomly and when it happens i must restart the device (Samsung Galaxy S) to be able to use the camera again.

在DDM,事故发生后,我可以看到下面一行:keyDispatchingTimedOut

In the DDM, after the crash i can see the following line: keyDispatchingTimedOut

下面是相关code: CameraActivity类:

Here is the relevant code: CameraActivity Class:

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.");

  }
}

preVIEW类:

Preview Class:

    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();
        }
    };

}

请帮忙,我想了几天,了解问题所在,但没有成功。

Please help, i am trying a few days to understand where the problem is with no success

的Eyal

推荐答案

我不知道是什么原因造成的错误,它会的真的如果帮你从什么时候这个贴出来的时候输出loggcat错误发生了。

I don't know what causes that bug, it would really help if you posted the loggcat output from the time from when this error happened.

不过,我可以做一些gusesses。它看起来像摄像头已被锁定(内置摄像头不工作)。如果你的应用程序强制关闭时,摄像机会锁定在三星相机HAL erroneus错误处理造成的。尤其是在旧的手机,如Galaxy S的,他们并没有在处理错误的,或者不标准的API调用做最好的工作。

But, I can make some gusesses. It looks like camera is locked (built-in camera does not work). If your app force closed, the camera lock might be caused by erroneus error handling in Samsung camera HAL. Especially in older phones, like Galaxy S, they did not do the best job at handling wrong, or not standard API calls.

下面是什么可能导致此行为的一些建议:

Here are some suggestions of what may have caused this behaviour:

  1. 您应该增加一个后卫拍照。现在,如果你触摸屏幕,并拍摄照片,您可以再次触摸屏幕,在图像拍摄完成。因此,camera.takePicture()将被调用两次。第二个将失败。这是我最好的猜测。

  1. You should add a guard for picture taking. Right now, if you touch the screen and take picture, you can touch the screen again, before the picture finishes taking. So, camera.takePicture() will be called twice. The second one will fail. This is my best guess.

添加一些布尔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呢?我在这里并不做任何有用的。 preVIEW回调有时有时会造成一定的痛苦,虽然你的code看起来好像没什么问题。您可以alwys尝试将其删除,并检查是否有帮助。

  • What do you use previewCallback for? I doesn't do anything useful here. Preview callbacks sometimes can sometimes cause some pain, although your code looks fine to me. You can alwys try to remove it and check if that helps.

    这篇关于Android摄像头 - 有时候,当我把照片,应用程序冻结,相机无法使用的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆