如何在Android Q中获取图像Uri?

4

我想在Android Q中获取文件位置的Uri。 我正在使用以下代码,但是Android Studio指出它已过时。如何以正确的方式获取文件的Uri?

val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES + "/meter"), "lalaland.jpg")

val uri = Uri.fromFile(file)

1
您无法访问该文件位置。请让用户将文件放置在您可以通过文件系统访问的位置(例如getExternalFilesDir()),或使用MediaStore,或使用ACTION_OPEN_DOCUMENT - CommonsWare
谢谢,有关于MediaStore的教程吗?我找不到如何使用它的文档。@CommonsWare - VINNUSAURUS
1
我不知道您将如何使用Uri,或者您尝试做什么的范围是什么。这本书中的这个Kotlin示例应用程序展示了如何通过文件名获取视频的Uri值。通常,您可以在ContentResolver上使用query()来查询所需类型的媒体。 - CommonsWare
使用这个需要 Uri 的裁剪库 https://github.com/Yalantis/uCrop,将会检查那个例子。 - VINNUSAURUS
好的,那么你需要集中精力考虑如何让用户选择要裁剪的图像。你问题中的代码假定在特定目录中有一个特定的文件名。更好的解决方案是使用ACTION_OPEN_DOCUMENT,允许用户从设备上的任何地方(或从云存储提供商,如Google Drive)选择图像。您将获得一个 Uri ,应该可以与 uCrop 一起使用。 - CommonsWare
Uri仅用于保存图像,我使用另一个库获取图像,它只是像您所说的那样操作,但我没有保存图像的方法。 - VINNUSAURUS
3个回答

0

如何在Android Q中访问共享存储中的媒体文件 为了提供更丰富的用户体验,许多应用程序允许用户贡献和访问外部存储卷上可用的媒体。框架提供了一个优化的媒体集合索引,称为媒体存储库,可以更轻松地检索和更新这些媒体文件。Android scoped storage将项添加到Android scoped storage集合

public static Uri getImageContentUri(Context context, File imageFile) {
    String filePath = imageFile.getAbsolutePath();
    Cursor cursor = context.getContentResolver().query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            new String[]{MediaStore.Images.Media._ID},
            MediaStore.Images.Media.DATA + "=? ",
            new String[]{filePath}, null);
    if (cursor != null && cursor.moveToFirst()) {
        int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
        cursor.close();
        return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + id);
    } else {
        if (imageFile.exists()) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                ContentResolver resolver = context.getContentResolver();
                Uri picCollection = MediaStore.Images.Media
                        .getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
                ContentValues picDetail = new ContentValues();
                picDetail.put(MediaStore.Images.Media.DISPLAY_NAME, imageFile.getName());
                picDetail.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg");
                picDetail.put(MediaStore.Images.Media.RELATIVE_PATH,"DCIM/" + UUID.randomUUID().toString());
                picDetail.put(MediaStore.Images.Media.IS_PENDING,1);
                Uri finaluri = resolver.insert(picCollection, picDetail);
                picDetail.clear();
                picDetail.put(MediaStore.Images.Media.IS_PENDING, 0);
                resolver.update(picCollection, picDetail, null, null);
                return finaluri;
            }else {
                ContentValues values = new ContentValues();
                values.put(MediaStore.Images.Media.DATA, filePath);
                return context.getContentResolver().insert(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            }

        } else {
            return null;
        }
    }
}

0

此函数将根据给定的文件名返回Uri。您可以将其更新为像MediaStore.Images...这样的图像。

public static Uri getUriFromDisplayName(Context context, String displayName) {

    String[] projection;
    projection = new String[]{MediaStore.Files.FileColumns._ID};

    // TODO This will break if we have no matching item in the MediaStore.
    Cursor cursor = context.getContentResolver().query(extUri, projection,
            MediaStore.Files.FileColumns.DISPLAY_NAME + " LIKE ?", new String[]{displayName}, null);
    assert cursor != null;
    cursor.moveToFirst();

    if (cursor.getCount() > 0) {
        int columnIndex = cursor.getColumnIndex(projection[0]);
        long fileId = cursor.getLong(columnIndex);

        cursor.close();
        return Uri.parse(extUri.toString() + "/" + fileId);
    } else {
        return null;
    }

}

0

Environment#getExternalStoragePublicDirectory(String)方法已经被弃用,以提高用户隐私。如果您有一个对Context的引用(比如说,ctx),您可以执行以下操作:

val file = File(ctx.getExternalFilesDir(Environment.DIRECTORY_PICTURES),
                "meter/lalaland.jpg")

val uri = Uri.fromFile(file)

请参阅文档,了解getExternalFilesDir()的工作原理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接