【问题标题】:Getting path from Uri from Google Photos app从 Google Photos 应用程序从 Uri 获取路径
【发布时间】:2017-04-19 15:33:52
【问题描述】:

我有一个允许使用外部应用程序选择照片的应用程序。然后我从 uri 中获取照片的路径并将其用于内部操作。

当用户使用 Google Photo 选择照片时,如果该照片是本地存储的,则下一个代码可以完美运行。但如果图片在云端,cursor.getString(index) 的结果为空。

我已经搜索了一些信息,但不确定解决方案

final String[] projection = { "_data" };
Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);

if (cursor != null && cursor.moveToFirst()) {
    final int index = cursor.getColumnIndexOrThrow("_data");
    return cursor.getString(index);
}

谢谢!

【问题讨论】:

  • 看起来像这个的副本? stackoverflow.com/questions/30527045/…
  • @user2765258 我看到了那个帖子。但不是一个好的解决方案。甚至用户说接受它是因为解决了问题但不是他实施的完整解决方案。还是谢谢你

标签: android uri


【解决方案1】:

最后,根据@CommonsWare 的回答和关于这个问题的上一篇文章,我解决了从 uri 获取 InputStream、处理到一个新的临时文件并将路径传递给我需要使用的函数的问题。

这里是简化的代码:

public String getImagePathFromInputStreamUri(Uri uri) {
    InputStream inputStream = null;
    String filePath = null;

    if (uri.getAuthority() != null) {
        try {
            inputStream = getContentResolver().openInputStream(uri); // context needed
            File photoFile = createTemporalFileFrom(inputStream);

            filePath = photoFile.getPath();

        } catch (FileNotFoundException e) {
            // log
        } catch (IOException e) {
            // log
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    return filePath;
}

private File createTemporalFileFrom(InputStream inputStream) throws IOException {
    File targetFile = null;

    if (inputStream != null) {
        int read;
        byte[] buffer = new byte[8 * 1024];

        targetFile = createTemporalFile();
        OutputStream outputStream = new FileOutputStream(targetFile);

        while ((read = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, read);
        }
        outputStream.flush();

        try {
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    return targetFile;
}

private File createTemporalFile() {
    return new File(getExternalCacheDir(), "tempFile.jpg"); // context needed
}

【讨论】:

  • 太棒了,这帮助我摆脱了 1 P0 :D
【解决方案2】:

当用户使用 Google Photo 选择一张照片时,如果该图片是本地存储的,那么下一个代码可以完美运行。

不一定。不需要Uri_data 列响应query()。它返回的值不需要对您有用(例如,您无法访问的内部存储或可移动存储上的文件)。

如果您需要将照片加载到ImageView,请将Uri 传递给an image-loading library,例如毕加索。

如果您需要照片的字节,请使用openInputStream()ContentResolver 以获取InputStream 上由Uri 标识的内容。请在后台线程上打开并阅读InputStream

【讨论】:

  • 谢谢,但问题是由于内部要求,我需要真实路径。我不会显示或操作图像,只是将路径传递给已经实现的后端服务。
  • @adalPaRi:没有“真正的路径”。如果您需要文件,欢迎您使用openInputStream() 中的InputStreamFileOutputStream 复制照片到您控制的某个文件。
  • @CommonsWare,我在这里遇到了 Google 照片的问题。我正在使用 Picasso 将 URI 加载到图像中,并在我的活动之间传递 URI,但经过一番搜索后我发现,一旦我离开 onActivityResult,我从图库/相机@987654337 检索意图,URI 似乎就会变得无效@ 意图选择器。你有什么建议?有推荐的链接吗?
  • @rgoncalv:在组件之间传递Uri 时,您需要使用FLAG_GRANT_READ_URI_PERMISSION,包括您自己的组件。请参阅this blog post 了解更多信息。
  • 我试过这个(阅读你的博客文章):当从活动A回到活动B时,我在setResult(Activity.RESULT_OK, savedPicIntent)之前添加picIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION),在活动A内部的一个方法中。我可以访问图片在活动 B 中完美(我在活动 B 的一个小框架中看到图片,并且可以转到另一个活动 C 以全屏查看图片,一切都符合预期),但是当将图片发送到服务器(使用 Firebase)时,在Activity B,崩溃发生在这一行:`.putFile(chosenImageUri!!, metadata)`
猜你喜欢
  • 2018-07-05
  • 2011-12-31
  • 1970-01-01
  • 2018-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 1970-01-01
相关资源
最近更新 更多