我有一个onActivityResult从一个mediastore图像选择返回,我可以获得一个图像使用以下URI:

Uri selectedImage = data.getData();

将this转换为字符串会得到:

content://media/external/images/media/47

或路径给出:

/external/images/media/47

然而,我似乎找不到一种方法将其转换为绝对路径,因为我想将图像加载到位图中,而不必复制到某个地方。我知道这可以使用URI和内容解析器来完成,但这似乎在重新启动手机时中断,我猜MediaStore在重新启动之间没有保持其编号相同。


当前回答

这些答案在所有情况下都不适用。我必须直接去谷歌的文档https://developer.android.com/guide/topics/providers/document-provider.html关于这个主题,并发现这个有用的方法:

private Bitmap getBitmapFromUri(Uri uri) throws IOException {
    ParcelFileDescriptor parcelFileDescriptor =
    getContentResolver().openFileDescriptor(uri, "r");
    FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
    Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
    parcelFileDescriptor.close();
    return image;
}

您可以使用此位图在图像视图中显示它。

其他回答

作为一个附加组件,如果在尝试打开输入流之前需要查看文件是否存在,可以使用DocumentsContract。

(Kotlin代码)

var iStream = null
if(DocumentsContract.isDocumentUri(context,myUri)) {
   val pfd: ParcelFileDescriptor? = context.contentResolver.openFileDescriptor(
            myUri, "r") ?: return null
   iStream = ParcelFileDescriptor.AutoCloseInputStream(pfd)
}

Bitmap Bitmap = MediaStore.Images.Media.getBitmap, uri;

这些答案在所有情况下都不适用。我必须直接去谷歌的文档https://developer.android.com/guide/topics/providers/document-provider.html关于这个主题,并发现这个有用的方法:

private Bitmap getBitmapFromUri(Uri uri) throws IOException {
    ParcelFileDescriptor parcelFileDescriptor =
    getContentResolver().openFileDescriptor(uri, "r");
    FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
    Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
    parcelFileDescriptor.close();
    return image;
}

您可以使用此位图在图像视图中显示它。

只是对第一个答案进行了简单的更新:mActivity.managedQuery()现在已弃用。我已经用新方法更新了代码。

private String getRealPathFromURI(Uri contentUri) {
    String[] proj = { MediaStore.Images.Media.DATA };
    CursorLoader loader = new CursorLoader(mContext, contentUri, proj, null, null, null);
    Cursor cursor = loader.loadInBackground();
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    String result = cursor.getString(column_index);
    cursor.close();
    return result;
}

Android开发源码

下面API 19使用这段代码从URI中获取文件路径:

public String getRealPathFromURI(Context context, Uri contentUri) {
  Cursor cursor = null;
  try { 
    String[] proj = { MediaStore.Images.Media.DATA };
    cursor = context.getContentResolver().query(contentUri,  proj, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
  } finally {
    if (cursor != null) {
      cursor.close();
    }
  }
}