2013-11-28 42 views
21

由於我支持我的應用程序到Kitkat版本,現在在這裏從圖庫檢索文件的方式是不同的。從圖庫kitkat中選擇圖像時檢索絕對路徑android

我寧願這個Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT,用於從庫文件,併成功地工作,但我需要的是文件的絕對路徑,我越來越

content://com.android.providers.media.documents/document/image:2505 

爲19以下的版本,我們使用URI不同的使用,我得到這樣的路徑

Cursor cursor = this.getContentResolver().query(originalUri, projection, null, null, null); 
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
cursor.moveToFirst(); 
String fpath = cursor.getString(column_index); 

但在19版本它會給我null值如何獲得用戶選擇的圖像文件的絕對路徑。

謝謝

回答

27

這是選擇文件後訪問絕對路徑的一種方法。

在新的URI格式獲取數據KK(奇巧)這樣的方式後

content://com.android.providers.media.documents/document/image:2505 

只需提取文檔

if(requestCode == GALLERY_KITKAT_INTENT_CALLED && resultCode == RESULT_OK){ 

    Uri originalUri = data.getData(); 

    final int takeFlags = data.getFlags() 
         & (Intent.FLAG_GRANT_READ_URI_PERMISSION 
         | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 
    // Check for the freshest data. 
    getContentResolver().takePersistableUriPermission(originalUri, takeFlags); 

    /* now extract ID from Uri path using getLastPathSegment() and then split with ":" 
    then call get Uri to for Internal storage or External storage for media I have used getUri() 
    */ 

    String id = originalUri.getLastPathSegment().split(":")[1]; 
    final String[] imageColumns = {MediaStore.Images.Media.DATA }; 
    final String imageOrderBy = null; 

    Uri uri = getUri(); 
    String selectedImagePath = "path"; 

    Cursor imageCursor = managedQuery(uri, imageColumns, 
      MediaStore.Images.Media._ID + "="+id, null, imageOrderBy); 

    if (imageCursor.moveToFirst()) { 
     selectedImagePath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA)); 
    } 
    Log.e("path",selectedImagePath); // use selectedImagePath 
}else if() { 
     // for older version use existing code here 
} 

// By using this method get the Uri of Internal/External Storage for Media 
private Uri getUri() { 
    String state = Environment.getExternalStorageState(); 
    if(!state.equalsIgnoreCase(Environment.MEDIA_MOUNTED)) 
     return MediaStore.Images.Media.INTERNAL_CONTENT_URI; 

    return MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 
} 
+0

我試圖執行此操作,但我收到 01-09 12:09:49.333:E/AndroidRuntime(21760):java.lang.RuntimeException:傳遞結果失敗ResultInfo {who = null,request = 1,result = 1,data = Intent {dat = content:flg = 0x1}} to activity {com.example.loadimage/com.example.loadimage.MainActivity}:java.lang.SecurityException:未找到針對UID 10259和Uri的權限授予內容: –

+0

似乎在這行異常發生takePersistableUriPermission 我必須添加清單中的任何種類的權限 –

+1

它的拋出'引起:java.lang.SecurityException:請求標誌0x1,但只允許0x0' – RobinHood

4

的ID PRATIK的解決方案幫助了我很多。以下是適用於Kitkat 4.4.2的版本。我改變的三件事是
1)使用內容解析器獲取路徑
2)originalUri.getLastPathSegment()。split(「:」)[1]給我索引越界,所以我使用索引0 。它一直在工作到目前爲止
3)刪除了標記並檢查最新的數據,因爲我們正在使用id過濾光標。

try { 
     Uri originalUri = data.getData(); 
     String pathsegment[] = originalUri.getLastPathSegment().split(":"); 
     String id = pathsegment[0]; 
     final String[] imageColumns = { MediaStore.Images.Media.DATA }; 
     final String imageOrderBy = null; 

     Uri uri = getUri(); 
     Cursor imageCursor = activity.getContentResolver().query(uri, imageColumns, 
           MediaStore.Images.Media._ID + "=" + id, null, null); 

     if (imageCursor.moveToFirst()) { 
      value = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA)); 
     } 

    } catch (Exception e) { 
     Toast.makeText(activity, "Failed to get image", Toast.LENGTH_LONG).show(); 
    } 
2
Bitmap bitmap = MediaStore.Images.Media 
.getBitmap(getActivity().getContentResolver(), uri); 

我希望這會幫助你。

-1

工作完美的解決方案:

package utils; 

/** 
* Created by layer on 4/21/2015. 
*/ 
import android.annotation.TargetApi; 
import android.content.ContentUris; 
import android.content.Context; 
import android.database.Cursor; 
import android.net.Uri; 
import android.os.Build; 
import android.os.Environment; 
import android.provider.DocumentsContract; 
import android.provider.MediaStore; 

public class ImageFilePath { 

