不幸的是,相机在 Kitkat 中停止工作
unfortunately camera has stopped working in Kitkat
我正在尝试在 Android 中集成拍照。虽然 运行 我收到的应用程序和错误“不幸的是,相机已停止 ”,但我的应用程序没有崩溃。我在 Android "KITKAT" 中发现了这个问题。这是我用来拍照的示例代码,
使用这个功能我正在拍照,
private void take_picture_intent() {
Intent takePictureIntent = (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
? new Intent(MediaStore.ACTION_IMAGE_CAPTURE_SECURE)
: new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(this.getActivity().getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(this.getActivity(), "com.android.myapplication.fileprovider", photoFile);
Log.e(TAG, "photoFile: "+photoFile+" ,URI : "+photoURI.getPath());
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
getActivity().startActivityForResult(takePictureIntent, SelectMedia.IMAGE_CAPTURE_AT_THE_DOOR);
}
}
}
此函数用于生成图片路径,
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
if (!storageDir.exists())
storageDir.mkdirs();
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
这是日志,
10-11 12:35:12.691 18815-18815/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sec.android.app.camera, PID: 18815
java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from
ProcessRecord{42d78c60 18815:com.sec.android.app.camera/u0a84} (pid=18815, uid=10084) that is not exported from uid 10786
at android.os.Parcel.readException(Parcel.java:1472)
at android.os.Parcel.readException(Parcel.java:1426)
at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:3201)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:4824)
at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2532)
at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1425)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:906)
at android.content.ContentResolver.openOutputStream(ContentResolver.java:669)
at android.content.ContentResolver.openOutputStream(ContentResolver.java:645)
at com.sec.android.app.camera.Camera$LastContentUriCallback.onCompleted(Camera.java:21369)
at com.sec.android.app.camera.Camera.onLaunchGalleryForImage(Camera.java:12409)
at com.sec.android.app.camera.Camera.onImageStoringCompleted(Camera.java:11140)
at com.sec.android.app.camera.CommonEngine.imageStoringCompleted(CommonEngine.java:6954)
at com.sec.android.app.camera.CeStateInitialized.handleMessage(CeStateInitialized.java:47)
at com.sec.android.app.camera.CommonEngine$StateMessageHandler.handleMessage(CommonEngine.java:957)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5590)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
10-11 12:35:13.021 600-19132/? E/android.os.Debug: !@Dumpstate > sdumpstate -k -t -z -d -m 18815 -o /data/log/dumpstate_app_error
添加特定包名的棒棒糖前版本的权限,之后就可以访问了。
getApplicationContext().grantUriPermission(getCallingPackage(),
contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
我发现这个问题是由于 URI 的转换。我已经通过替换
解决了这个问题
FileProvider.getUriForFile(getApplicationContext(), "com.android.myapplication.fileprovider", photoFile);
通过添加条件,
if ((Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT))
photoURI = FileProvider.getUriForFile(getApplicationContext(), "com.android.myapplication.fileprovider", photoFile);
else
photoURI = Uri.fromFile(photoFile);
在 take_picture_intent()
函数上。
此外,在我的清单中,我已删除权限,
<uses-permission android:name="android.permission.CAMERA" />
我正在尝试在 Android 中集成拍照。虽然 运行 我收到的应用程序和错误“不幸的是,相机已停止 ”,但我的应用程序没有崩溃。我在 Android "KITKAT" 中发现了这个问题。这是我用来拍照的示例代码,
使用这个功能我正在拍照,
private void take_picture_intent() {
Intent takePictureIntent = (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
? new Intent(MediaStore.ACTION_IMAGE_CAPTURE_SECURE)
: new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(this.getActivity().getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(this.getActivity(), "com.android.myapplication.fileprovider", photoFile);
Log.e(TAG, "photoFile: "+photoFile+" ,URI : "+photoURI.getPath());
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
getActivity().startActivityForResult(takePictureIntent, SelectMedia.IMAGE_CAPTURE_AT_THE_DOOR);
}
}
}
此函数用于生成图片路径,
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
if (!storageDir.exists())
storageDir.mkdirs();
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
这是日志,
10-11 12:35:12.691 18815-18815/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sec.android.app.camera, PID: 18815
java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from
ProcessRecord{42d78c60 18815:com.sec.android.app.camera/u0a84} (pid=18815, uid=10084) that is not exported from uid 10786
at android.os.Parcel.readException(Parcel.java:1472)
at android.os.Parcel.readException(Parcel.java:1426)
at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:3201)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:4824)
at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2532)
at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1425)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:906)
at android.content.ContentResolver.openOutputStream(ContentResolver.java:669)
at android.content.ContentResolver.openOutputStream(ContentResolver.java:645)
at com.sec.android.app.camera.Camera$LastContentUriCallback.onCompleted(Camera.java:21369)
at com.sec.android.app.camera.Camera.onLaunchGalleryForImage(Camera.java:12409)
at com.sec.android.app.camera.Camera.onImageStoringCompleted(Camera.java:11140)
at com.sec.android.app.camera.CommonEngine.imageStoringCompleted(CommonEngine.java:6954)
at com.sec.android.app.camera.CeStateInitialized.handleMessage(CeStateInitialized.java:47)
at com.sec.android.app.camera.CommonEngine$StateMessageHandler.handleMessage(CommonEngine.java:957)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5590)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
10-11 12:35:13.021 600-19132/? E/android.os.Debug: !@Dumpstate > sdumpstate -k -t -z -d -m 18815 -o /data/log/dumpstate_app_error
添加特定包名的棒棒糖前版本的权限,之后就可以访问了。
getApplicationContext().grantUriPermission(getCallingPackage(),
contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
我发现这个问题是由于 URI 的转换。我已经通过替换
解决了这个问题FileProvider.getUriForFile(getApplicationContext(), "com.android.myapplication.fileprovider", photoFile);
通过添加条件,
if ((Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT))
photoURI = FileProvider.getUriForFile(getApplicationContext(), "com.android.myapplication.fileprovider", photoFile);
else
photoURI = Uri.fromFile(photoFile);
在 take_picture_intent()
函数上。
此外,在我的清单中,我已删除权限,
<uses-permission android:name="android.permission.CAMERA" />