2011-10-15 43 views
2

我正在处理用户可以选择文件的应用程序,可以是来自相机的新图像,也可以是图库中的图像或普通的旧文件。然后它会显示一个图标和所选项目的名称。我有一个例外工作。画廊应用程序集成了picasaweb图片。如果用户从Picasa相册中选择了一张图片,我无法获取它的缩略图。如何获取从图库中选择的Picasa图像的缩略图?

我使用的是MediaStore.Images.Thumbnails.getThumbnail()方法,它适用于图库中的其他图像,但对于picasaweb文件,我会得到,不管什么样的缩略图I尝试获取(虽然MICRO是我后):

ERROR/MiniThumbFile(2051):GOT例外阅读魔,ID = 5634890756050069570,当磁盘已满或安装只读? class java.lang.IllegalArgumentException

我注意到给出的URI对于选定的文件是不同的。本地图像文件看起来像:

内容://媒体/外部/图像/媒体/ 6912

和Picasa网络相册的URL看起来像:

内容:// COM .android.gallery3d.provider/Picasa中/项目/ 5634890756050069570

我试图使用查询来获得在原始THUMB_DATA,使用Thumbnails.queryMiniThumbnails() ,在投影数组中有Thumbnails.THUMB_DATA,但我得到了“没有这样的列”的错误。

是否有另一种方法可以使缩略图更好地工作?当我尝试访问完整图像数据时,是否会遇到同样的问题?

+0

我可以很容易地确定URI中的差异,并显示吐司如果拍摄的图像从Picasa ,但这并不完全理想。更好但仍不完美的方法是从ACTION_PICK中排除Picasa图像,但我无法看到如何做到这一点。 – Mark

+0

我在Android bug跟踪器中为此创建了一个问题。 http://code.google.com/p/android/issues/detail?id=21234&q=picasa&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars – Mark

回答

2

我发现的是,在我的Galaxy Nexus上,Picassa的图像存储在/sdcard/Android/data/com.google.android.apps.plus/cache目录下的一个子目录中。当内容提供商是com.google.android.gallery3d.provider时,那么URL中“item”之后的数字包含图片的名称(在上例中为“5634890756050069570”)。此数据与/sdcard/Android/data/com.google.android.apps.plus/cache下扩展名为“.screen”的其中一个子目录中的文件相对应。如果您要使用DDMS从手机中复制此图像(在您的案例5634890756050069570.screen中),并使用扩展名“.jpeg”对其进行重命名,您可以打开它并在计算机上查看它。

以下onActivityResult方法将检查返回的内容提供者,然后递归搜索/sdcard/Android/data/com.google.android.apps.plus/cache目录中的文件。私有成员变量fileSearchPathResults由递归搜索方法walkDirectoryRecursivelySearchingForFile()填充。

private String fileSearchPathResult = null; 

protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    Uri selectedImage = data.getData(); 
      String[] filePathColumn = { MediaStore.Images.Media.DATA }; 
      String filePath = null; 

      // This code is required to get the image path on content providers 
      // on API > 10 where the image is from a picassa web album, since Google changed 
      // the content provider in versions with API > 10 
      if (selectedImage.toString().contains("com.google.android.gallery3d.provider")) { 
       StringBuilder contentProviderPath = new StringBuilder(selectedImage.toString()); 
       int beginningIndex = contentProviderPath.lastIndexOf("/"); 
       String fileNameWithoutExt = contentProviderPath.subSequence(beginningIndex + 1, 
         contentProviderPath.length()).toString(); 
       Log.i(TAG, fileNameWithoutExt); 
       try { 
        File path = new File("/sdcard/Android/data/com.google.android.apps.plus/cache"); 
        if (path.exists() && path.isDirectory()) { 
         fileSearchPathResult = null; 
         walkDirectoryRecursivelySearchingForFile(fileNameWithoutExt, path); 
         if (fileSearchPathResult != null) { 
          filePath = fileSearchPathResult; 
         } 
        } 
       } catch (Exception e) { 
        Log.i(TAG, "Picassa gallery content provider directory not found."); 
       } 
      } 
    } 


    public void walkDirectoryRecursivelySearchingForFile(String fileName, File dir) { 
     String pattern = fileName; 

     File listFile[] = dir.listFiles(); 
     if (listFile != null) { 
      for (int i = 0; i < listFile.length; i++) { 
       if (listFile[i].isDirectory()) { 
        walkDirectoryRecursivelySearchingForFile(fileName, listFile[i]); 
       } else { 
        if (listFile[i].getName().contains(pattern)) { 
         fileSearchPathResult = listFile[i].getPath(); 
        } 
       } 
      } 
     } 
    } 

随着文件路径,您可以创建图像的用下面的代码位图:

 Bitmap sourceImageBitmap = BitmapFactory.decodeFile(filePath); 
+0

我在Galaxy Nexus上发现Picasa文件时遇到问题,并且此解决方案适用于我。谢谢。但对谷歌字符串的引用似乎有点脆弱。它会在其他手机上工作吗?是否有更通用的解决方案,不依赖于这些特定的硬编码字符串? – gcl1

+0

这个工作,但问题是这个缓冲区可以在不同的地方。 AFAIK,Google新增了此新内容提供商,以便为您的Picasa图像提供更高的安全性。阅读URL时,您的应用会获得一次性使用异常。然后下一次,如果您再次使用该网址,则您的应用会崩溃。如果您需要更多地使用这些图像,您必须将其自己的副本放入自己的缓存区域(尽管如果您的区域是公开的话,会引发更多安全漏洞)。 – kenyee

0

ACTIVITYRESULT_CHOOSEPICTURE是您在调用startActivity(intent,requestCode)时使用的整型;

public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if(requestCode == ACTIVITYRESULT_CHOOSEPICTURE) { 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inSampleSize = 4; 
    final InputStream is = context.getContentResolver().openInputStream(intent.getData()); 
    final Bitmap bitmap = BitmapFactory.decodeStream(is, null, options); 
    is.close(); 
    } 
} 

该代码将加载整个图像。您可以将样本大小调整为合理的值以获得缩略图大小的图像。

+0

显然,核心问题是我回来了com.android .gallery3d.provider,它应该是com.google.android.gallery3d.provider。出于某种原因,这似乎在摩托罗拉xoom上被打破。 – Mark

相关问题