我的应用程序(使用少于24的SDK)可以使用相机拍摄照片和视频。可以在应用程序外的图库中查看照片和视频。 SDK 24及更高版本要求FileProvider创建用于将照片或视频保存到图库的uri。
在SDK 24之前,我会使用uri和意图拍照:
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);
}
制作Uri
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;
}
答案 0 :(得分:2)
照片出现在GT-I9300 Galaxy S3的图库中,所以我知道代码可以在该设备上运行。在Galaxy 7上,在手机开启和关闭之前,照片不会出现在图库中。
经过多天的研究,答案是使用文件上的媒体扫描更新图库。仅在PICTURES目录中创建照片是不够的。这是一个扫描单个文件的类:
import android.app.Activity;
import android.media.MediaScannerConnection;
import android.net.Uri;
import java.io.File;
class Gallery implements IGallery {
private Activity activity;
public Gallery(Activity activity) {
this.activity = activity;
}
@Override
public void scanFile(File file) {
if(activity == null || file == null) {
return;
}
MediaScannerConnection.scanFile(activity,
new String[] { file.getAbsolutePath() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
}
});
}
}