当前位置: 首页 > 知识库问答 >
问题:

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

长孙正卿
2023-03-14

我正在尝试使用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();
            }

<代码>列表。获取(0)。getDocFile()返回一个文档文件,我也在API 28上测试了这个,谢谢

请注意,此图像已存在于外部存储器中,只需复制即可。

编辑:我删除此代码fos=resolver.openOutputStream(ImageUri);是重复的。我真的很抱歉。文件工作正常,但盗用了错误的名称。

共有2个答案

龙默
2023-03-14

我删除此代码fos=解析器。openOutputStream(imageUri) 重复。该图像工作正常,但盗取了错误的名称。

关于错误的名称和扩展名,我认为MediaStore不适用于Android 9及更低版本,因为我在Android 11上测试了相同的代码并且运行良好

公良骁
2023-03-14

首先,让我们看看如何获取现有图像的写入权限。请注意,光路不一定存在,但应指向您希望保存文件的位置。

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

    编辑:按名称更新(在请求覆盖权限后的onActivityResult中)

    Uri fromUri = MediaUtils.getImageUriFromFS(this, new File(from));
                    ContentResolver contentResolver = getContentResolver();
                    ContentValues contentValues = new ContentValues();
    
                    contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 1);
                    contentResolver.update(fromUri, contentValues, null, null);
                    contentValues.clear();
                    contentValues.put(MediaStore.Files.FileColumns.DISPLAY_NAME, new File(to).getName());
                    contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0);
                    contentResolver.update(fromUri, contentValues, null, null);
    

  •  类似资料:
    • 我正在使用MediaStore和ContentResolver API使用MediaStore.Images保存图像文件(jpg/png/gif)。它可以工作,但问题是所有文件都以.jpg扩展名保存,并且文件名始终是“以毫秒为单位的当前时间.jpg”。 这是我在ContentValue中添加的示例: 但是在将其插入ContentResolver并写入文件后,显示名称更改为2067623.jpg,文

    • 我需要一些非常简单的东西-我的应用程序录制了一个mp4文件,我想将其插入MediaStore到用户的视频收藏中。这是我的代码,包括处理新范围存储的推荐方法: 但是,在这个函数调用名称为变成了类似的东西,所以名称和扩展名都不同(我的设备是Android 9)。已弃用。我该如何解决这个问题?

    • 我有一个有趣的是保存位图为PNG或JPG(都不工作),但似乎使用内容值不按预期工作。 文件名不正确 文件类型不正确 我错过了什么?适用于Android 10,但不适用于Android 8 实际文件名为1592205828045(一些时间戳) 实际文件类型是带有0B的jpg-因为它没有正确保存?

    • 问题内容: 这是新的Android Q 范围存储的链接。 根据此Android开发者最佳实践博客,(这是我的情况)应使用MediaStore API完成。 深入研究文档,我找不到相关功能。 这是我在科特林的审判: 结果是,按照最佳做法博客中的描述,我的图像保存在此处为 我的问题是: 如何使用MediaStore API保存图像? 用Java回答同样可以接受。 提前致谢! 编辑 感谢PerracoL

    • 问题内容: 我已经创建了一个将捕获图片并保存在sdcard文件夹中的android应用程序,现在我想使用自定义名称保存图片。 这是我用来捕获图像并将其保存在sd卡文件夹中的代码,请帮助我以特定名称保存图像,例如:android.jpeg 问题答案: 您还需要在Android清单中添加权限。 该代码段将使用名称保存内部内容

    • 问题内容: 我正在使用此代码上传文件(图像到文件夹) 当文件(图像)保存在指定路径时…如果我想用某个所需的名称保存文件…。 我曾尝试更换此 有了这个 但是它不起作用 问题答案: 你可以试试看