繁体   English   中英

使用 MediaStore 保存图像,以错误的名称和扩展名保存

[英]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();
        }
 }

如果许可请求被接受,这将拍照

使用提供者的默认意图拍照:

  1. 在清单中声明您的提供者

     <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>

以上将授予您保存到文档文件夹的权限。 根据需要更换。

  1. 利用提供者拍照

    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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM