2017-04-19 80 views
3

我有一個應用程序允許選擇與外部應用程序的照片。然後,我從uri中獲取照片的路徑,並將其用於內部操作。從谷歌照片應用程序從Uri獲取路徑

當用戶使用Google照片選擇一張照片時,如果圖片在本地存儲,那麼下一個代碼完美工作。但如果圖片在雲中,則的結果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); 
} 

謝謝!

+0

看起來像這樣重複? http://stackoverflow.com/questions/30527045/choosing-photo-using-new-google-photos-app-is-broken –

+0

@ user2765258我看到那篇文章。但不是一個好的解決方案。即使用戶說接受它是因爲解決了問題,但並不是他實施的完整解決方案。謝謝您 – adalPaRi

回答

3

最後,根據@CommonsWare的回答和關於這個問題的上一篇文章,我解決了從uri獲取InputStream,應對一個新的臨時文件並將路徑傳遞給我需要使用的函數。

這裏是simplificated代碼:

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

當用戶使用Google照片選擇一張照片時,如果圖片在本地存儲,那麼下一個代碼完美工作。

不一定。沒有要求Uri_data列迴應query()。不要求它返回的值對您有用(例如,您無法訪問的內部存儲或可移動存儲上的文件)。

如果您需要將照片加載到ImageView,請將Uri轉換爲an image-loading library,如畢加索。

如果您需要照片的字節,請使用openInputStream()ContentResolver獲取由Uri標識的內容的InputStream。請在後臺線程上打開並從InputStream中讀取。

+0

謝謝,但事實是,由於內部要求,我需要真正的路徑。我不會顯示或操縱圖像,只需將路徑傳遞給已實施的後端服務即可。 – adalPaRi

+2

@adalPaRi:沒有「真正的路徑」。如果您需要一個文件,歡迎您使用'openInputStream()'中的'InputStream'和一個'FileOutputStream'來創建一個文件,並將它複製到您控制的某個文件中。 – CommonsWare