【发布时间】:2017-04-06 06:46:12
【问题描述】:
我的应用程序(使用小于 24 的 SDK)可以使用相机拍摄照片和视频。可以在应用程序外部的图库中查看照片和视频。 SDK 24 及更高版本需要 FileProvider 创建用于将照片或视频保存到图库的 uri。
在 SDK 24 之前,我会使用 uri 和 intent 来拍照:
private void openCameraForResult(int requestCode){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
picturesDirectoryPhotoFileName = nextFileName();
File photoFile = makePicturesPhotoFile();
Uri uri = Uri.fromFile(photoFile);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, requestCode);
}
private File makePicturesPhotoFile() {
File photoGallery = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File media = new File(photoGallery, picturesDirectoryPhotoFileName);
return media;
}
使用 SDK 24 及更高版本时发生异常:
Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/126cfd69-59c6-4534-9b2e-4af9753d3643.jpg exposed beyond app through ClipData.Item.getUri()
我想使用 FileProvider 实现相同(无一例外)。下面的实现可以拍照,但它不会出现在图库中。我想知道我做错了什么。
AndroidManifest.xml:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="Pictures" path="Pictures"/>
<external-path name="Movies" path="Movies"/>
</paths>
拍照:
private void openCameraForResult(int requestCode){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
picturesDirectoryPhotoFileName = nextFileName();
File photoFile = makePicturesPhotoFile();
getDependencyService().getLogger().debug(photoFile.getAbsolutePath());
Uri uri = fileProviderUri.makeUriUsingSdkVersion(photoFile);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, requestCode);
}
制作乌里
private static final String AUTHORITY_FORMAT = "%s.fileprovider";
public Uri makeUriUsingSdkVersion(File file) {
Uri uri;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
uri = Uri.fromFile(file);
} else {
String packageName = getApplicationContext().getPackageName();
String authority = String.format(Locale.getDefault(), AUTHORITY_FORMAT, packageName);
uri = getUriForFile(getApplicationContext(), authority, file);
}
return uri;
}
【问题讨论】:
-
The implementation below can take a photo but the it does not appear in the gallery.上面的旧实现可以拍照但它也不会出现在图库中。