FileProvider不能使用相机
我试图让相机应用程序将输出存储到我的内部存储。 我也明白,第三方应用程序无法访问我的应用程序的内部存储, 但我们可以通过FileProvider
公开内部目录来FileProvider
。 我在这里遵循指南:
- 相机意图不保存照片
- https://developer.android.com/reference/android/support/v4/content/FileProvider.html
我用下面的方式指定我的AndroidManifest.xml
:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.stackoverflow.test.camerawithfileprovider" > <application> <activity ... </activity> <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.stackoverflow.test.camerawithfileprovider.fileprovider" android:exported="false" android:grantUriPermissions="true" > <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_provider_path" /> </provider> </application> </manifest>
我在/res/xml/
创build了名为file_provider_path.xml
的xml文件:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="image_capture" path="public/" /> </paths>
这是我创build和调用相机意图的方式:
private static final int CAMERA_REQUEST_CODE = 5000; private static final String CAMERA_FP_AUTHORITY = "com.stackoverflow.test.camerawithfileprovider.fileprovider"; Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); Context context = MainActivity.this; File imagePath = new File(context.getFilesDir(), "public"); if (!imagePath.exists()) imagePath.mkdirs(); File newFile = new File(imagePath, "tmp.jpg"); Uri imageUri = FileProvider.getUriForFile(context, CAMERA_FP_AUTHORITY, newFile); //context.grantUriPermission("com.google.android.GoogleCamera", imageUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); Log.d("YouQi", "Image URI Passing to Camera: " + imageUri.toString()); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); startActivityForResult(intent, CAMERA_REQUEST_CODE);
当我运行应用程序时,我可以得到下面的Logcat结果:
11-11 20:07:39.581 18303-18303/com.stackoverflow.test.camerawithfileprovider D/YouQi: Image URI Passing to Camera: content://com.stackoverflow.test.camerawithfileprovider.fileprovider/image_capture/tmp.jpg
在相机closures的那一刻,我碰到下面的例外情况:
com.google.android.GoogleCamera E/AndroidRuntime: FATAL EXCEPTION: main com.google.android.GoogleCamera E/AndroidRuntime: Process: com.google.android.GoogleCamera, PID: 19420 com.google.android.GoogleCamera E/AndroidRuntime: java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{42e44f70 19420:com.google.android.GoogleCamera/u0a83} (pid=19420, uid=10083) that is not exported from uid 10312 com.google.android.GoogleCamera E/AndroidRuntime: at android.os.Parcel.readException(Parcel.java:1465) com.google.android.GoogleCamera E/AndroidRuntime: at android.os.Parcel.readException(Parcel.java:1419) com.google.android.GoogleCamera E/AndroidRuntime: at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2882) com.google.android.GoogleCamera E/AndroidRuntime: at android.app.ActivityThread.acquireProvider(ActivityThread.java:4544) com.google.android.GoogleCamera E/AndroidRuntime: at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2274) com.google.android.GoogleCamera E/AndroidRuntime: at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1425) com.google.android.GoogleCamera E/AndroidRuntime: at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:906) com.google.android.GoogleCamera E/AndroidRuntime: at android.content.ContentResolver.openOutputStream(ContentResolver.java:669) com.google.android.GoogleCamera E/AndroidRuntime: at android.content.ContentResolver.openOutputStream(ContentResolver.java:645) com.google.android.GoogleCamera E/AndroidRuntime: at com.android.camera.PhotoModule.onCaptureDone(PhotoModule.java:1281) com.google.android.GoogleCamera E/AndroidRuntime: at com.android.camera.PhotoModule$8.onClick(PhotoModule.java:593) com.google.android.GoogleCamera E/AndroidRuntime: at android.view.View.performClick(View.java:4445) com.google.android.GoogleCamera E/AndroidRuntime: at android.view.View$PerformClick.run(View.java:18446) com.google.android.GoogleCamera E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:733) com.google.android.GoogleCamera E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95) com.google.android.GoogleCamera E/AndroidRuntime: at android.os.Looper.loop(Looper.java:136) com.google.android.GoogleCamera E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5146) com.google.android.GoogleCamera E/AndroidRuntime: at java.lang.reflect.Method.invokeNative(Native Method) com.google.android.GoogleCamera E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:515) com.google.android.GoogleCamera E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732) com.google.android.GoogleCamera E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566) com.google.android.GoogleCamera E/AndroidRuntime: at dalvik.system.NativeStart.main(Native Method)
任何人都可以帮助解释为什么问题发生? 我已经创build了我的问题的示例项目: http : //www.axzae.com/downloads/CameraWithFileProvider.zip
无论如何,应用程序将工作,如果我明确指定:
context.grantUriPermission( "com.google.android.GoogleCamera", imageUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION );
但是这只适用于nexus / cyanogen设备。 三星相机应用程序可能会使用不同的包名称。
-
请不要试图把
pskink
指出的exported="true"
,你的应用程序在加载的时候会崩溃。 FileProvider并不意味着在这种状态下工作。 -
试用了
CommonsWare
intent.addFlags
解决scheme。 不工作。 可能只会使用ACTION_SEND
types的意图。 -
我在这篇文章中find了答案。 显然手动授权方式是唯一的解决scheme。 但是我们总是可以遍历候选包列表并授予所有这些包。
List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo resolveInfo : resInfoList) { String packageName = resolveInfo.activityInfo.packageName; context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); }
我有一个类似的问题,但后来发现我的代码有一个错字。 错字是在AndroidManifest.xml中,正好在“权限”行的标签中。
为了我,
android:authorities="com.stackoverflow.test.camerawithfileprovider.fileprovider"
不起作用(当我调用相机实例,应用程序崩溃),但如果我删除“文件”,并replace该string如下:
android:authorities="com.stackoverflow.test.camerawithfileprovider.provider"
我的应用程序运行顺利(应用程序拍摄照片,存储它,并预览给客户端应用程序中的活动)。
你的应用程序也有同样的问题?