使用FileProvider拍摄照片后无法保存在图库中
问题描述:
由于我已经使用FileProvider将我的应用程序迁移到了Android N,因此我无法在手机的图库中看到我的图片(即使是低于Android N的版本)。所以我创建了一个小测试应用程序来调试,没有成功。使用FileProvider拍摄照片后无法保存在图库中
在我的清单
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
<application
...>
...
<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/file_paths"></meta-data>
</provider>
</application>
在file_paths.xml
<paths>
<external-files-path
name="test_images"
path="Pictures/TestPictures"/>
</paths>
而且我做了一个小活动,显示最后拍摄的照片,以确保URI是正确的:
private final static int REQUEST_CAMERA = 1102;
public static final String CAMERA_IMAGES_DIR = "TestPictures";
String mOutputFilePath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onCamera();
}
});
}
public void onCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
File photoFile = createImageFile();
Uri photoURI = FileProvider.getUriForFile(this,
getPackageName() + ".fileprovider",
photoFile);
mOutputFilePath = photoFile.getAbsolutePath();
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(intent, REQUEST_CAMERA);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CAMERA)
onCaptureImageResult();
}
private void onCaptureImageResult() {
if (mOutputFilePath != null) {
File f = new File(mOutputFilePath);
Uri finalUri = Uri.fromFile(f);
galleryAddPic(finalUri);
((ImageView) findViewById(R.id.imageView)).setImageURI(finalUri);
}
}
public File createImageFile() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), CAMERA_IMAGES_DIR + "/");
if (!storageDir.exists())
storageDir.mkdir();
return new File(storageDir, imageFileName + ".jpg");
}
private void galleryAddPic(Uri contentUri) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, contentUri);
sendBroadcast(mediaScanIntent);
}
我的照片是在我的应用程序和我的文件浏览器像预期的,但我不能在照片库中看到它。 我试图使用FileProvider Uri,这不起作用。
答
问题似乎是要添加到图库的文件的位置,而不是添加它的方式。
getExternalFilesDir(Environment.DIRECTORY_PICTURES)没有为介质扫描,但Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)做工作。但是,我们不能使用FileProvider中的最后一个,所以我需要在公共目录中创建拍摄照片的副本。
更新我的代码,如:
private void onCaptureImageResult() {
if (mOutputFilePath != null) {
File f = new File(mOutputFilePath);
try {
File publicFile = copyImageFile(f);
Uri finalUri = Uri.fromFile(publicFile);
galleryAddPic(finalUri);
((ImageView) findViewById(R.id.imageView)).setImageURI(finalUri);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public File copyImageFile(File fileToCopy) throws IOException {
File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), CAMERA_IMAGES_DIR + "/");
if (!storageDir.exists())
storageDir.mkdir();
File copyFile = new File(storageDir, fileToCopy.getName());
copyFile.createNewFile();
copy(fileToCopy, copyFile);
return copyFile;
}
public static void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
+0
查看https://*.com/a/33031091/966789 (Android为Android 6.0 Marshmallow添加了新的权限模型) –
https://*.com/questions/32789157/how-to-write-files-to-external-public-storage-in-android-so-这是他们是可见的 – CommonsWare
在画廊中添加我的照片的方式不是问题,但我注意到您分享的线程中使用的目录,它帮助我找到解决方案,thx。 – Silwek