【问题标题】:How to get URI from filename which is saved in the external Storage using Scoped Storage in android 10 and above?如何使用 android 10 及更高版本中的 Scoped Storage 从保存在外部存储中的文件名获取 URI?
【发布时间】:2020-08-19 20:39:25
【问题描述】:

在 SDK 29 之前,这是查找 Uri 的正确方法,但现在它不再适用于大于 28 的 sdk。假设我使用以下范围存储保存 BITMAP: p>

@RequiresApi(api = Build.VERSION_CODES.Q)
@NonNull
private Uri saveBitmap(@NonNull final Context context, @NonNull final Bitmap bitmap,
                       @NonNull final Bitmap.CompressFormat format, @NonNull final String mimeType,
                       @NonNull final String displayName, @Nullable final String subFolder) throws IOException {
    String relativeLocation = Environment.DIRECTORY_PICTURES;

    if (!TextUtils.isEmpty(subFolder)) {
        relativeLocation += File.separator + subFolder;
    }

    final ContentValues contentValues = new ContentValues();
    contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, displayName);
    contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
    contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation);

    final ContentResolver resolver = context.getContentResolver();

    OutputStream stream = null;
    Uri uri = null;

    try {
        final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        uri = resolver.insert(contentUri, contentValues);

        if (uri == null) {
            throw new IOException("Failed to create new MediaStore record.");
        }

        stream = resolver.openOutputStream(uri);

        if (stream == null) {
            throw new IOException("Failed to get output stream.");
        }

        if (!bitmap.compress(format, 95, stream)) {
            throw new IOException("Failed to save bitmap.");
        }

        return uri;
    } catch (IOException e) {
        if (uri != null) {
            // Don't leave an orphan entry in the MediaStore
            resolver.delete(uri, null, null);
        }

        throw e;
    } finally {
        if (stream != null) {
            stream.close();
        }
    }
}

此代码适用于 SDK 但是,对于 SDK 29 及更高版本,如何使用保存在外部存储中的 fileName 获取 URI?

private String getFilePathUri(String enteredFileName) {

    String file_uri_string = Environment.getExternalStorageDirectory() + "/"
            + AppConstants.APP_FOLDER + "/" + enteredFileName + ".jpg";
    AppUtils.showLog(TAG, file_uri_string + "");
    return file_uri_string;

}

【问题讨论】:

  • 根据 Commonsware 在他的书中。值得注意的是,getExternalStorageDirectory() 和 getExternalStoragePublicDirectory() 等 Environment 方法已被弃用。而且,如果您尝试使用这些目录,您会发现您的应用程序缺乏访问权限,即使您持有 READ_EXTERNAL_STORAGE 和/或 WRITE_EXTERNAL_STORAGE。您可以将 android:requestLegacyExternalStorage=" true" 添加到清单中的 元素,以表明您想要“旧版”存储模型。这将帮助您访问在 Android 10 上运行的存储应用。
  • 您的第一个代码块应该适用于 Q/29。但是我们看不到您的文件夹和路径变量的值。请将它们添加到您的帖子中。
  • 如果有人可以帮助我,那就太好了:stackoverflow.com/questions/63480192/…

标签: android local-storage android-10.0 android-external-storage scoped-storage


【解决方案1】:

Android 10 及更高版本:这里 uri 会根据给定的 displayName 为您提供 file_id。

/**
 * Returns the Uri which can be used to delete/work with images in the photo gallery.
 * @param displayName Path to IMAGE on SD card
 * @return Uri in the format of... content://media/external/images/media/[NUMBER]
 */
private Uri getUriFromPath(String displayName) {
    long photoId;
    Uri photoUri = MediaStore.Images.Media.getContentUri("external");

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

    int columnIndex = cursor.getColumnIndex(projection[0]);
    photoId = cursor.getLong(columnIndex);

    cursor.close();
    return Uri.parse(photoUri.toString() + "/" + photoId);
}

【讨论】:

  • 不同目录下可以有多个同名文件。你是怎么处理的?
  • 可以使用相对路径查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 2022-12-18
  • 1970-01-01
  • 1970-01-01
  • 2018-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多