java中uri找不到文件路径_华为手机选择文件路径uri问题

冉永宁
2023-12-01

在上传文件功能的时候在文件管理器中选择文件有些打不开,例如在下载文件夹中的,一直找不到原因,最后查到这篇文章成功使用里面的方法解决了

重点就是 添加docId.startsWith("raw:")这个的判断处理

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;

}

以下为原文章内容

在华为手机上选择图片的时候。拿到一个这样的路径:(华为手机进打开图库-》下载内容-》browser-》图片收藏-》选择图片)

@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());

}

之前一直这么用,直到遇到了这次,之前选择以后的路径都是类似这种:

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;

}

 类似资料: