从Gallery中检索非缓存的Picasa图像.3.0和4.0

you*_*chy 10 android picasa gallery android-3.0-honeycomb android-4.0-ice-cream-sandwich

我的应用程序调用库的意图如下:

Intent intent = new Intent(Intent.ACTION_PICK,
        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, SELECT_IMAGE_FROM_GALLERY);
Run Code Online (Sandbox Code Playgroud)

在<3.0版本中没有问题.

对于3.0及更高版本,当您获得本地图像时,onActivityResult方法中的意图包含类似于Uri的...

content://media/external/images/media/XXX
Run Code Online (Sandbox Code Playgroud)

但是当你选择一个picasa图像时,uri就像......

content://com.google.android.gallery3d.provider/picasa/item/XXXXXXXXXXXXXXXXXXXXX
Run Code Online (Sandbox Code Playgroud)

我读了很多关于这个问题的文章,我尝试了很多解决方法.

目前,我可以使用以下方法获取缓存的图像:

getContentprovider().openInputStream(uri)
Run Code Online (Sandbox Code Playgroud)

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

任何人都知道如何获取文件或网址下载文件或东西来获取图像?

谢谢!!

Jua*_*ana 7

正确的解决方案是使用ACTION_GET_CONTENT.它的名字可能听起来不像ACTION_PICK那么直观,但它应该用于你想要做的事情.

背后采用的原因ACTION_GET_CONTENT在您的画廊选择一个图像,而不是使用ACTION_PICK并指向ImageStore的URI提供者是ACTION_GET_CONTENT很好的支持,而ACTION_PICK不是.Android Framework工程师已经多次提到它.

我很难学到它.在发现这一点之前,我不得不处理各种不一致问题.


与此相关的说明

你应该总是使用openInputStream通过获取该文件ContentResolverURI接受,而不是试图获得在其中存储的文件真实路径.它很可能是该案件ContentProvider的实现是由云服务支持(这是与Picasa的情况下)或实施细则随时间而改变.

Android的内容提供商允许您抽象数据的访问方式.试图找出文件所在的位置是我看到的常见错误.通常建议的是通过查询DATA给定列来找到位置URI.根据ContentProvider使用情况,它可能返回不同的东西,甚至随着时间的推移随新版本而变化.

通过使用openInputStream您不必关心文件的位置,您只需接收字节流并按照您的意愿执行操作.这样,您就不会遇到支持来自Google Drive,Dropbox等其他应用程序的内容提供商的问题,这些应用程序提供类似的选择器界面来选择图像.

我知道OP正在使用openInputStream,但其他答案建议不然,这是我经常看到的.


Rob*_*ree 2

获取图片比特流的另一种方法是通过 picasa api....

将一些映射应用到内容提供者 uri ...

内容://com.google.android.gallery3d.provider/picasa/item/5703943700733980450

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

项目=>照片名字?? 蛋白??

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

以上是照片输入的 api 请求 - 有关详细信息,请参阅 picasa 文档。

API要求

姓名 专辑ID 照片ID

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

“媒体$组”:{“媒体$内容”:[{“网址”:

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

php picasa api 显示大图像

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

在示例中使用我自己的内容 URI 之一...

内容://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

并检查响应的文本值

“媒体$组”:{“媒体$内容”:[{“网址”:

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

我使用上面的值发出照片图像请求,并且我得到了图像。


Gallery 3D 应用程序还具有您可以派生的代码,因为无论它在缩略图列表之一上检测到“触摸”,它都会委托给 contentProvider 接口来“获取”BMP。我相信这个接口封装了上面提到的所有血淋淋的实现细节。通过要求 ContentProvider 生成 BMP,开发人员不必担心实现的风格?在拇指触摸上,Gallery3d 可能只要求提供者返回 BMP 及其负责解析缓存的各种状态以及是否需要网络调用来返回 BMP 的提供者实例。