2014-12-16 4 views
2

uri에서 경로를 가져 오려고합니다. 그것은 kitkat 아래 장치에서 작동합니다. 내가 봤 거든 내가 문서 ID를 얻고 갤러리 항목으로 쿼리해야한다는 것을 알았습니다. 그리고 그것은 작동합니다. 그러나 나는 비디오에 문제가있다. 비디오 섹션에서 비디오를 선택하면 작동합니다. 그러나 갤러리에서 그것을 선택하면 잘못된 응용 프로그램 예외 - 문서 유형이 아닌 응용 프로그램이 다운됩니다. 나는 그것이 왜 일어나고 있는지 안다. 갤러리 섹션에서 동영상의 문서 유형을 찾고 있기 때문입니다. 그러나 이것을 방지하는 방법. 그래서 두 갤러리 & 비디오 섹션에서 비디오를 선택할 수 있습니다.안드로이드에서 Uri의 경로 가져 오기 Kitkat이 잘못된 인수 예외를 throw합니다

여기 내 코드입니다 :

public static String getRealPathFromURI(Context context, Uri contentUri,String type) { 
    if(isKitkatBelow()) { 
     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); 
    }else{ 

     String docId= DocumentsContract.getDocumentId(contentUri); 
     String id= docId.split(":")[1]; 
     if(type== TYPE_IMAGE){ 
      String[] proj = { MediaStore.Images.Media.DATA }; 
      String whereClause=MediaStore.Images.Media._ID + "=?"; 
      Cursor cursor=context.getContentResolver().query(getUri(type),proj,whereClause,new String[]{id},null); 
      int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
      cursor.moveToFirst(); 
      return cursor.getString(column_index); 
     }else{ 
      String[] proj = { MediaStore.Video.Media.DATA }; 
      String whereClause=MediaStore.Video.Media._ID + "=?"; 
      Cursor cursor=context.getContentResolver().query(getUri(type),proj,whereClause,new String[]{id},null); 
      int column_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA); 
      cursor.moveToFirst(); 
      return cursor.getString(column_index); 
     } 



    } 
} 

내가 갤러리에 입력 MediaStore.Video.Media.DATA의 파일을 검색하는 것을 시도하고 있기 때문에이 일어나고있다. 그러나 kitkat 아래의 장치의 경우 MediaStore.Images.Media.DATA는 충돌을 일으키지 않고 갤러리에서 비디오 URI를 가져옵니다. 미리 감사드립니다 ..

답변

10
당신이 사용하는 다음 코드를 달성하기 때문에 안드로이드에서 Kitkat으로 모두 킷캣 (API 19)의 아래에 차이 선택한 파일의 URI에서 절대 경로를 얻기 위해 사용할 수있는

,

public static String getPath(final Context context, final Uri uri) { 

    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]; 
      } 

      // TODO handle non-primary volumes 
     } 
     // 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 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 column_index = cursor.getColumnIndexOrThrow(column); 
      return cursor.getString(column_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()); 
} 
+0

고마워요. 이걸 사용하겠습니다. 작동한다면 알려 드리겠습니다. –

+0

감사합니다. 하지만 하나의 쿼리가 있습니다. 다른 앱이 있고 사용자가 그 중 하나를 선택하면 오른쪽 충돌이 발생합니다. –

+0

사용자가 선택하는 방법은 무엇입니까? –