以下代码在 HTC Desire S、Galaxy S II 和模拟器上进行了测试。它运行良好,但令人惊讶的是它不适用于 Galaxy S Duos (GT-S7562)。发生的情况是所有调用都成功,无一例外,但没有调用回调。
public class CameraManager implements PictureCallback {
private final static String DEBUG_TAG = "CameraManager";
public void TakePicture() {
try {
_camera = Camera.open(cameraId);
Log.d(DEBUG_TAG, "Camera.TakePicture.open");
SurfaceView view = new SurfaceView(CameraManager.this.getContext());
_camera.setPreviewDisplay(view.getHolder());
Log.d(DEBUG_TAG, "Camera.TakePicture.setPreviewDisplay");
_camera.startPreview();
Log.d(DEBUG_TAG, "Camera.TakePicture.startPreview");
AudioManager manager = (AudioManager) CameraManager.super.getContext().getSystemService(Context.AUDIO_SERVICE);
Log.d(DEBUG_TAG, "Camera.TakePicture.AudioManager.ctor()");
manager.setStreamVolume(AudioManager.STREAM_SYSTEM, 0 , AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
Log.d(DEBUG_TAG, "Camera.TakePicture.setStreamVolume");
Camera.ShutterCallback shutter = new Camera.ShutterCallback() {
@Override
public void onShutter() {
AudioManager manager = (AudioManager) CameraManager.super.getContext().getSystemService(Context.AUDIO_SERVICE);
Log.d(DEBUG_TAG, "Camera.TakePicture.Shutter.AudioManager.ctor()");
manager.setStreamVolume(AudioManager.STREAM_SYSTEM, manager.getStreamMaxVolume(AudioManager.STREAM_SYSTEM) , AudioManager.FLAG_ALLOW_RINGER_MODES);
Log.d(DEBUG_TAG, "Camera.TakePicture.Shutter.setStreamVolume");
}
};
Camera.PictureCallback rawCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
if (data != null) {
Log.i(DEBUG_TAG, "Picture taken::RAW");
_camera.stopPreview();
_camera.release();
} else {
Log.wtf(DEBUG_TAG, "Picture NOT taken::RAW");
}
}
};
_camera.takePicture(shutter, rawCallback, CameraManager.this);
Log.d(DEBUG_TAG, "Camera.TakePicture.taken");
} catch (Exception err) {
err.printStackTrace();
Log.d(DEBUG_TAG, "Camera.TakePicture.Exception:: %s" + err.getMessage());
}
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
if (data != null) {
Log.i(DEBUG_TAG, "Picture taken::JPG");
_camera.stopPreview();
_camera.release();
} else {
Log.wtf(DEBUG_TAG, "Picture NOT taken::JPG");
}
}
}
这是执行上述代码的 logcat 的输出日志,如您所见,未调用回调:
[ 10-16 01:39:18.711 3873:0xf21 D/CameraManager ]
Camera.TakePicture.open
[ 10-16 01:39:18.891 3873:0xf21 D/CameraManager ]
Camera.TakePicture.setFrontCamera
[ 10-16 01:39:18.901 3873:0xf21 D/CameraManager ]
Camera.TakePicture.setPreviewDisplay
[ 10-16 01:39:18.901 3873:0xf21 D/CameraManager ]
Camera.TakePicture.startPreview
[ 10-16 01:39:18.901 3873:0xf21 D/CameraManager ]
Camera.TakePicture.AudioManager.ctor()
[ 10-16 01:39:19.001 3873:0xf21 D/CameraManager ]
Camera.TakePicture.setStreamVolume
[ 10-16 01:39:19.041 3873:0xf21 D/CameraManager ]
Camera.TakePicture.taken
我还检查了 Galaxy S 的类似问题,发现以下代码,我使用它没有成功:
Camera.Parameters parameters = camera.getParameters();
parameters.set("camera-id", 2);
// (800, 480) is also supported front camera preview size at Samsung Galaxy S.
parameters.setPreviewSize(640, 480);
camera.setParameters(parameters);
我想知道是否有人可以告诉我我的代码有什么问题?或者这个模型可能存在一些限制,不允许在不显示预览表面的情况下拍照。如果是这样,那么您能否让我知道任何可能的解决方法?请注意,此代码是从 android 服务执行的。