【问题标题】:Background Service to take picture with Camera后台服务用相机拍照
【发布时间】:2013-06-20 16:25:27
【问题描述】:

我知道有很多关于此的问题,但我认为我面临的问题没有在其中任何一个中得到解决。 我写了这个服务的所有不同问题。问题是我在 onStartCommand 方法的所有 try-catch 块中都获得了“成功”,但是回调方法(ShutterCallback 和 PictureCallback)中的日志没有得到处理。 我认为这意味着拍摄了照片但没有调用回调,这很奇怪。

Camera cam;
Parameters param;
PictureCallback rawCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
        Log.d("CAMERA", "onPictureTaken - raw");
    }
};

ShutterCallback shutterCallback = new ShutterCallback() {
    public void onShutter() {
        Log.i("CAMERA", "onShutter'd");
    }
};

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    try {
        cam = Camera.open();
        Log.i("CAMERA", "Success");
    } catch (RuntimeException e) {
        Log.e("CAMERA", "Camera currently unavailable");
        e.printStackTrace();
    }
    try {
        param = cam.getParameters();
        cam.setParameters(param);
        Log.i("CAMERA", "Success");
    } catch (Exception e1) {
        Log.e("CAMERA", "Parameter problem");
        e1.printStackTrace();
    }
    try {
        SurfaceView view = new SurfaceView(this);
        cam.setPreviewDisplay(view.getHolder());
        cam.startPreview();
        Log.i("CAMERA", "Success");
    } catch (Exception e) {
        Log.e("CAMERA", "Surface Problem");
        e.printStackTrace();
    }
    try {
        cam.takePicture(shutterCallback, rawCallback, null);
        Log.i("CAMERA", "Success");
    } catch (Exception e) {
        Log.e("CAMERA", "Click Failure");
        e.printStackTrace();
    }
    cam.release();
    return super.onStartCommand(intent, flags, startId);
}

【问题讨论】:

标签: android android-camera android-service


【解决方案1】:

你不应该在调用 takePicture 方法后立即释放相机。您需要给相机足够的时间来执行回调。顺便说一句,您最好还添加一个 JPG 回调。也可以在释放相机之前调用 stopPreview。您的代码可能如下所示:

Camera cam;
Parameters param;
PictureCallback rawCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
        Log.d("CAMERA", "onPictureTaken - raw");
        camera.stopPreview();
        camera.release();
    }
};

PictureCallback jpgCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
        Log.d("CAMERA", "onPictureTaken - jpg");
        camera.stopPreview();
        camera.release();
    }
};

ShutterCallback shutterCallback = new ShutterCallback() {
    public void onShutter() {
        Log.i("CAMERA", "onShutter'd");
    }
};

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    try {
        cam = Camera.open();
        Log.i("CAMERA", "Success");
    } catch (RuntimeException e) {
        Log.e("CAMERA", "Camera currently unavailable");
        e.printStackTrace();
    }
    try {
        param = cam.getParameters();
        cam.setParameters(param);
        Log.i("CAMERA", "Success");
    } catch (Exception e1) {
        Log.e("CAMERA", "Parameter problem");
        e1.printStackTrace();
    }
    try {
        SurfaceView view = new SurfaceView(this);
        cam.setPreviewDisplay(view.getHolder());
        cam.startPreview();
        Log.i("CAMERA", "Success");
    } catch (Exception e) {
        Log.e("CAMERA", "Surface Problem");
        e.printStackTrace();
    }
    try {
        cam.takePicture(shutterCallback, rawCallback, null);
        Log.i("CAMERA", "Success");
    } catch (Exception e) {
        Log.e("CAMERA", "Click Failure");
        e.printStackTrace();
    }
    // Commented out following line and moved it into your callbacks
    //cam.release();
    return super.onStartCommand(intent, flags, startId);
}

【讨论】:

  • 在释放相机之前真的需要stopPreview吗?
  • 我认为您很清楚需要 JPEG 回调; takePicture 文档暗示并非所有设备都支持其他回调。
  • cam.takePicture(shutterCallback, rawCallback, null); 给我一个错误。运行时异常拍照失败。有什么想法吗?
【解决方案2】:

你错过了这些关键点:

  1. SurfaceView 必须添加到 WindowManager。
  2. 在尝试使用之前,您没有等待创建表面。在view.getHolder() 上,使用addCallback 并在回调的surfaceCreated 方法中设置和初始化预览并拍照。

【讨论】:

    【解决方案3】:

    您在属于 PictureCallback 的 takePicture 方法中将“null”作为第三个参数传递。

    你的代码:

    try {
            cam.takePicture(shutterCallback, rawCallback, null);
            Log.i("CAMERA", "Success");
        } catch (Exception e) {
            Log.e("CAMERA", "Click Failure");
            e.printStackTrace();
        }
    

    改变如下:

    try {
                cam.takePicture(shutterCallback,null,rawCallback);
                Log.i("CAMERA", "Success");
            } catch (Exception e) {
                Log.e("CAMERA", "Click Failure");
                e.printStackTrace();
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 1970-01-01
      • 2016-06-10
      • 2018-08-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多