2013-11-28 2 views
21

내 앱을 Kitkat 버전으로 지원하므로 갤러리의 파일 검색 방법이 다릅니다.갤러리에서 이미지를 선택할 때 절대 경로를 검색합니다. android

나는 갤러리에서 파일을 검색하는이 Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT을 선호하고 성공적으로 작동하지만 해당 파일의 절대 경로를 요구했다, 나는 점점 오전 사용하여 우리가 다른 URI 사용 버전 아래 19

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

무엇입니까 이쪽 경로는

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 버전에서는 사용자가 선택한 이미지 파일의 절대 경로를 얻는 방법을 알려줍니다.

감사

답변

27

여기에 파일을 선택한 후 절대 경로에 액세스 할 수있는 한 가지 방법입니다.

이 방법처럼 KK (킷캣)에 대한 새로운 URI 형식으로 데이터를 가져 오는 한 후

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

그냥 Pratik의 솔루션이 많이 도와주었습니다 문서

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}} {com.example.loadimage/com.example.loadimage.MainActivity} : java.lang.SecurityException : UID 10259 및 Uri에 대한 권한 부여가 없습니다. 내용 : –

+0

이 줄에서 예외가 발생하는 것 같습니다 takePersistableUriPermission 매니페스트에 어떤 종류의 허가도 추가해야합니까? –

+1

던졌습니다. 원인 : java.lang.SecurityException : 요청한 플래그 0x1이지만 0x0 만 허용됩니다. – RobinHood

4

의 ID를 추출합니다. 다음은 Kitkat 4.4.2에서 저에게 맞는 버전입니다. 내가 변경 한 세 가지는
입니다. 1) 콘텐츠 확인자를 사용하여 경로를 가져옵니다.
2) originalUri.getLastPathSegment(). split (":") [1] 나 대신 인덱스 0을 사용하고 있습니다. . 지금까지 노력해 왔습니다.
3) id가있는 커서를 필터링 할 때 takeflags를 제거하고 가장 신선한 데이터를 확인하십시오.

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

이 링크가 질문에 대답 할 수 있지만 여기에 답의 핵심 부분을 포함하고 참조 용 링크를 제공하는 것이 좋다. 링크 된 페이지가 변경되면 링크 전용 답변이 유효하지 않을 수 있음 - 리뷰에서] (리뷰/저품질 게시물/18524227) – Jon

관련 문제