在 Android 6.0 中缺乏访问相机服务的权限
Posted
技术标签:
【中文标题】在 Android 6.0 中缺乏访问相机服务的权限【英文标题】:Lacking privileges to access camera service in Android 6.0 【发布时间】:2017-03-14 05:11:48 【问题描述】:我在 android 6.0 中使用 Camera2API。我在 Android 5.0 中没有出错。但是,当我在 Android 6.0 中使用我的代码时,我遇到了一个问题。问题是有时我可以成功打开相机并拍照。但是,有时相机无法打开并且出现错误
java.lang.SecurityException: Lacking privileges to access camera service
at android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:108)
我添加运行时权限如下:
String[] PERMISSIONS = Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
if(!hasAllPermissions(this, PERMISSIONS))
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
public static boolean hasAllPermissions(Context context, String... permissions)
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null)
for (String permission : permissions)
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED)
return false;
return true;
这是所有日志
FATAL EXCEPTION: main
Process: com.example.camera2api, PID: 5376
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 $Proxy2.cancelRequest(Unknown Source)
at android.hardware.camera2.impl.CameraDeviceImpl.stopRepeating(CameraDeviceImpl.java:926)
at android.hardware.camera2.impl.CameraCaptureSessionImpl.close(CameraCaptureSessionImpl.java:378)
at android.hardware.camera2.impl.CameraCaptureSessionImpl$2.onDisconnected(CameraCaptureSessionImpl.java:514)
at android.hardware.camera2.impl.CameraDeviceImpl$7.run(CameraDeviceImpl.java:228)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
更新:对于想要查看我的完整代码的人。我在这里上传我的完整代码
公共类 AndroidCamera 扩展 AppCompatActivity
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
private static final String TAG = "Camera2App";
private String mImageFileLocation = "";
private static final int STATE_PREVIEW = 0;
private static final int STATE_WAIT_LOCK = 1;
private static final int STATE_WAITING_PRECAPTURE = 2;
/**
* Camera state: Waiting for the exposure state to be something other than precapture.
*/
private static final int STATE_WAITING_NON_PRECAPTURE = 3;
/**
* Camera state: Picture was taken.
*/
private static final int STATE_PICTURE_TAKEN = 4;
private int mState;
private TextureView mTextureView;
private Size mPreviewSize;
private String mCameraId;
String[] PERMISSIONS = Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA;
private static final int PERMISSION_ALL = 105;
private static final int REQUEST_CAMERA_RESULT = 106;
private boolean isRegistred=false;
private int mSensorOrientation;
private TextureView.SurfaceTextureListener mSurfaceTextureListener =
new TextureView.SurfaceTextureListener()
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)
if (!TextUtils.isEmpty(BleUtils.getCameraLens(AndroidCamera.this)))
setupCamera(width, height,BleUtils.getCameraLens(AndroidCamera.this));
else
setupCamera(width, height,"1");
openCamera();
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height)
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface)
//closeCamera();
return false;
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface)
;
private Semaphore mCameraOpenCloseLock = new Semaphore(1);
private CameraDevice mCameraDevice;
private CameraDevice.StateCallback mCameraDeviceStateCallback =
new CameraDevice.StateCallback()
@Override
public void onOpened(CameraDevice camera)
mCameraOpenCloseLock.release();
mCameraDevice = camera;
//Toast.makeText(getApplicationContext(),"Camera Opened!", Toast.LENGTH_SHORT).show();
createCameraPreviewSession();
@Override
public void onDisconnected(CameraDevice camera)
camera.close();
mCameraDevice = null;
@Override
public void onError(CameraDevice camera, int error)
camera.close();
mCameraDevice = null;
;
private CaptureRequest mPreviewCaptureRequest;
private CaptureRequest.Builder mPreviewCaptureRequestBuilder;
private CameraCaptureSession mCameraCaptureSession;
private CameraCaptureSession.CaptureCallback mSessionCaptureCallback
= new CameraCaptureSession.CaptureCallback()
private void process(CaptureResult result)
switch (mState)
case STATE_PREVIEW:
break;
case STATE_WAIT_LOCK:
Integer afState=result.get(CaptureResult.CONTROL_AF_STATE);
if(afState==CaptureRequest.CONTROL_AF_STATE_FOCUSED_LOCKED)
captureStillImage();
else
captureStillImage();
break;
@Override
public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber)
super.onCaptureStarted(session, request, timestamp, frameNumber);
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result)
super.onCaptureCompleted(session, request, result);
process(result);
@Override
public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure)
super.onCaptureFailed(session, request, failure);
Handler mHandler = new Handler(getMainLooper());
mHandler.post(new Runnable()
@Override
public void run()
Toast.makeText(getApplicationContext(), "Focus Lock UnSuccesful", Toast.LENGTH_SHORT).show();
);
;
private HandlerThread mBackgroundThread;
private Handler mBackgroundHandler;
private static File mImageFile;
private ImageReader mImageReader;
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener =
new ImageReader.OnImageAvailableListener()
@Override
public void onImageAvailable(ImageReader reader)
mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage()));
;
private static class ImageSaver implements Runnable
private final Image mImage;
private ImageSaver(Image image)
mImage = image;
@Override
public void run()
ByteBuffer byteBuffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
FileOutputStream fileOutputStream = null;
try
fileOutputStream = new FileOutputStream(mImageFile);
fileOutputStream.write(bytes);
catch (IOException e)
e.printStackTrace();
finally
mImage.close();
if (fileOutputStream != null)
try
fileOutputStream.close();
catch (IOException e)
e.printStackTrace();
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_activity);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
if(!hasAllPermissions(this, PERMISSIONS))
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
mTextureView = (TextureView) findViewById(R.id.texture);
public static boolean hasAllPermissions(Context context, String... permissions)
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null)
for (String permission : permissions)
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED)
return false;
return true;
@Override
public void onStart()
super.onStart();
if (!EventBus.getDefault().isRegistered(this))
EventBus.getDefault().register(this);
//onStop
@Override
public void onStop()
super.onStop();
EventBus.getDefault().unregister(this);
@Subscribe
public void onCaptureNumberReceived(OnCaptureEvent event)
//get the phone number value here and do something with it
String capturecode = event.getCodeCapture();
Log.d(TAG, capturecode);
if (capturecode.equals("capture"))
try
mImageFile = createImageFile();
catch (IOException e)
e.printStackTrace();
lockFocus();
MediaActionSound sound = new MediaActionSound();
sound.play(MediaActionSound.SHUTTER_CLICK);
else if(capturecode.equals("end_capture"))
finish(); // call this to finish the current activity
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory( Intent.CATEGORY_HOME );
homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(homeIntent);
public void takepicture(View view)
try
mImageFile = createImageFile();
Log.d("TAG","=====Take picture=====");
catch (IOException e)
e.printStackTrace();
lockFocus();
MediaActionSound sound = new MediaActionSound();
sound.play(MediaActionSound.SHUTTER_CLICK);
public void switch_camera(View view)
closeCamera();
//swap the id of the camera to be used
if(mCameraId == String.valueOf(Camera.CameraInfo.CAMERA_FACING_BACK))
mCameraId = String.valueOf(Camera.CameraInfo.CAMERA_FACING_FRONT);
else
mCameraId = String.valueOf(Camera.CameraInfo.CAMERA_FACING_BACK);
BleUtils.setCameraLens(this, mCameraId);
if (mTextureView.isAvailable())
setupCamera(mTextureView.getWidth(), mTextureView.getHeight(),mCameraId);
openCamera();
else
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
File createImageFile() throws IOException
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "BLE_" + timeStamp + "_";
File storageDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
if(!storageDirectory.exists())
if(!storageDirectory.mkdirs())
Log.e("Dir", "Failed to create directory");
Log.d("MAKE DIR", storageDirectory.mkdir() + "" + storageDirectory.getParentFile() + "");
return null;
File image = File.createTempFile(imageFileName, ".jpg", storageDirectory);
mImageFileLocation = image.getAbsolutePath();
return image;
@Override
public void onResume()
super.onResume();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
if(!hasAllPermissions(this, PERMISSIONS))
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
openBackgroundThread();
if (mTextureView.isAvailable())
if (!TextUtils.isEmpty(BleUtils.getCameraLens(AndroidCamera.this)))
setupCamera(mTextureView.getWidth(), mTextureView.getHeight(),BleUtils.getCameraLens(AndroidCamera.this));
else
setupCamera(mTextureView.getWidth(), mTextureView.getHeight(),"1");
closeCamera();
openCamera();
else
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
@Override
public void onDestroy()
super.onDestroy();
Log.d(TAG,"onDestroy");
public void onPause()
Log.d(TAG,"onPause");
closeCamera();
closeBackgroundThread();
super.onPause();
private void setupCamera(int width, int height, String cameraId)
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size largestImageSize = Collections.max(
Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
new Comparator<Size>()
@Override
public int compare(Size lhs, Size rhs)
return Long.signum(lhs.getWidth() * lhs.getHeight() -
rhs.getWidth() * rhs.getHeight());
);
mImageReader = ImageReader.newInstance(largestImageSize.getWidth(),
largestImageSize.getHeight(),
ImageFormat.JPEG,
1);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener,
mBackgroundHandler);
mPreviewSize = getPreferredPreviewSize(map.getOutputSizes(SurfaceTexture.class), width, height);
mCameraId = cameraId;
Log.d("CAMERA_ID",String.valueOf(mCameraId));
//
catch (CameraAccessException e)
e.printStackTrace();
private Size getPreferredPreviewSize(Size[] mapSizes, int width, int height)
List<Size> collectorSizes = new ArrayList<>();
for (Size option : mapSizes)
if (width > height)
if (option.getWidth() > width &&
option.getHeight() > height)
collectorSizes.add(option);
else
if (option.getWidth() > height &&
option.getHeight() > width)
collectorSizes.add(option);
if (collectorSizes.size() > 0)
return Collections.min(collectorSizes, new Comparator<Size>()
@Override
public int compare(Size lhs, Size rhs)
return Long.signum(lhs.getWidth() * lhs.getHeight() - rhs.getWidth() * rhs.getHeight());
);
return mapSizes[0];
private void openCamera()
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try
Log.v("CAMERA", mCameraId + " " + mCameraDeviceStateCallback);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
if(ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED)
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback,mBackgroundHandler);
else
if (shouldShowRequestPermissionRationale(android.Manifest.permission.CAMERA))
Toast.makeText(this,"No Permission to use the Camera services", Toast.LENGTH_SHORT).show();
requestPermissions(new String[] android.Manifest.permission.CAMERA,REQUEST_CAMERA_RESULT);
else
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
catch (CameraAccessException e)
e.printStackTrace();
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
switch (requestCode)
case REQUEST_CAMERA_RESULT:
if (grantResults[0] != PackageManager.PERMISSION_GRANTED)
Toast.makeText(this, "Cannot run application because camera service permission have not been granted", Toast.LENGTH_SHORT).show();
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
private void closeCamera()
if(mCameraCaptureSession!=null)
mCameraCaptureSession.close();
mCameraCaptureSession=null;
if (mCameraDevice!=null)
mCameraDevice.close();
mCameraDevice=null;
if(mImageReader!=null)
mImageReader.close();
mImageReader=null;
private void createCameraPreviewSession()
try
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(),mPreviewSize.getHeight());
Surface previewSurface= new Surface(surfaceTexture);
mPreviewCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewCaptureRequestBuilder.addTarget(previewSurface);
mPreviewCaptureRequestBuilder.set(CaptureRequest.JPEG_QUALITY, (byte)100);
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface,mImageReader.getSurface()),
new CameraCaptureSession.StateCallback()
@Override
public void onConfigured(CameraCaptureSession session)
if(mCameraDevice==null)
return;
try
mPreviewCaptureRequest = mPreviewCaptureRequestBuilder.build();
mCameraCaptureSession = session;
mCameraCaptureSession.setRepeatingRequest(
mPreviewCaptureRequest,
mSessionCaptureCallback,
mBackgroundHandler
);
catch (CameraAccessException e)
e.printStackTrace();
@Override
public void onConfigureFailed(CameraCaptureSession session)
Handler mHandler = new Handler(getMainLooper());
mHandler.post(new Runnable()
@Override
public void run()
Toast.makeText(
getApplicationContext(),
"create camera session failed!",
Toast.LENGTH_SHORT
).show();
);
,null);
catch (CameraAccessException e)
e.printStackTrace();
private void openBackgroundThread()
mBackgroundThread=new HandlerThread("Camera2 background thread");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
private void closeBackgroundThread()
mBackgroundThread.quitSafely();
try
mBackgroundThread.join();
mBackgroundThread=null;
mBackgroundHandler=null;
catch (InterruptedException e)
e.printStackTrace();
private void lockFocus()
try
mState=STATE_WAIT_LOCK;
mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CaptureRequest.CONTROL_AF_TRIGGER_START);
mCameraCaptureSession.capture(mPreviewCaptureRequestBuilder.build(),
mSessionCaptureCallback,mBackgroundHandler);
catch (CameraAccessException e)
e.printStackTrace();
private void unLockFocus()
try
mState=STATE_PREVIEW;
mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
mCameraCaptureSession.capture(mPreviewCaptureRequestBuilder.build(),
mSessionCaptureCallback,mBackgroundHandler);
catch (CameraAccessException e)
e.printStackTrace();
private void captureStillImage()
try
CaptureRequest.Builder captureStillBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureStillBuilder.addTarget(mImageReader.getSurface());
// Use the same AE and AF modes as the preview.
captureStillBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// setAutoFlash(captureBuilder);
// Orientation
int rotation=0;
//Front camera
if(mCameraId.equals("1"))
rotation = this.getWindowManager().getDefaultDisplay().getRotation();
captureStillBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));
else
rotation = this.getWindowManager().getDefaultDisplay().getRotation();
captureStillBuilder.set(CaptureRequest.JPEG_ORIENTATION,
ORIENTATIONS.get(rotation));
CameraCaptureSession.CaptureCallback captureCallback =
new CameraCaptureSession.CaptureCallback()
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result)
super.onCaptureCompleted(session, request, result);
//Toast.makeText(getApplicationContext(),"Image Captured",Toast.LENGTH_SHORT).show();
unLockFocus();
;
mCameraCaptureSession.capture(
captureStillBuilder.build(),captureCallback,null
);
catch (CameraAccessException e)
e.printStackTrace();
private int getOrientation(int rotation)
return (ORIENTATIONS.get(rotation) + mSensorOrientation +180) % 360;
【问题讨论】:
你可以看看这个解决方案***.com/a/34841433/1840795 在授予权限之前您是否正在启动相机? 不,先生,我之前检查过许可。有时我成功地拍照了。但是,有时我失败了。 您能告诉我们您使用的是哪款智能手机/模拟器吗?如果您在另一台设备上测试过您的代码? 是的,我使用的是 Galaxy S7 和 Android M。我在 Android 5.0 中测试没有错误 【参考方案1】:setupCamera()
直接从onSurfaceTextureAvailable
调用,可以早于授予权限。
您需要做的是跟踪权限是否被授予以及表面纹理是否在两个回调中可用。
为检查这些条件和设置相机创建一个条目
private boolean mSurfaceTextureAvailable;
private boolean mPermissionsGranted;
private boolean mCameraOpened;
private void setupCameraIfPossible()
if (!mCameraOpened && mSurfaceTextureAvailable && mPermissionsGranted)
String cameraLens = BleUtils.getCameraLens(AndroidCamera.this);
if (TextUtils.isEmpty(cameraLens))
cameraLens = "1";
setupCamera(mTextureView.getWidth(), mTextureView.getHeight(), cameraLens);
openCamera();
private final TextureView.SurfaceTextureListener mSurfaceTextureListener =
new TextureView.SurfaceTextureListener()
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)
mSurfaceTextureAvailable = true;
setupCameraIfPossible();
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height)
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface)
//closeCamera();
mSurfaceTextureAvailable = false;
return false;
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface)
;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_activity);
openBackgroundThread();
// Make sure the boolean flag is set. Will be true for lower SDK
mPermissionsGranted = hasAllPermissions(this, PERMISSIONS);
if (!mPermissionsGranted)
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
mTextureView = (TextureView) findViewById(R.id.texture);
在onResume()
中,您不需要检查权限。如果他们在后台被拒绝,您的 Activity 将被终止,您将再次通过onCreate()
。
删除onPause()
和onResume()
中的代码!
// @Override
// public void onResume()
// super.onResume();
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
// if(!hasAllPermissions(this, PERMISSIONS))
// ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
//
//
// openBackgroundThread();
// if (mTextureView.isAvailable())
// if (!TextUtils.isEmpty(BleUtils.getCameraLens(AndroidCamera.this)))
// setupCamera(mTextureView.getWidth(), mTextureView.getHeight(),BleUtils.getCameraLens(AndroidCamera.this));
// else
// setupCamera(mTextureView.getWidth(), mTextureView.getHeight(),"1");
// closeCamera();
// openCamera();
// else
// mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
//
//
// public void onPause()
// Log.d(TAG,"onPause");
// closeCamera();
//
// closeBackgroundThread();
// super.onPause();
//
将此添加到onStart()
@Override
public void onStart()
super.onStart();
openCameraIfPossible();
将关闭相机移动到onStop()
@Override
public void onStop()
super.onStop();
closeCamera();
private void closeCamera()
mCameraOpened = false; // set a field indicating it is closed
...
private void openCamera()
...
mCameraOpened = true; // If successful, set a field indicating it is opened
现在我发现的另一件事是,您实际上必须检查 onRequestPermissionsResult()
中的权限,而不是使用 grantResults
标志
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
case REQUEST_CAMERA_RESULT:
mPermissionsGranted = hasAllPermissions(this, PERMISSIONS);
setupCameraIfPossible();
break;
default:
break;
【讨论】:
谢谢。我想你错过了调用函数openBackgroundThread
。其次,仍然是上述问题的错误。
@user3051460 是的,对不起,我错过了。编辑并添加到 onCreate()。你确定错误日志和上面一样吗?我无法运行您的代码,因为我没有 BleUtils 和您的布局。
等我一下。我会创建一个项目让你知道
终于,我得到了解决方案。问题是我在屏幕未准备好时开始预览(屏幕关闭然后打开)。为了解决这个问题,我添加了一个计时器来设置延迟时间。这是我的代码。您可以贡献并提供比使用计时器更好的解决方案。谢谢github.com/mjohn123/Camera2APIM
我接受了它以感谢您的帮助。此外,我需要将openBackgroundThread
移动到onResume
函数上,而不是onCreate.
让我们查看我的代码了解更多详情以上是关于在 Android 6.0 中缺乏访问相机服务的权限的主要内容,如果未能解决你的问题,请参考以下文章
Android 6.0 RuntimeException:无法连接到相机服务