从Gallery检索未缓存的Picasa图像。3.0和4.0版本。

10

我的应用程序使用如下意图调用相册:

Intent intent = new Intent(Intent.ACTION_PICK,
        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, SELECT_IMAGE_FROM_GALLERY);

在版本 < 3.0 中没有问题。

在3.0及更高版本中,当您获取本地图像时,onActivityResult 方法中的 intent 包含一个类似于...的 Uri。

content://media/external/images/media/XXX

但是当你选择一个Picasa图片时,它的URI看起来像...

content://com.google.android.gallery3d.provider/picasa/item/XXXXXXXXXXXXXXXXXXXXX

我阅读了很多与这个问题相关的内容,并尝试了许多解决方法。

目前,我只能使用以下方式获取缓存图像:

getContentprovider().openInputStream(uri)

问题是,当图片没有被缓存时,openInputStream(uri) 方��会抛出 FileNotFoundException,我无法获取图片 :_(

有人知道如何获取文件或下载文件的 URL 或其他方法来获取图片吗?

谢谢!!


最终使用了经典解决方案...通过使用Document.util,该工具覆盖了所有权限 :-) https://dev59.com/cmgt5IYBdhLWcg3w3xEw#30453641 - Adarsh Yadav
2个回答

7
正确的解决方案是使用ACTION_GET_CONTENT。它的名字可能不像ACTION_PICK那样直观,但对于你想要做的事情,这才是应该使用的。
在从相册中选择图像时使用ACTION_GET_CONTENT而不是使用ACTION_PICK并指向ImageStore的URI提供程序的原因是,ACTION_GET_CONTENT得到了很好的支持,而ACTION_PICK则没有。这已经由Android Framework工程师提到了几次。
我是通过艰难的方式学会的。在找到这个方法之前,我必须处理各种不一致性。

关于此事的说明

您应该始终使用openInputStream通过ContentResolver获取文件,而不是尝试获取文件实际存储的真实路径。可能情况是ContentProvider实现由云服务支持(这是Picasa的情况)或实现细节随时间变化。

Android的内容提供程序使您抽象了数据访问方式。试图找出文件所在位置是我看到的常见错误。通常建议的方法是通过查询给定URIDATA列来查找位置。根据使用的ContentProvider,它可能返回不同的内容,甚至会随着新版本而改变。

通过使用openInputStream,您无需关心文件在哪里,只需接收字节流并对其进行操作。这样,您就不会遇到支持其他应用程序的内容提供程序(如Google Drive、Dropbox等)提供类似选择器界面以选择图像的问题。

我知道 OP 正在使用 openInputStream,但其他答案却建议使用其他方法,而且我经常看到这种情况。


2

通过picasa api,还有另一种获取图片位流的方式...

对内容提供程序uri应用一些映射...

content://com.google.android.gallery3d.provider/picasa/item/5703943700733980450

可以将其映射到如下所示的picasa api:

item=>photoid name?? albumid??

picasaweb.google.com/data/entry/api/user/$NAME/albumid/nnnn/photoid/nnnn

以上是照片条目的api请求——有关详细信息,请参阅picasa文档。

API需要

Name albumID photoID

我认为您可以从手机上的帐户中获取名称。 AlbumID很棘手,因为内容提供程序中的/item/节点值不是GUID,无法使用关系推断出它所在的相册。我认为在picasa中,您需要用户、相册、照片元组才能引用照片条目,并且照片条目具有API元素中大型照片的URL:

"media$group":{ "media$content":[ {"url":

您可以获取url属性的文本值,并使用http(s)请求它,如果相册的可见性是公共的,则响应是JPG的二进制流。

php picasa api show large image

请参阅上面链接中的已接受答案,以获取有关从picasa api获取所需图像的更多详细信息。

以我的一个内容URI为例...

content://com.google.android.gallery3d.provider/picasa/item/5703943700733980450

不在缓存中,那么如何获取图片呢?

好吧,帐户名称是'rowntreerob', 我知道photoid 5703943700733980450属于albumid 5703943611411433905。

因此,我对该条目进行api请求。

https://picasaweb.google.com//data/entry/api/user/rowntreerob/albumid/5682316071017984417/photoid/5682316083381958690?fields=media%3Agroup%2Fmedia%3Athumbnail%5B%40url%5D%2Cmedia%3Agroup%2Fmedia%3Acontent%5B%40url%5D&alt=json

请检查响应中

"media$group":{ "media$content":[ {"url":

的文本值。

value=https://lh3.googleusercontent.com/-_FFMNGPU1TQ/TtukXyN4eCI/AAAAAAAACso/EzPmut2iKVQ/DSC01612.JPG

我使用上述值进行照片图像请求,并且我有了这张图片。


Gallery 3D应用程序还具有您可以分叉的代码,因为无论在缩略图列表中检测到哪个'触摸',它都将委托给contentProvider接口来'获取'BMP。 我相信这个接口封装了上面提到的所有恶心的实现细节。通过请求ContentProvider生成BMP,开发人员不必担心实现的种类?在thumbtouch上,Gallery3d可能会要求提供程序返回BMP,而负责解决缓存的各种状态和是否需要网络调用以返回BMP的是提供程序实例。


是啊...因为这应该是我们作为开发人员的工作,去做所有这些事情,哈哈。我觉得不是这样的。这是谷歌的问题,而不是开发人员的问题。 - ChuckKelly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接