【问题标题】:Choosing photo using new Google Photos app is broken使用新的 Google 相册应用选择照片已损坏
【发布时间】:2015-08-12 04:05:37
【问题描述】:

我的应用可以从库中选择照片。正是我想要这个选择的文件路径。

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

    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 相册应用之前,一切正常。 现在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 操作创建意图 - 不走运。

【问题讨论】:

    标签: android android-intent android-gallery google-photos


    【解决方案1】:

    下面的代码也可以让我在最新的 Google 照片上获取内容 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);
    }
    

    【讨论】:

    • 我已经接受了这个答案,尽管对于我们的流程来说这是一种解决方法。但它允许让应用程序恢复到完全工作状态,所以这很重要。注意:我没有从 InputStream 进行位图解码 - 我已将其复制到 File tempFile = new File("path_to_my_temp_directory");,然后将最后一个用于所有内容。
    • @Akhil 谢谢!
    • is = context.getContentResolver().openInputStream(uri); 返回空值。我似乎找不到从谷歌照片应用程序中挑选图像的任何解决方案。如果有人有可行的解决方案,请分享。
    • 我在其他问题中做了一个类似于这个 bt 使用输入和输出流而不是位图的答案:stackoverflow.com/questions/43500164/…
    • 但是如何从谷歌照片中下载视频文件呢?
    【解决方案2】:

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

    我能够使用authority=media and path=external/images/media/xxx 创建一个新的 URI,并且内容解析器返回了一个真实的 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();
    

    【讨论】:

    • 您能分享一下这个解决方案的来源吗?卡在这个问题上几天了!
    • @JonRogstad 你的例子就像一个魅力!但这是目前的解决方法。我认为应该有一种处理自定义/应用程序特定 URI 的本地方式
    • 这在三星 Galaxy S5、Android 5.0 上崩溃
    • 只是一个警告:这不适用于所有设备和所有照片......即我的 URI 看起来像这样......content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F31769/ORIGINAL/NONE/########### 表示一个数字(0-9 )
    【解决方案3】:

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

    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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多