[英]I can't save file to gallery after taking photo by camera by using the FileProvider for Android 7.1.1
I build my app with FileProvider and I want to save the image after I take it. 我使用FileProvider构建我的应用程序,我想在我拿它之后保存图像。 But I can't find the image in the gallery. 但我无法在画廊中找到图像。 I found these source codes from the Android Studio tutorial. 我在Android Studio教程中找到了这些源代码。 I don't know what is the problem. 我不知道是什么问题。 I tried use debugger and I think the createFile() is correct. 我尝试使用调试器,我认为createFile()是正确的。 I also have my bitmap works. 我也有我的位图工作。 It can display the image I take but I can't add the image to the gallery. 它可以显示我拍摄的图像,但我无法将图像添加到图库。
I have this in my Manifest.xml 我在Manifest.xml中有这个
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.temp.test"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
And in the file_paths.xml I have 在我有的file_paths.xml中
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external" path="Android/data/com.temp.test/files/Pictures" />
</paths>
This is how I write the activity 这就是我写活动的方式
private String mCurrentPhotoPath;
private ImageView mImageView;
private ImageButton StartCameraBtn;
private File photoFile = null;
//requestCode
private static final int REQUEST_IMAGE_CAPTURE = 1;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo_note);
mImageView = (ImageView) findViewById(R.id.imageView);
StartCameraBtn = (ImageButton) findViewById(R.id.StartCamera);
StartCameraBtn.setOnClickListener(this);
}
public void onClick(View view)
{
clearAllFocus();
switch (view.getId())
{
case R.id.StartCamera:
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null)
{
try
{
photoFile = createFile();
}
catch (IOException e)
{
e.printStackTrace();
}
if(photoFile != null){
Uri photoURI = FileProvider.getUriForFile(this,
"com.temp.test",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
break;
...
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
mImageView.setImageBitmap(null);
switch (requestCode)
{
case REQUEST_IMAGE_CAPTURE:
if (resultCode == RESULT_OK)
{
setPic();
galleryAddPic();
}
break;
}
}
private File createFile() throws IOException
{
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
private void galleryAddPic()
{
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
private void setPic()
{
// Get the dimensions of the View
int targetW = mImageView.getWidth();
int targetH = mImageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
mImageView.setImageBitmap(bitmap);
}
Please help! 请帮忙! Thank you! 谢谢!
I use debugger to test the galleryaddpic() and the URI has been accessed sucessfully, but I don't know why I can't add it to the gallery. 我使用调试器来测试galleryaddpic()并且已经成功访问了URI,但我不知道为什么我无法将它添加到库中。 I can't find the image file in the android VM directory either. 我也找不到android VM目录中的图像文件。 This is the debug log: 这是调试日志:
https://i.stack.imgur.com/JN9uJ.png https://i.stack.imgur.com/JN9uJ.png
I'm using chickendinner as my domian, and keep is the name of my app. 我正在使用chickendinner作为我的domian,而keep是我的应用程序的名称。
Thank you! 谢谢!
Your code handles 你的代码处理
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
通过broadcst Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
将新照片添加到media-db FileProvider
that allow other apps to access private //Android/data/com.temp.test/files/Pictures/...
files through a content-uri content://com.temp.test/...
创建一个FileProvider
,允许其他应用程序通过content-uri content://com.temp.test/...
访问私人//Android/data/com.temp.test/files/Pictures/...
文件content://com.temp.test/...
I assume that the media-db scanner has no read-permission to your app-s private data directory Android/data/com.temp.test/files/Pictures
via a file-uri and therefore cannot add the new photo to media-db. 我假设media-db扫描程序没有对你的应用程序的私有数据目录Android/data/com.temp.test/files/Pictures
通过文件uri的读取权限,因此无法将新照片添加到media-db 。
Whatsapp and other apps store their received/send photo in public readable internal memory (ie /sdcard/PICTURES/WhatsApp/ ) where the media scanner can read it via file-uri via Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
. Whatsapp和其他应用程序将他们收到/发送的照片存储在公共可读的内部存储器(即/ sdcard / PICTURES / WhatsApp /)中,媒体扫描器可以通过文件uri通过Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
读取它。
I donot know, if the media scanner can handle content: -uris
instead of file uri-s
: You can try this: 我不知道,如果媒体扫描仪可以处理content: -uris
而不是file uri-s
:你可以试试这个:
private void galleryAddPic()
{
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
// assume that mCurrentPhotoPath ="Android/data/com.temp.test/files/Pictures/myTestImage.jpg"
// can be accessed from outside as "content://com.temp.test/myTestImage.jpg"
Uri contentUri = Uri.parse("content://com.temp.test/myTestImage.jpg");
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
Please let us know if this works. 如果有效,请告诉我们。
If this does not work you can try to manually insert a "content://com.temp.test/..." entry into media database. 如果这不起作用,您可以尝试手动将“content://com.temp.test / ...”条目插入媒体数据库。
using public readable internal memory directories
should work without a fileprovider 使用public readable internal memory directories
应该没有fileprovider
Call this function in onActivityResult. 在onActivityResult中调用此函数。 It worked for me! 它对我有用!
It is in fragment.In activity you can use "this" instead of "getActivity()". 它位于fragment.In活动中,您可以使用“this”而不是“getActivity()”。
private void galleryAddPic() {
File f = new File(imageFilePath); //set your picture's path
try {
MediaStore.Images.Media.insertImage(getActivity().getContentResolver(),
f.getAbsolutePath(), f.getName(), null);
getActivity().sendBroadcast(new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(f)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.