2011-10-15 44 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

相關問題