50

我的应用程序能够从库中选择照片。正是我想要这个选择的文件路径。

这是创建用于选择照片的意图的代码:

    Intent photoPickerIntent = new Intent(Intent.ACTION_PICK,
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    photoPickerIntent.setType("image/*");
    startActivityForResult(photoPickerIntent, INTENT_REQUEST_CODE_SELECT_PHOTO);

这是从 URI 获取文件路径的代码:

    Cursor cursor = null;
    String path = null;
    try {
        String[] projection = { MediaStore.Images.Media.DATA };
        cursor = context.getContentResolver().query(contentUri, projection, null, null, null);
        int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
        cursor.moveToFirst();
        path = cursor.getString(columnIndex);
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
    return path;

在昨天更新 Google Photos 应用程序之前,一切都运行良好。现在path解析 URI 后为空。

URI 与此类似:content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F75209/ACTUAL

我还尝试使用 Intent.ACTION_GET_CONTENT 操作创建意图 - 不走运。

4

3 回答 3

47

下面的代码也适用于我在最新的谷歌照片上获取内容 URI。我尝试的是写入临时文件并返回临时图像 URI,如果它在内容 URI 中具有权限。

你可以试试同样的:

private static String getImageUrlWithAuthority(Context context, Uri uri)
{
    InputStream is = null;

    if (uri.getAuthority() != null)
    {
        try
        {
            is = context.getContentResolver().openInputStream(uri);
            Bitmap bmp = BitmapFactory.decodeStream(is);
            return writeToTempImageAndGetPathUri(context, bmp).toString();
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                if (is != null)
                {
                    is.close();
                }
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
    return null;
}

private static Uri writeToTempImageAndGetPathUri(Context inContext, Bitmap inImage)
{
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}
于 2015-06-01T06:50:05.377 回答
6

这无疑是一种解决方法,但您可以提取由于某种原因显然已嵌入的真实内容 URI:content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F75209

我能够创建一个新的 URI authority=media and path=external/images/media/xxx,并且内容解析器返回了一个真实的 URL。

示例代码:

String unusablePath = contentUri.getPath();
int startIndex = unusablePath.indexOf("external/");
int endIndex = unusablePath.indexOf("/ACTUAL");
String embeddedPath = unusablePath.substring(startIndex, endIndex);

Uri.Builder builder = contentUri.buildUpon();
builder.path(embeddedPath);
builder.authority("media");
Uri newUri = builder.build();
于 2015-05-31T17:55:48.500 回答
1

我知道这个问题有点老了,但我还是做了以下从图库中获取图像并使用它。以下是相同的扩展功能。

fun Uri.toBitmap(context: Context?): Bitmap {
    return MediaStore.Images.Media.getBitmap(context?.contentResolver, this)
}

它以 context 作为参数来获取从 onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) 接收的 contentResolver 和 Uri。

要使用,只需执行以下操作:

intent?.data.toBitmap(context)

intent?.data从 onActivityResult() 收到的 Uri在哪里。

于 2020-02-19T05:56:29.197 回答