我正在使用android中的camera2 api,并尝试在TextureView和SurfaceView之间切换,因此我唯一的改变是使用SurfaceView替换TextureView,使用SurfaceHolder.Callback替换TextureView.SurfaceTextureListener。现在android 7下的所有手机都崩溃了。 (我有所需的权限和所需的运行时权限。 - 在切换到SurfaceView之前,应用程序运行良好)。
应用程序崩溃:
mPreviewBuilder =
mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
旧代码:
private TextureView.SurfaceTextureListener mSurfaceTextureListener
= new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture,
int width, int height) {
openCamera(width, height);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture,
int width, int height) {
configureTransform(width, height);
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
};
/**
* Start the camera preview.
*/
private void startPreview() {
if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) {
return;
}
try {
closePreviewSession();
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
Surface previewSurface = new Surface(texture);
mPreviewBuilder.addTarget(previewSurface);
mCameraDevice.createCaptureSession(Collections.singletonList(previewSurface),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
mPreviewSession = session;
updatePreview();
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
if (null != activity) {
Toast.makeText(activity, "Failed", Toast.LENGTH_SHORT).show();
}
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
新代码:
private SurfaceHolder.Callback mSurfaceViewListener =
new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
SurfaceViewLifeCycle.setSurfaceState(SurfaceViewLifeCycle.SURFACE_VIEW_LIFE_CYCLE_CREATED);
openCamera(640, 480);
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
SurfaceViewLifeCycle.setSurfaceState(SurfaceViewLifeCycle.SURFACE_VIEW_LIFE_CYCLE_DESTROYED);
closeCamera();
}
};
/**
* Start the camera preview.
*/
private void startPreview() {
if (null == mCameraDevice ||
SurfaceViewLifeCycle.getSurfaceState() != SurfaceViewLifeCycle.SURFACE_VIEW_LIFE_CYCLE_CREATED ||
null == mPreviewSize) {
return;
}
try {
closePreviewSession();
//SurfaceTexture texture = mTextureView.getSurfaceTexture();
//assert texture != null;
//texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
//Surface previewSurface = new Surface(texture);
Surface previewSurface = mSurfaceView.getHolder().getSurface();
mPreviewBuilder.addTarget(previewSurface);
mCameraDevice.createCaptureSession(Collections.singletonList(previewSurface),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
mPreviewSession = session;
updatePreview();
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
if (null != activity) {
Toast.makeText(activity, "Failed", Toast.LENGTH_SHORT).show();
}
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
错误日志:
11-28 15:38:32.253 13516-13516/rifdsafsda.com.phase9try12 E/AndroidRuntime: FATAL EXCEPTION: main
Process: rifdsafsda.com.phase9try12, PID: 13516
java.lang.SecurityException: Lacking privileges to access camera service
at android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:108)
at android.hardware.camera2.utils.CameraBinderDecorator$CameraBinderDecoratorListener.onAfterInvocation(CameraBinderDecorator.java:73)
at android.hardware.camera2.utils.Decorator.invoke(Decorator.java:81)
at java.lang.reflect.Proxy.invoke(Proxy.java:393)
at $Proxy1.createDefaultRequest(Unknown Source)
at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureRequest(CameraDeviceImpl.java:628)
at rifdsafsda.com.phase9try12.media.camera.RecordingManager.startPreview(RecordingManager.java:282)
at rifdsafsda.com.phase9try12.media.camera.RecordingManager.access$300(RecordingManager.java:41)
at rifdsafsda.com.phase9try12.media.camera.RecordingManager$2.onOpened(RecordingManager.java:121)
at android.hardware.camera2.impl.CameraDeviceImpl$1.run(CameraDeviceImpl.java:134)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
答案 0 :(得分:0)
似乎在调用openCamera后已授予相机权限,请尝试此操作并检查:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(AndroidCameraApi.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, CAMERA_PERMISSION_REQUEST_ID);
}
else
{
openCamera(640, 480);
}