    /** 
    * Method for return file path of Gallery image 
    * 
    * @param context 
    * @param uri 
    * @return path of the selected image file from gallery 
    */ 
    @TargetApi(Build.VERSION_CODES.KITKAT) 
    public static String getPath(final Context context, final Uri uri) { 

     // check here to KITKAT or new version 
     final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; 

     // DocumentProvider 
     if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { 

      // ExternalStorageProvider 
      if (isExternalStorageDocument(uri)) { 
       final String docId = DocumentsContract.getDocumentId(uri); 
       final String[] split = docId.split(":"); 
       final String type = split[0]; 

       if ("primary".equalsIgnoreCase(type)) { 
        return Environment.getExternalStorageDirectory() + "/" 
          + split[1]; 
       } 
      } 
      // DownloadsProvider 
      else if (isDownloadsDocument(uri)) { 

       final String id = DocumentsContract.getDocumentId(uri); 
       final Uri contentUri = ContentUris.withAppendedId(
         Uri.parse("content://downloads/public_downloads"), 
         Long.valueOf(id)); 

       return getDataColumn(context, contentUri, null, null); 
      } 
      // MediaProvider 
      else if (isMediaDocument(uri)) { 
       final String docId = DocumentsContract.getDocumentId(uri); 
       final String[] split = docId.split(":"); 
       final String type = split[0]; 

       Uri contentUri = null; 
       if ("image".equals(type)) { 
        contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 
       } else if ("video".equals(type)) { 
        contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; 
       } else if ("audio".equals(type)) { 
        contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
       } 

       final String selection = "_id=?"; 
       final String[] selectionArgs = new String[] { split[1] }; 

       return getDataColumn(context, contentUri, selection, 
         selectionArgs); 
      } 
     } 
     // MediaStore (and general) 
     else if ("content".equalsIgnoreCase(uri.getScheme())) { 

      // Return the remote address 
      if (isGooglePhotosUri(uri)) 
       return uri.getLastPathSegment(); 

      return getDataColumn(context, uri, null, null); 
     } 
     // File 
     else if ("file".equalsIgnoreCase(uri.getScheme())) { 
      return uri.getPath(); 
     } 

     return null; 
    } 

    /** 
    * Get the value of the data column for this Uri. This is useful for 
    * MediaStore Uris, and other file-based ContentProviders. 
    * 
    * @param context 
    *   The context. 
    * @param uri 
    *   The Uri to query. 
    * @param selection 
    *   (Optional) Filter used in the query. 
    * @param selectionArgs 
    *   (Optional) Selection arguments used in the query. 
    * @return The value of the _data column, which is typically a file path. 
    */ 
    public static String getDataColumn(Context context, Uri uri, 
             String selection, String[] selectionArgs) { 

     Cursor cursor = null; 
     final String column = "_data"; 
     final String[] projection = { column }; 

     try { 
      cursor = context.getContentResolver().query(uri, projection, 
        selection, selectionArgs, null); 
      if (cursor != null && cursor.moveToFirst()) { 
       final int index = cursor.getColumnIndexOrThrow(column); 
       return cursor.getString(index); 
      } 
     } finally { 
      if (cursor != null) 
       cursor.close(); 
     } 
     return null; 
    } 

    /** 
    * @param uri 
    *   The Uri to check. 
    * @return Whether the Uri authority is ExternalStorageProvider. 
    */ 
    public static boolean isExternalStorageDocument(Uri uri) { 
     return "com.android.externalstorage.documents".equals(uri 
       .getAuthority()); 
    } 

    /** 
    * @param uri 
    *   The Uri to check. 
    * @return Whether the Uri authority is DownloadsProvider. 
    */ 
    public static boolean isDownloadsDocument(Uri uri) { 
     return "com.android.providers.downloads.documents".equals(uri 
       .getAuthority()); 
    } 

    /** 
    * @param uri 
    *   The Uri to check. 
    * @return Whether the Uri authority is MediaProvider. 
    */ 
    public static boolean isMediaDocument(Uri uri) { 
     return "com.android.providers.media.documents".equals(uri 
       .getAuthority()); 
    } 

    /** 
    * @param uri 
    *   The Uri to check. 
    * @return Whether the Uri authority is Google Photos. 
    */ 
    public static boolean isGooglePhotosUri(Uri uri) { 
     return "com.google.android.apps.photos.content".equals(uri 
       .getAuthority()); 
    } 
} 

https://github.com/layerlre/Android-Utility-Class/blob/master/utils/ImageFilePath.java

希望你的作品。

+0

雖然這個鏈接可能回答這個問題,但最好在這裏包含答案的基本部分並提供參考鏈接。如果鏈接頁面發生變化,僅鏈接答案可能會失效 - 來自評論](/ review/low-quality-posts/18524227) – Jon

相關問題