如何从Uri内容中获取绝对路径文件? Java Android Studio

问题描述 投票:0回答:2

此类 Uris 的 2 个示例是:

“content://com.android.providers.downloads.documents/document/msf%3A33346”和“content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%” 2F下载%2F2021-06-18格式%204.xls"

这些 Uris 会根据手机类型而变化。我需要将 uri 转换为路径文件,例如“storage/emulated/0/document/...”

我使用的最后一种看似最完整但不起作用的方法是我在页面上看到的一个类https://www.semicolonworld.com/question/45962/how-to-get-the-full-file -path-from-uri 如下:

public class FileUtils {

/* Get uri related content real local file path. */
public static String getPath(Context ctx, Uri uri) {
    String ret;
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // Android OS above sdk version 19.
            ret = getUriRealPathAboveKitkat(ctx, uri);
        } else {
            // Android OS below sdk version 19
            ret = getRealPath(ctx.getContentResolver(), uri, null);
        }
    } catch (Exception e) {
        e.printStackTrace();
        Log.d("DREG", "FilePath Catch: " + e);
        ret = getFilePathFromURI(ctx, uri);
    }
    return ret;
}

private static String getFilePathFromURI(Context context, Uri contentUri) {
    //copy file and send new file path
    String fileName = getFileName(contentUri);
    if (!TextUtils.isEmpty(fileName)) {
        String TEMP_DIR_PATH = Environment.getExternalStorageDirectory().getPath();
        File copyFile = new File(TEMP_DIR_PATH + File.separator + fileName);
        Log.d("DREG", "FilePath copyFile: " + copyFile);
        copy(context, contentUri, copyFile);
        return copyFile.getAbsolutePath();
    }
    return null;
}

public static String getFileName(Uri uri) {
    if (uri == null) return null;
    String fileName = null;
    String path = uri.getPath();
    int cut = path.lastIndexOf('/');
    if (cut != -1) {
        fileName = path.substring(cut + 1);
    }
    return fileName;
}

public static void copy(Context context, Uri srcUri, File dstFile) {
    try {
        InputStream inputStream = context.getContentResolver().openInputStream(srcUri);
        if (inputStream == null) return;
        OutputStream outputStream = new FileOutputStream(dstFile);
        IOUtils.copy(inputStream, outputStream); // org.apache.commons.io
        inputStream.close();
        outputStream.close();
    } catch (Exception e) { // IOException
        e.printStackTrace();
    }
}

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private static String getUriRealPathAboveKitkat(Context ctx, Uri uri) {
    String ret = "";

    if (ctx != null && uri != null) {

        if (isContentUri(uri)) {
            if (isGooglePhotoDoc(uri.getAuthority())) {
                ret = uri.getLastPathSegment();
            } else {
                ret = getRealPath(ctx.getContentResolver(), uri, null);
            }
        } else if (isFileUri(uri)) {
            ret = uri.getPath();
        } else if (isDocumentUri(ctx, uri)) {

            // Get uri related document id.
            String documentId = DocumentsContract.getDocumentId(uri);

            // Get uri authority.
            String uriAuthority = uri.getAuthority();

            if (isMediaDoc(uriAuthority)) {
                String idArr[] = documentId.split(":");
                if (idArr.length == 2) {
                    // First item is document type.
                    String docType = idArr[0];

                    // Second item is document real id.
                    String realDocId = idArr[1];

                    // Get content uri by document type.
                    Uri mediaContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    if ("image".equals(docType)) {
                        mediaContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    } else if ("video".equals(docType)) {
                        mediaContentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    } else if ("audio".equals(docType)) {
                        mediaContentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    }

                    // Get where clause with real document id.
                    String whereClause = MediaStore.Images.Media._ID + " = " + realDocId;

                    ret = getRealPath(ctx.getContentResolver(), mediaContentUri, whereClause);
                }

            } else if (isDownloadDoc(uriAuthority)) {
                // Build download uri.
                Uri downloadUri = Uri.parse("content://downloads/public_downloads");

                // Append download document id at uri end.
                Uri downloadUriAppendId = ContentUris.withAppendedId(downloadUri, Long.valueOf(documentId));

                ret = getRealPath(ctx.getContentResolver(), downloadUriAppendId, null);

            } else if (isExternalStoreDoc(uriAuthority)) {
                String idArr[] = documentId.split(":");
                if (idArr.length == 2) {
                    String type = idArr[0];
                    String realDocId = idArr[1];

                    if ("primary".equalsIgnoreCase(type)) {
                        ret = Environment.getExternalStorageDirectory() + "/" + realDocId;
                    }
                }
            }
        }
    }

    return ret;
}

