2013-11-28 43 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

相关问题