繁体   English   中英

如何从 Intent.ACTION_GET_CONTENT 返回的 URI 中提取文件名?

[英]How to extract the file name from URI returned from Intent.ACTION_GET_CONTENT?

我正在使用第 3 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这就是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult中的内容:

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器指令中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方式,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中获得了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有一种从 URI 中提取文件名的首选方法,或者应该求助于字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我的回答有点矫枉过正,但这里是如何从 android 中的 4 种不同 uri 类型中获取文件名的方法。

  1. 内容提供者 uri [content://com.example.app/sample.png]
  2. 文件 uri [file://data/user/0/com.example.app/cache/sample.png]
  3. 资源 uri [android.resource://com.example.app/1234567890][android.resource://com.example.app/raw/sample]
  4. Http uri [https://example.com/sample.png]
fun Uri.name(context: Context): String {
    when (scheme) {
        ContentResolver.SCHEME_FILE -> {
            return toFile().nameWithoutExtension
        }
        ContentResolver.SCHEME_CONTENT -> {
            val cursor = context.contentResolver.query(
                this,
                arrayOf(OpenableColumns.DISPLAY_NAME),
                null,
                null,
                null
            ) ?: throw Exception("Failed to obtain cursor from the content resolver")
            cursor.moveToFirst()
            if (cursor.count == 0) {
                throw Exception("The given Uri doesn't represent any file")
            }
            val displayNameColumnIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
            val displayName = cursor.getString(displayNameColumnIndex)
            cursor.close()
            return displayName.substringBeforeLast(".")
        }
        ContentResolver.SCHEME_ANDROID_RESOURCE -> {
            // for uris like [android.resource://com.example.app/1234567890]
            var resourceId = lastPathSegment?.toIntOrNull()
            if (resourceId != null) {
                return context.resources.getResourceName(resourceId)
            }
            // for uris like [android.resource://com.example.app/raw/sample]
            val packageName = authority
            val resourceType = if (pathSegments.size >= 1) {
                pathSegments[0]
            } else {
                throw Exception("Resource type could not be found")
            }
            val resourceEntryName = if (pathSegments.size >= 2) {
                pathSegments[1]
            } else {
                throw Exception("Resource entry name could not be found")
            }
            resourceId = context.resources.getIdentifier(
                resourceEntryName,
                resourceType,
                packageName
            )
            return context.resources.getResourceName(resourceId)
        }
        else -> {
            // probably a http uri
            return toString().substringBeforeLast(".").substringAfterLast("/")
        }
    }
}

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

如果有人正在寻找Kotlin答案,尤其是extension功能,那么这就是要走的路。

fun Uri.getOriginalFileName(context: Context): String? {
    return context.contentResolver.query(this, null, null, null, null)?.use {
        val nameColumnIndex = it.getColumnIndex(OpenableColumns.DISPLAY_NAME)
        it.moveToFirst()
        it.getString(nameColumnIndex)
    }
}

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

我正在使用 3rd 方文件管理器从文件系统中选择一个文件(在我的情况下为 PDF)。

这是我启动活动的方式:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(getString(R.string.app_pdf_mime_type));
intent.addCategory(Intent.CATEGORY_OPENABLE);

String chooserName = getString(R.string.Browse);
Intent chooser = Intent.createChooser(intent, chooserName);

startActivityForResult(chooser, ActivityRequests.BROWSE);

这就是我在onActivityResult

Uri uri = data.getData();
if (uri != null) {
    if (uri.toString().startsWith("file:")) {
        fileName = uri.getPath();
    } else { // uri.startsWith("content:")

        Cursor c = getContentResolver().query(uri, null, null, null, null);

        if (c != null && c.moveToFirst()) {

            int id = c.getColumnIndex(Images.Media.DATA);
            if (id != -1) {
                fileName = c.getString(id);
            }
        }
    }
}

代码片段是从此处提供的Open Intents 文件管理器说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我想知道这是否是获取文件名的最佳方法,因为我发现其他文件管理器会返回所有类型的东西。

例如, Documents ToGo返回如下内容:

content://com.dataviz.dxtg.documentprovider/document/file%3A%2F%2F%2Fsdcard%2Fdropbox%2FTransfer%2Fconsent.pdf

在其中getContentResolver().query()返回null

为了让事情变得更有趣,未命名的文件管理器(我从客户端日志中得到了这个 URI)返回如下内容:

/./sdcard/downloads/.bin


是否有从 URI 中提取文件名的首选方法,或者应该诉诸字符串解析?

这是我实现此目的的 utils 方法。 您可以从任何地方复制/粘贴和使用它。

public class FileUtils {

    /**
     * Return file name from Uri given.
     * @param context the context, cannot be null.
     * @param uri uri request for file name, cannot be null
     * @return the corresponding display name for file defined in uri or null if error occurs.
     */
    public String getNameFromURI(@NonNull Context context,  @NonNull Uri uri) {
        String result = null;
        Cursor c = null;
        try {
            c = context.getContentResolver().query(uri, null, null, null, null);
            c.moveToFirst();
            result = c.getString(c.getColumnIndex(OpenableColumns.DISPLAY_NAME));
        }
        catch (Exception e){
            // error occurs
        }
        finally {
            if(c != null){
                c.close();
            }
        }
        return result;
    }
...
}

和用法。

String fileName = FileUtils.getNameFromContentUri(context, myuri);
if(fileName != null){
    // do stuff
}

问候。

这个怎么样?

 Uri uri = result.getData().getClipData().getItemAt(i).getUri();
 uri = Uri.parse(uri.getLastPathSegment());
 System.out.println(uri.getLastPathSegment());

这将打印带有扩展名的文件名

尝试这个,

Intent data = result.getData();
// check condition
if (data != null) {
    Uri sUri = data.getData();
    @SuppressLint("Recycle")
    Cursor returnCursor = getContentResolver().query(sUri, null, null, null, null);
    int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
    returnCursor.moveToFirst();
    String file_name = returnCursor.getString(nameIndex);
}
                    

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM