I am trying to develop a camera instant app, but it always posts a crash when I open the camera by manager.openCamera(cameraId, mStateCallback, null);
:
09-10 21:00:55.333 9472-9472/com.pixelslab.stickerpe I/CameraManager: Using legacy camera HAL.
09-10 21:00:55.340 1402-1914/? I/CameraService: CameraService::connect call (PID -1 "com.pixelslab.stickerpe", camera ID 0) for HAL version default and Camera API version 1
09-10 21:00:55.340 1402-1914/? W/ServiceManager: Permission failure: android.permission.CAMERA from uid=10088 pid=9472
09-10 21:00:55.340 1402-1914/? E/CameraService: Permission Denial: can't use the camera pid=9472, uid=10088
09-10 21:00:55.345 9472-9472/com.pixelslab.stickerpe D/AndroidRuntime: Shutting down VM
09-10 21:00:55.348 9472-9472/com.pixelslab.stickerpe E/AndroidRuntime: FATAL EXCEPTION:
main Process: com.pixelslab.stickerpe, PID: 9472
java.lang.SecurityException: Lacking privileges to access camera service
at android.hardware.camera2.CameraManager.throwAsPublicException(CameraManager.java:643)
at android.hardware.camera2.CameraManager.openCameraDeviceUserAsync(CameraManager.java:340)
at android.hardware.camera2.CameraManager.openCameraForUid(CameraManager.java:466)
at android.hardware.camera2.CameraManager.openCamera(CameraManager.java:430)
at com.gomo.minivideo.camera2.Camera2VideoFragment.openCamera(Camera2VideoFragment.java:378)
at com.gomo.minivideo.camera2.Camera2VideoFragment.access$000(Camera2VideoFragment.java:65)
at com.gomo.minivideo.camera2.Camera2VideoFragment$1.onSurfaceTextureAvailable(Camera2VideoFragment.java:120)
at android.view.TextureView.getHardwareLayer(TextureView.java:390)
at android.view.TextureView.draw(TextureView.java:339)
at android.view.View.updateDisplayListIfDirty(View.java:18069)
at android.view.View.draw(View.java:18847)
at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
at android.view.View.updateDisplayListIfDirty(View.java:18060)
at android.view.View.draw(View.java:18847)
at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
at android.view.View.updateDisplayListIfDirty(View.java:18060)
at android.view.View.draw(View.java:18847)
at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
at android.view.View.updateDisplayListIfDirty(View.java:18060)
at android.view.View.draw(View.java:18847)
at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
at android.view.View.updateDisplayListIfDirty(View.java:18060)
at android.view.View.draw(View.java:18847)
at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
at android.view.View.updateDisplayListIfDirty(View.java:18060)
at android.view.View.draw(View.java:18847)
at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
at android.view.View.updateDisplayListIfDirty(View.java:18060)
at android.view.View.draw(View.java:18847)
at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
at android.view.View.updateDisplayListIfDirty(View.java:18060)
at android.view.View.draw(View.java:18847)
at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
at android.view.View.draw(View.java:19122)
at com.android.internal.policy.DecorView.draw(DecorView.java:785)
at android.view.View.updateDisplayListIfDirty(View.java:18069)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:643)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:649)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:757)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2980)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2794)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2347)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1386)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6733)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:658)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
09-10 21:00:55.349 9472-9472/com.pixelslab.stickerpe E/AndroidRuntime:
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: android.os.ServiceSpecificException: Lacking privileges to access camera service (code 1)
at android.hardware.camera2.legacy.LegacyExceptionUtils.throwOnServiceError(LegacyExceptionUtils.java:132)
at android.hardware.camera2.legacy.CameraDeviceUserShim.connectBinderShim(CameraDeviceUserShim.java:374)
at android.hardware.camera2.CameraManager.openCameraDeviceUserAsync(CameraManager.java:317)
... 61 more
However, I am sure that I have camera-permission granted, because the same code run successfully in installed version.
Can anyone solve this? Thank you!
Here is the code went crash:
// CameraFragment.java
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) {
}
};
private void openCamera(int width, int height) {
final Activity activity = getActivity();
if (null == activity || activity.isFinishing()) {
return;
}
CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
try {
Log.d(TAG, "tryAcquire");
if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Time out waiting to lock camera opening.");
}
String cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics
.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
if (map == null) {
throw new RuntimeException("Cannot get available preview/video sizes");
}
mVideoSize = chooseVideoSize(map.getOutputSizes(MediaRecorder.class));
mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
width, height, mVideoSize);
int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
mTextureView.setAspectRatio(mPreviewSize.getWidth(), mPreviewSize.getHeight());
} else {
mTextureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth());
}
configureTransform(width, height);
mMediaRecorder = new MediaRecorder();
manager.openCamera(cameraId, mStateCallback, null); // here will crash!!!
} catch (CameraAccessException e) {
Toast.makeText(activity, "Cannot access the camera.", Toast.LENGTH_SHORT).show();
activity.finish();
} catch (NullPointerException e) {
ErrorDialog.newInstance(getString(R.string.camera_error))
.show(getChildFragmentManager(), FRAGMENT_DIALOG);
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while trying to lock camera opening.");
}
}
And here is how I get the camera permission:
// MainActivity.java
private void requestCameraPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
Snackbar.make(mRootView, R.string.permission_camera_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, new View.OnClickListener() {
@Override
public void onClick(View view) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, REQUEST_CAMERA);
}
})
.show();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA,
Manifest.permission.INTERNET, Manifest.permission.RECORD_AUDIO}, REQUEST_CAMERA);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CAMERA) {
if (grantResults.length >= 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getSupportFragmentManager().beginTransaction().replace(R.id.content_layout, Camera2VideoFragment.newInstance()).commitAllowingStateLoss();
//getSupportFragmentManager().beginTransaction().replace(R.id.content_layout, new CameraFragment()).commitAllowingStateLoss();
}
}
}
And then here is my full manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pixelslab.stickerpe">
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:xlargeScreens="true" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:name="com.gomo.minivideo.CameraApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/CameraTheme">
<activity
android:name="com.gomo.minivideo.MainActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:launchMode="singleTop"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="default-url"
android:value="https://hugo775128583.github.io/main" />
<intent-filter android:order="1" android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="hugo775128583.github.io"
android:pathPrefix="/main" />
</intent-filter>
<intent-filter android:order="1" android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="http"
android:host="hugo775128583.github.io"
android:pathPrefix="/main" />
</intent-filter>
</activity>
<service android:name="com.jb.zcamera.camera.ProcessVideoService" />
<activity android:name="com.gomo.minivideo.camera.ShareActivity" />
<activity android:name="com.gomo.minivideo.camera.VideoViewActivity" />
</application>
</manifest>
With reference to Google issue tracker,
This issue has been fixed and rolled out on 8.1 devices already. We are working with our partners to roll out the fix into the update for 8.0 devices. We expect those updates to be rolled out in the coming months.
If any issue persists, please report at Google issue tracker they will re-open to examine.