Reputation: 3
I am trying to add camera 2 API on my app using Google examples. My app has permission to use camera, and old API works fine. I have check more than one the permission even line before to execute the code in which Android throws the exceptions but I still receive Lacking privileges to access camera service.
private void createCameraPreviewSession() {
try{
SurfaceTexture texture = mTextureView.getSurfaceTexture();
//assert texture != null;
Log.d(TAG,String.format("Textureview is null: %b, texture is null: %b",mTextureView==null, texture==null));
// We configure the size of default buffer to be the size of camera preview we want.
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
// This is the output Surface we need to start preview.
Surface surface = new Surface(texture);
// We set up a CaptureRequest.Builder with the output Surface.
if (ActivityCompat.checkSelfPermission(a, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Permission granted");
mPreviewRequestBuilder= mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
Log.d(TAG, "Capture request created");
}
else{
return ;
}
mPreviewRequestBuilder.addTarget(surface);
// Here, we create a CameraCaptureSession for camera preview.
mCameraDevice.createCaptureSession(Arrays.asList(surface),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (null == mCameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
mCaptureSession = cameraCaptureSession;
try {
// Auto focus should be continuous for camera preview.
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// Finally, we start displaying the camera preview.
mPreviewRequest = mPreviewRequestBuilder.build();
mCaptureSession.setRepeatingRequest(mPreviewRequest, null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(
@NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(a,a.getString(R.string.error_configuring_camera),Toast.LENGTH_LONG).show();
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
Here is the log:
12-02 20:30:07.427 697-697/kiam.cameraintentpractice.pendant D/ICAMERA2: Textureview is null: false, texture is null: false
12-02 20:30:07.428 697-697/kiam.cameraintentpractice.pendant D/ICAMERA2: Permission granted
12-02 20:30:07.429 697-697/kiam.cameraintentpractice.pendant D/AndroidRuntime: Shutting down VM
12-02 20:30:07.430 697-697/kiam.cameraintentpractice.pendant E/AndroidRuntime: FATAL EXCEPTION: main
Process: kiam.cameraintentpractice.pendant, PID: 697
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.createDefaultRequest(Unknown Source)
at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureRequest(CameraDeviceImpl.java:636)
at kiam.cameraintentpractice.model.CameraV2.createCameraPreviewSession(CameraV2.java:377)
at kiam.cameraintentpractice.model.CameraV2.access$400(CameraV2.java:55)
at kiam.cameraintentpractice.model.CameraV2$2.onOpened(CameraV2.java:340)
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:5525)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
12-02 20:30:08.752 697-797/kiam.cameraintentpractice.pendant D/TaskManager: Error processing queue - Call: 3
Code is called form here:
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice cameraDevice) {
// This method is called when the camera is opened. We start camera preview here.
mCameraOpenCloseLock.release();
mCameraDevice = cameraDevice;
createCameraPreviewSession();
}
@Override
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
mCameraOpenCloseLock.release();
cameraDevice.close();
mCameraDevice = null;
}
@Override
public void onError(@NonNull CameraDevice cameraDevice, int error) {
mCameraOpenCloseLock.release();
cameraDevice.close();
mCameraDevice = null;
Toast.makeText(a, a.getString(R.string.error_using_camera), Toast.LENGTH_SHORT).show();
a.finish();
}
};
And the callback proceed form here:
private void openCamera(int width, int height) {
if (ContextCompat.checkSelfPermission(a, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Permission denied");
return;
}
setUpCameraOutputs(width, height);
configureTransform(width, height);
try {
/*if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Time out waiting to lock camera opening.");
}*/
if (ActivityCompat.checkSelfPermission(a, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Permission accepted");
CameraManager manager = (CameraManager) a.getSystemService(Context.CAMERA_SERVICE);
manager.openCamera(mCameraId, mStateCallback, null);
}
else{
Log.d(TAG, "Permission denied");
return;
}
} catch (CameraAccessException e) {
e.printStackTrace();
} /*catch (InterruptedException e) {
throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
}*/
}
Edit - Posting manifest as requested
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.front"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:screenOrientation="reversePortrait"
android:hardwareAccelerated="true">
<activity
android:name=".UI.ImageAcquisition"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:screenOrientation="reversePortrait"
/>
<activity
android:name=".UI.ImageManipulation"
android:label="@string/title_activity_image_manuplation"
android:launchMode="singleTop"
android:screenOrientation="reversePortrait"
android:theme="@style/AppTheme" />
<activity
android:name=".UI.ProjectsActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:screenOrientation="reversePortrait">
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".UI.IndividualProjectDetailActivity"
android:label="@string/title_activity_individual_project_detail"
android:parentActivityName=".UI.ProjectsActivity"
android:theme="@style/AppTheme"
android:screenOrientation="reversePortrait">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="kiam.cameraintentpractice.UI.ProjectsActivity" />
</activity>
<service
android:name=".model.CalculatorService"
android:enabled="true"
android:exported="true"></service>
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
</application>
Upvotes: 0
Views: 2674
Reputation: 2464
Don't put the delay for the opening camera. Just closeCamera() in onSurfaceTextureDestroyed() method of SurfaceTextureListener.
Upvotes: 2
Reputation: 36
I had the same issue on devices like the Samsung Galaxy S7. I resolved it by adding a delay before opening the camera as follow :
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mSurfaceTextureAvailable = true;
if (ContextCompat.checkSelfPermission(CameraActivity.this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(CameraActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
return;
}else {
mPermissionsGranted = true;
// Execute some code after 500 milliseconds have passed
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
setupCameraIfPossible();
}
}, 500);
}
}
...
Here is the method I used to open the camera :
private void setupCameraIfPossible() {
if (mSurfaceTextureAvailable && mPermissionsGranted) {
openCamera();
}
}
I hope it will help you
Upvotes: 1