2015-04-15 4 views
4

Я хочу создать подборщик изображений для Android Lollipop. Я использую Intent.ACTION_GET_CONTENT, чтобы выбрать мое изображение, но я не могу получить путь к выбранному изображению из URI, который отобразил диалоговое окно выбора.Как получить путь к файлу изображения из URI в Android Lollipop?

Я попытался коды из этих нитей:

retrieve absolute path when select image from gallery kitkat android

https://chintankhetiya.wordpress.com/2013/12/14/picture-selection-from-camera-gallery/

но все они возвращают нуль. Может кто-нибудь мне помочь?

+0

взглянуть на этот вопрос: http://stackoverflow.com/questions/21017925/android-image-file-path-from-uri/40301000 # 40301000 – birdy

ответ

13

Попробуйте

import android.annotation.SuppressLint; 
import android.content.Context; 
import android.content.CursorLoader; 
import android.database.Cursor; 
import android.net.Uri; 
import android.provider.DocumentsContract; 
import android.provider.MediaStore; 

public class RealPathUtil { 
    @SuppressLint("NewApi") 
    public static String getRealPathFromURI_API19(Context context, Uri uri) { 
     Log.variable("uri", uri.getPath()); 
     String filePath = ""; 
     if (DocumentsContract.isDocumentUri(context, uri)) { 
      String wholeID = DocumentsContract.getDocumentId(uri); 
      Log.variable("wholeID", wholeID); 
// Split at colon, use second item in the array 
      String[] splits = wholeID.split(":"); 
      if (splits.length == 2) { 
       String id = splits[1]; 

       String[] column = {MediaStore.Images.Media.DATA}; 
// where id is equal to 
       String sel = MediaStore.Images.Media._ID + "=?"; 
       Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
         column, sel, new String[]{id}, null); 
       int columnIndex = cursor.getColumnIndex(column[0]); 
       if (cursor.moveToFirst()) { 
        filePath = cursor.getString(columnIndex); 
       } 
       cursor.close(); 
      } 
     } else { 
      filePath = uri.getPath(); 
     } 
     return filePath; 
    } 

    @SuppressLint("NewApi") 
    public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) { 
     String[] proj = {MediaStore.Images.Media.DATA}; 
     String result = null; 
     CursorLoader cursorLoader = new CursorLoader(
       context, 
       contentUri, proj, null, null, null); 
     Cursor cursor = cursorLoader.loadInBackground(); 
     if (cursor != null) { 
      int column_index = 
        cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
      cursor.moveToFirst(); 
      result = cursor.getString(column_index); 
     } 
     return result; 
    } 

    public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri) { 
     String[] proj = {MediaStore.Images.Media.DATA}; 
     Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null); 
     int column_index 
       = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
     cursor.moveToFirst(); 
     return cursor.getString(column_index); 
    } 

и использование:

private String uriToFilename(Uri uri) { 
    String path = null; 

    if (Build.VERSION.SDK_INT < 11) { 
     path = RealPathUtil.getRealPathFromURI_BelowAPI11(mContext, uri); 
    } else if (Build.VERSION.SDK_INT < 19) { 
     path = RealPathUtil.getRealPathFromURI_API11to18(mContext, uri); 
    } else { 
     path = RealPathUtil.getRealPathFromURI_API19(mContext, uri); 
    } 

    return path; 
} 

работает для меня в сусло случаях (not works для загрузки приложения)

+0

Это не работает с Android N – Akshay

1

Эта работа для меня.

Я создал класс Util RealPathUtil (есть некоторые небольшие различия с классом в ответ @Artem):

import android.annotation.SuppressLint; 
import android.content.Context; 
import android.content.CursorLoader; 
import android.database.Cursor; 
import android.net.Uri; 
import android.provider.DocumentsContract; 
import android.provider.MediaStore; 

public class RealPathUtil { 

    @SuppressLint("NewApi") 
    public static String getRealPathFromURI_API19(Context context, Uri uri) { 
     String filePath = ""; 
     String wholeID = DocumentsContract.getDocumentId(uri); 

     // Split at colon, use second item in the array 
     String id = wholeID.split(":")[1]; 

     String[] column = { MediaStore.Images.Media.DATA }; 

     // where id is equal to 
     String sel = MediaStore.Images.Media._ID + "=?"; 

     Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
       column, sel, new String[]{ id }, null); 

     assert cursor != null; 
     int columnIndex = cursor.getColumnIndex(column[0]); 

     if (cursor.moveToFirst()) { 
      filePath = cursor.getString(columnIndex); 
     } 
     cursor.close(); 
     return filePath; 
    } 


    @SuppressLint("NewApi") 
    public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) { 
     String[] proj = { MediaStore.Images.Media.DATA }; 
     String result = null; 

     CursorLoader cursorLoader = new CursorLoader(
       context, 
       contentUri, proj, null, null, null); 
     Cursor cursor = cursorLoader.loadInBackground(); 

     if(cursor != null){ 
      int column_index = 
        cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
      cursor.moveToFirst(); 
      result = cursor.getString(column_index); 
     } 
     return result; 
    } 

    public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri){ 
     Cursor cursor = null; 

     try { 
      String[] proj = { MediaStore.Images.Media.DATA }; 
      cursor = context.getContentResolver().query(contentUri, proj, null, null, null); 
      assert cursor != null; 
      int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
      cursor.moveToFirst(); 
      return cursor.getString(column_index); 
     } finally { 
      if (cursor != null) { 
       cursor.close(); 
      } 
     } 
    } 

} 

Тогда в моем приложении код, который я использовал:

private String getPathFromUri(Uri uri) { 
    if (Build.VERSION.SDK_INT < 11) 
     return RealPathUtil.getRealPathFromURI_BelowAPI11(getContext(), uri); 
    else if (Build.VERSION.SDK_INT < 19) 
     return RealPathUtil.getRealPathFromURI_API11to18(getContext(), uri); 
    else 
     return RealPathUtil.getRealPathFromURI_API19(getContext(), uri); 
} 
0

Убедитесь, что вы даете разрешение в манифесте Android!

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
2

Попробуйте эту маленькую функцию:

public static String getRealPathFromUri(Uri uri) { 
    String result = ""; 
    String documentID; 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { 
     String[] pathParts = uri.getPath().split("/"); 
     documentID = pathParts[pathParts.length - 1]; 
    } else { 
     String pathSegments[] = uri.getLastPathSegment().split(":"); 
     documentID = pathSegments[pathSegments.length - 1]; 
    } 
    String mediaPath = MediaStore.Images.Media.DATA; 
    Cursor imageCursor = getContentResolver().query(uri, new String[]{mediaPath}, MediaStore.Images.Media._ID + "=" + documentID, null, null); 
    if (imageCursor.moveToFirst()) { 
     result = imageCursor.getString(imageCursor.getColumnIndex(mediaPath)); 
    } 
    return result; 
} 
+0

Это очень помогло мне, я искал код, который работает в Lollipop, ваш ответ был идеальным для меня, спасибо! – drikoda

+0

Счастливый услышать это. Пожалуйста. – MLF

+2

В Nougat, передавая содержимое изображения Uri, это возвращает null. –

Смежные вопросы