
[英]Wrong file extension and file name after creating image file with Android's MediaStore (ContentResolver/scoped storage)
[英]Save image using MediaStore, saved with wrong name and extension
我正在尝试使用MediaStore API
保存图像,但它始终使用此名称保存文件1637955326427.jpg并且文件的大小为0 B 。 这是我使用的代码:
OutputStream fos;
ContentResolver resolver = getBaseContext().getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, "fileName.jpg");
contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
try {
fos = resolver.openOutputStream(Objects.requireNonNull(imageUri));
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),list.get(0).getDocfile().getUri());
if(bitmap!=null){
bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
list.get(0).getDocFile()
返回一个DocumentFile
我也在API 28
上测试了这个 提前致谢
注意此图像已存在于External Storage
中,只需复制它即可。
编辑:我删除此代码fos = resolver.openOutputStream(imageUri);
是重复的。 我真的很抱歉。 该文件工作正常,但窃取了错误的名称。
首先让我们看一下获取现有图像的写入权限。 请注意,photopath 不一定存在,但应该指向您希望保存文件的位置。
if (!requestPhotoWritePermission(this, getImageUriFromFS(this, new File(photoPath)))) {
return;
} else {
takePicture();
}
这将使用默认相机形成覆盖请求
public static Uri getImageUriFromFS(Context c, File file) {
long id = getFilePathToImageID(file, c);
Uri fromUri = ContentUris.withAppendedId( MediaStore.Images.Media.EXTERNAL_CONTENT_URI,id);
return fromUri;
}
public static long getFilePathToImageID(File imagePath, Context context)
{
Uri mainUri;
Cursor cursor1 = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media._ID},
MediaStore.Images.Media.DATA + "=? ",
new String[]{imagePath.getAbsolutePath()}, null);
long id = 0;
if (cursor1 != null && cursor1.moveToFirst()) {
id = cursor1.getLong(cursor1.getColumnIndex(MediaStore.MediaColumns._ID));
cursor1.close();
}
return id;
}
public static boolean requestPhotoWritePermission(Activity activity, Uri fromUri) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
boolean hasPermission = true;
if (activity.checkUriPermission(fromUri, Binder.getCallingPid(), Binder.getCallingUid(),
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION) != PackageManager.PERMISSION_GRANTED) {
hasPermission = false;
}
List<Uri> uriList = new ArrayList<>();
uriList.add(fromUri);
if (!hasPermission) {
PendingIntent pi = MediaStore.createWriteRequest(activity.getContentResolver(), uriList);
try {
activity.startIntentSenderForResult(pi.getIntentSender(), REQUEST_OVERWRITE_PERMISSION_CODE, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
return false;
}
return true;
}
return true;
}
这将保留通过相机意图覆盖或创建新图片的权限
然后在您的活动中:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 53) {
if (resultCode == RESULT_OK) {
//you'll want to take your picture here and possibly store the uri to your photo for later retrieval
takePicture();
}
}
如果许可请求被接受,这将拍照
使用提供者的默认意图拍照:
在清单中声明您的提供者
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.provider" android:enabled="true" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"> </meta-data> </provider>
1.5:xml 文件路径文件:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path
name="internal_images"
path="files/Pictures" />
<external-files-path
name="internal_images_alternate"
path="Pictures" />
<external-path
name="external"
path="Documents" />
<external-files-path
name="external_files"
path="Documents" />
<cache-path
name="cache"
path="Documents" />
<external-cache-path
name="external_cache"
path="Documents" />
<files-path
name="files"
path="Documents" />
</paths>
以上将授予您保存到文档文件夹的权限。 根据需要更换。
利用提供者拍照
public static File dispatchTakePictureIntent(Activity activity, String photoPath) { Intent takePictureIntent = getCameraIntentWithUpdatedPackages(activity); Uri photoURI = Uri.fromFile(new File(photoPath)); Uri photoUri = FileProvider.getUriForFile(activity.getApplicationContext(), activity.getApplicationContext().getPackageName() + ".provider", new File(photoPath)); activity.grantUriPermission(photoURI.getAuthority(), photoUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); //disable strict mode policies StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); activity.startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO); return new File(photoPath); return null;
}
编辑:我忘记了一些东西
public static Intent getCameraIntentWithUpdatedPackages(Context context) {
List<ResolveInfo> resolveInfo = new ArrayList<>();
final Intent capturePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
PackageManager pm = context.getPackageManager();
resolveInfo = pm.queryIntentActivities(capturePhoto, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// For Android 11 we need to add specific camera apps
// due them are not added during ACTION_IMAGE_CAPTURE scanning...
// resolveInfo.addAll(getCameraSpecificAppsInfo(context));
}
capturePhoto.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
return capturePhoto;
}
我删除了这段代码fos = resolver.openOutputStream(imageUri);
是重复的。 图像工作正常,但窃取了错误的名称。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.