Android uri轉真實路徑。
阿新 • • 發佈:2018-12-12
在華為手機上選擇圖片的時候。拿到一個這樣的路徑:(華為手機進開啟相簿-》下載內容-》browser-》圖片收藏-》選擇圖片)
content://com.android.providers.downloads.documents/document/raw:/storage/emulated/0/Download/browser/圖片收藏/200832810200350_2.jpg
emmm.這個uri怎麼轉換都不成功。之前的轉換方法:
@TargetApi(Build.VERSION_CODES.KITKAT) 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]; } } // DownloadsProvider else if (isDownloadsDocument(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 uri.getPath(); } 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); } } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "GetDataColumnFail", e); } finally { if (cursor != null) cursor.close(); } return null; } public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); }
之前一直這麼用,直到遇到了這次,之前選擇以後的路徑都是類似這種:
content://com.android.providers.media.documents/document/image%3A836956
這次的路徑是:
content://com.android.providers.downloads.documents/document/raw:/storage/emulated/0/Download/browser/圖片收藏/200832810200350_2.jpg
這個會進到isDownloadsDocument這個判斷中,程式碼裡是拿到long型別的id.可是我們這個拿到的id是:
raw:/storage/emulated/0/Download/browser/圖片收藏/200832810200350_2.jpg"
這樣就會報轉換錯誤。
java.lang.NumberFormatException: For input string: "raw:/storage/emulated/0/Download/browser/圖片收藏/200832810200350_2.jpg"
找了很多資料,最後找到解決辦法。
if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); if (id.startsWith("raw:")) { return id.replaceFirst("raw:", ""); } final Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); }
我們也可以看到raw後面返回的其實就是真實路徑,所以我們直接取出來就好了。
完整的程式碼:
@SuppressLint("NewApi")
public static String getPathFromUri(final Context context, final Uri uri) {
if (uri == null) {
return null;
}
// 判斷是否為Android 4.4之後的版本
final boolean after44 = Build.VERSION.SDK_INT >= 19;
if (after44 && DocumentsContract.isDocumentUri(context, uri)) {
// 如果是Android 4.4之後的版本,而且屬於檔案URI
final String authority = uri.getAuthority();
// 判斷Authority是否為本地端檔案所使用的
if ("com.android.externalstorage.documents".equals(authority)) {
// 外部儲存空間
final String docId = DocumentsContract.getDocumentId(uri);
final String[] divide = docId.split(":");
final String type = divide[0];
if ("primary".equals(type)) {
String path = Environment.getExternalStorageDirectory().getAbsolutePath().concat("/").concat(divide[1]);
return path;
} else {
String path = "/storage/".concat(type).concat("/").concat(divide[1]);
return path;
}
} else if ("com.android.providers.downloads.documents".equals(authority)) {
// 下載目錄
final String docId = DocumentsContract.getDocumentId(uri);
if (docId.startsWith("raw:")) {
final String path = docId.replaceFirst("raw:", "");
return path;
}
final Uri downloadUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.parseLong(docId));
String path = queryAbsolutePath(context, downloadUri);
return path;
} else if ("com.android.providers.media.documents".equals(authority)) {
// 圖片、影音檔案
final String docId = DocumentsContract.getDocumentId(uri);
final String[] divide = docId.split(":");
final String type = divide[0];
Uri mediaUri = null;
if ("image".equals(type)) {
mediaUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
mediaUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
mediaUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
} else {
return null;
}
mediaUri = ContentUris.withAppendedId(mediaUri, Long.parseLong(divide[1]));
String path = queryAbsolutePath(context, mediaUri);
return path;
}
} else {
// 如果是一般的URI
final String scheme = uri.getScheme();
String path = null;
if ("content".equals(scheme)) {
// 內容URI
path = queryAbsolutePath(context, uri);
} else if ("file".equals(scheme)) {
// 檔案URI
path = uri.getPath();
}
return path;
}
return null;
}
public static String queryAbsolutePath(final Context context, final Uri uri) {
final String[] projection = {MediaStore.MediaColumns.DATA};
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
return cursor.getString(index);
}
} catch (final Exception ex) {
ex.printStackTrace();
if (cursor != null) {
cursor.close();
}
}
return null;
}
每日語錄:
呀。撐一撐。國慶了!!!!加油!!!
單曲迴圈老狼的《情人劫》