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

Uri selectedImage = data.getData();

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

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

或路径给出:

/external/images/media/47

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


当前回答

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

(Kotlin代码)

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

其他回答

尝试从Uri获取图像文件路径

public void getImageFilePath(Context context, Uri uri) {

    Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
    cursor.moveToFirst();
    String image_id = cursor.getString(0);
    image_id = image_id.substring(image_id.lastIndexOf(":") + 1);
    cursor.close();
    cursor = context.getContentResolver().query(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", new String[]{image_id}, null);
    cursor.moveToFirst();
    String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
    cursor.close();
    upLoadImageOrLogo(path);
}

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

这是我的例子获取文件名,从URI file://…内容://... .这是为我工作,不仅与Android MediaStore,而且与第三方应用程序,如EzExplorer。

public static String getFileNameByUri(Context context, Uri uri)
{
    String fileName="unknown";//default fileName
    Uri filePathUri = uri;
    if (uri.getScheme().toString().compareTo("content")==0)
    {      
        Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
        if (cursor.moveToFirst())
        {
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);//Instead of "MediaStore.Images.Media.DATA" can be used "_data"
            filePathUri = Uri.parse(cursor.getString(column_index));
            fileName = filePathUri.getLastPathSegment().toString();
        }
    }
    else if (uri.getScheme().compareTo("file")==0)
    {
        fileName = filePathUri.getLastPathSegment().toString();
    }
    else
    {
        fileName = fileName+"_"+filePathUri.getLastPathSegment();
    }
    return fileName;
}

这些答案在所有情况下都不适用。我必须直接去谷歌的文档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;
}

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

如果你的系统版本在19以上,这对我来说是完美的,希望这能帮助你。

  @TargetApi(Build.VERSION_CODES.KITKAT)
    public static String getPath(final Context context, final Uri uri) {
        final boolean isOverKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        // DocumentProvider
        if (isOverKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/"
                            + split[1];
                }
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {
                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"),
                        Long.valueOf(id));
                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }
                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{split[1]};
                return getDataColumn(context, contentUri, selection,
                        selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }
        return null;
    }