1
私はandroidでcamera2 apiを使用していて、TextureViewとSurfaceViewを切り替えようとしたので、TextureViewをSurfaceViewと置き換えて、TextureView.SurfaceTextureListenerをSurfaceHolder.Callbackに置き換えてみました。アンドロイド7のすべての携帯電話がクラッシュするようになりました。 (私は必要なアクセス許可と実行時のアクセス許可を必要としています - アプリケーションはSurfaceViewに切り替える前にうまくいきました)。camera2 throw SecurityException
ラインでのアプリのクラッシュ:
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)
カメラの権限とその他のすべての権限が(外部記憶装置、記録オーディオなどを書き込む)前のアクティビティでユーザーが付与されていますそうでなければ、彼はカメラアクティビティに進むことができなくなるでしょう – Admond
SurfaceViewコールバックがTextureViewコールバックより速く働いていて、カメラオフなどのようなものの順序が変更を必要としたので、問題が見つかりました。 – Admond
openCameraを呼び出したときに、私が指摘したように、まだアクセス許可がなかったので、あなたの呼び出しを同期することができれば幸いです。 –