我想在Android文件系统中添加新功能后修复问题,但我收到此错误:
android.os.FileUriExposedException: file:///storage/emulated/0/MyApp/Camera_20180105_172234.jpg exposed beyond app through ClipData.Item.getUri()
所以我希望有人可以帮我解决这个问题:)
由于
private Uri getTempUri() {
// Create an image file name
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
String dt = sdf.format(new Date());
imageFile = null;
imageFile = new File(Environment.getExternalStorageDirectory()
+ "/MyApp/", "Camera_" + dt + ".jpg");
AppLog.Log(
TAG,
"New Camera Image Path:- "
+ Environment.getExternalStorageDirectory()
+ "/MyApp/" + "Camera_" + dt + ".jpg");
File file = new File(Environment.getExternalStorageDirectory() + "/MyApp");
if (!file.exists()) {
file.mkdir();
}
imagePath = Environment.getExternalStorageDirectory() + "/MyApp/"
+ "Camera_" + dt + ".jpg";
imageUri = Uri.fromFile(imageFile);
return imageUri;
}
答案 0 :(得分:102)
在开始相机或文件浏览之前添加以下代码块
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
请参阅推荐链接strict mode及其解释的所有用法和技术细节。
答案 1 :(得分:84)
对于sdk 24及更高版本,如果您需要在应用程序存储区外获取文件的Uri,则会出现此错误。
@ eranda.del解决方案允许您更改策略以允许此操作并且它正常工作。
但是,如果您想要遵循Google指南而无需更改应用的API政策,则必须使用FileProvider。
首先要获取文件的URI,你需要使用FileProvider.getUriForFile()方法:
Uri imageUri = FileProvider.getUriForFile(
MainActivity.this,
"com.example.homefolder.example.provider", //(use your app signature + ".provider" )
imageFile);
然后您需要在Android清单中配置您的提供程序:
<application>
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.homefolder.example.provider"
android:exported="false"
android:grantUriPermissions="true">
<!-- ressource file to create -->
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths">
</meta-data>
</provider>
</application>
(&#34;权限&#34;使用与getUriForFile()方法的第二个参数相同的值(app signature +&#34; .provider&#34;)
最后你需要创建ressources文件:&#34; file_paths&#34;。 需要在res / xml目录下创建此文件(您可能还需要创建此目录):
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />
</paths>
答案 2 :(得分:0)
无需在AndroidManifest中进行提供程序的任何配置,仅允许“摄像头和存储”权限。使用以下代码启动相机:
final int REQUEST_ACTION_CAMERA = 9;
void openCamra() {
Intent cameraImgIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraImgIntent.putExtra(MediaStore.EXTRA_OUTPUT,
FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID +".provider",
new File("your_file_name_with_dir")));
startActivityForResult(cameraImgIntent, REQUEST_ACTION_CAMERA);
}
捕获图像后,您可以在以下位置找到捕获的图像:
"your_file_name_with_dir"
答案 3 :(得分:0)
在其中添加代码
onCreate(Budle savedInstancesState){
if (Build.VERSION.SDK_INT >= 24) {
try {
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
m.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
}