2015-10-19 8 views
6

ich diese Funktion bin mit dem Bild Weg von uri zu erhalten:Get RealPath Rückgabe null auf Android Marshmallow?

private static String getRealPathFromURI(Context context, Uri contentUri) { 
     Cursor cursor = null; 
     try { 
      String[] proj = {MediaStore.Images.Media.DATA}; 
      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); 
     } finally { 
      if (cursor != null) { 
       cursor.close(); 
      } 
     } 
    } 

die obigen Funktion arbeitet mit der Version < 23 in Ordnung. aber es gibt null mit Android Marshmallow?

I am using emulator nexus 4 with android 6.0 x86_64 

Der Emulator verfügt über Speicherberechtigungen.

was könnte das Problem sein?

Antwort

46
/** 
* Get a file path from a Uri. This will get the the path for Storage Access 
* Framework Documents, as well as the _data field for the MediaStore and 
* other file-based ContentProviders. 
* 
* @param context The context. 
* @param uri The Uri to query. 
* @author paulburke 
*/ 
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 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()); 
} 

von here und aus diesem answer genommen. Dies ist ein hässlicher Hack, der nicht auf allen Geräten funktioniert, aber meiner Erfahrung nach funktioniert er auf 99% aller Geräte. Laut CommonsWare sollten Sie nicht davon ausgehen, dass der Stream, den Sie über ContentResolver erhalten, in eine Datei konvertierbar ist. Stattdessen sollten Sie eine inputstream von dieser Uri mit der context.getContentResolver().openInputStream(fileUri) Methode öffnen. Weitere Informationen hierzu finden Sie unter commonsBlog post und wie man mit Uris umgeht

+0

vielen Dank – david

+0

vielen Dank! – mmw5610

+1

Vielen Dank !! :) – mt0s