/* Check whether this uri represent a document or not. */
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private static boolean isDocumentUri(Context ctx, Uri uri) {
    boolean ret = false;
    if (ctx != null && uri != null) {
        ret = DocumentsContract.isDocumentUri(ctx, uri);
    }
    return ret;
}

/* Check whether this uri is a content uri or not.
 *  content uri like content://media/external/images/media/1302716
 *  */
private static boolean isContentUri(Uri uri) {
    boolean ret = false;
    if (uri != null) {
        String uriSchema = uri.getScheme();
        if ("content".equalsIgnoreCase(uriSchema)) {
            ret = true;
        }
    }
    return ret;
}

/* Check whether this uri is a file uri or not.
 *  file uri like file:///storage/41B7-12F1/DCIM/Camera/IMG_20180211_095139.jpg
 * */
private static boolean isFileUri(Uri uri) {
    boolean ret = false;
    if (uri != null) {
        String uriSchema = uri.getScheme();
        if ("file".equalsIgnoreCase(uriSchema)) {
            ret = true;
        }
    }
    return ret;
}

/* Check whether this document is provided by ExternalStorageProvider. */
private static boolean isExternalStoreDoc(String uriAuthority) {
    boolean ret = false;

    if ("com.android.externalstorage.documents".equals(uriAuthority)) {
        ret = true;
    }

    return ret;
}

/* Check whether this document is provided by DownloadsProvider. */
private static boolean isDownloadDoc(String uriAuthority) {
    boolean ret = false;

    if ("com.android.providers.downloads.documents".equals(uriAuthority)) {
        ret = true;
    }

    return ret;
}

/* Check whether this document is provided by MediaProvider. */
private static boolean isMediaDoc(String uriAuthority) {
    boolean ret = false;

    if ("com.android.providers.media.documents".equals(uriAuthority)) {
        ret = true;
    }

    return ret;
}

/* Check whether this document is provided by google photos. */
private static boolean isGooglePhotoDoc(String uriAuthority) {
    boolean ret = false;

    if ("com.google.android.apps.photos.content".equals(uriAuthority)) {
        ret = true;
    }

    return ret;
}

/* Return uri represented document file real local path.*/
@SuppressLint("Recycle")
private static String getRealPath(ContentResolver contentResolver, Uri uri, String whereClause) {
    String ret = "";

    // Query the uri with condition.
    Cursor cursor = contentResolver.query(uri, null, whereClause, null, null);

    if (cursor != null) {
        boolean moveToFirst = cursor.moveToFirst();
        if (moveToFirst) {

            // Get columns name by uri type.
            String columnName = MediaStore.Images.Media.DATA;

            if (uri == MediaStore.Images.Media.EXTERNAL_CONTENT_URI) {
                columnName = MediaStore.Images.Media.DATA;
            } else if (uri == MediaStore.Audio.Media.EXTERNAL_CONTENT_URI) {
                columnName = MediaStore.Audio.Media.DATA;
            } else if (uri == MediaStore.Video.Media.EXTERNAL_CONTENT_URI) {
                columnName = MediaStore.Video.Media.DATA;
            }

            // Get column index.
            int columnIndex = cursor.getColumnIndex(columnName);

            // Get column value which is the uri related file local path.
            ret = cursor.getString(columnIndex);
        }
    }

    return ret;
}
}
java android-studio file path uri
2个回答
1
投票

任何面临这个问题的人都可以使用这个功能,它对我有用。

private fun getRealPathFromURI(contentUri: Uri, context: Context): String? {
    val proj = arrayOf(MediaStore.Images.Media.DATA)
    val loader = CursorLoader(context, contentUri, proj, null, null, null)
    val cursor: Cursor? = loader.loadInBackground()
    val columnIndex: Int = cursor
        ?.getColumnIndexOrThrow(MediaStore.Images.Media.DATA) 
        ?: return null
    cursor.moveToFirst()
    val result: String? = cursor.getString(columnIndex)
    cursor.close()
    return result
}

0
投票

要在 Java Android Studio 中从 Uri 内容获取文件的绝对路径,可以使用此 GitHub gist 中提供的方法:GetAbsolutePathFromUri.java.

您可以将此文件包含在 Android Studio 项目中并调用

getRealPathFromURI()
方法,并将
Uri
作为参数传递。该方法将返回与提供的
Uri
对应的文件的绝对路径。

以下是如何在代码中使用它:

// Assuming you have a Uri named uri
String absolutePath = GetAbsolutePathFromUri.getRealPathFromURI(context, uri);

确保将

context
替换为您的应用程序上下文,并将
uri
替换为您想要获取其绝对路径的 Uri。

有关更多详细信息,请参阅 GitHub gist。如果您还有任何疑问,请随时询问!


© www.soinside.com 2019 - 2024. All rights reserved.