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

我正在使用第三方文件pipe理器从文件系统中select一个文件(在我的情况下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 File Manager的说明中借用的:
http://www.openintents.org/en/node/829

if-else的目的是向后兼容。 我不知道这是否是获取文件名的最好方法,因为我发现其他文件pipe理器返回所有types的东西。

例如, Documents ToGo返回如下所示的内容:

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

getContentResolver().query()返回null

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

 /./sdcard/downloads/.bin 

有没有从URI中提取文件名的首选方式,或者应该求助于stringparsing?

developer.android.com有这个很好的示例代码: https : //developer.android.com/guide/topics/providers/document-provider.html

压缩版本只提取文件名(假设“this”是一个Activity):

 public String getFileName(Uri uri) { String result = null; if (uri.getScheme().equals("content")) { Cursor cursor = getContentResolver().query(uri, null, null, null, null); try { if (cursor != null && cursor.moveToFirst()) { result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); } } finally { cursor.close(); } } if (result == null) { result = uri.getPath(); int cut = result.lastIndexOf('/'); if (cut != -1) { result = result.substring(cut + 1); } } return result; } 

我正在使用这样的东西:

 String scheme = uri.getScheme(); if (scheme.equals("file")) { fileName = uri.getLastPathSegment(); } else if (scheme.equals("content")) { String[] proj = { MediaStore.Images.Media.TITLE }; Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null); if (cursor != null && cursor.getCount() != 0) { int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.TITLE); cursor.moveToFirst(); fileName = cursor.getString(columnIndex); } if (cursor != null) { cursor.close(); } } 

采取从文件信息| Android开发者

检索文件的名称。

 private String queryName(ContentResolver resolver, Uri uri) { Cursor returnCursor = resolver.query(uri, null, null, null, null); assert returnCursor != null; int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); returnCursor.moveToFirst(); String name = returnCursor.getString(nameIndex); returnCursor.close(); return name; } 
 public String getFilename() { /* Intent intent = getIntent(); String name = intent.getData().getLastPathSegment(); return name;*/ Uri uri=getIntent().getData(); String fileName = null; Context context=getApplicationContext(); String scheme = uri.getScheme(); if (scheme.equals("file")) { fileName = uri.getLastPathSegment(); } else if (scheme.equals("content")) { String[] proj = { MediaStore.Video.Media.TITLE }; Uri contentUri = null; Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null); if (cursor != null && cursor.getCount() != 0) { int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE); cursor.moveToFirst(); fileName = cursor.getString(columnIndex); } } return fileName; } 

如果你想要它短暂这应该工作。

 Uri uri= data.getData(); File file= new File(uri.getPath()); file.getName(); 

我使用下面的代码从我的项目中得到Uri的文件名和文件大小。

 /** * Used to get file detail from uri. * <p> * 1. Used to get file detail (name & size) from uri. * 2. Getting file details from uri is different for different uri scheme, * 2.a. For "File Uri Scheme" - We will get file from uri & then get its details. * 2.b. For "Content Uri Scheme" - We will get the file details by querying content resolver. * * @param uri Uri. * @return file detail. */ public static FileDetail getFileDetailFromUri(final Context context, final Uri uri) { FileDetail fileDetail = null; if (uri != null) { fileDetail = new FileDetail(); // File Scheme. if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { File file = new File(uri.getPath()); fileDetail.fileName = file.getName(); fileDetail.fileSize = file.length(); } // Content Scheme. else if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { Cursor returnCursor = context.getContentResolver().query(uri, null, null, null, null); if (returnCursor != null && returnCursor.moveToFirst()) { int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE); fileDetail.fileName = returnCursor.getString(nameIndex); fileDetail.fileSize = returnCursor.getLong(sizeIndex); returnCursor.close(); } } } return fileDetail; } /** * File Detail. * <p> * 1. Model used to hold file details. */ public static class FileDetail { // fileSize. public String fileName; // fileSize in bytes. public long fileSize; /** * Constructor. */ public FileDetail() { } } 
 String Fpath = getPath(this, uri) ; File file = new File(Fpath); String filename = file.getName(); 

我的版本答案其实非常类似于@Stefan Haustein。 我在Android开发者页面上find答案正在检索文件信息 ; 这里的信息比存储访问框架指南网站上的这个特定主题更加简洁。 在查询结果中,包含文件名的列索引是OpenableColumns.DISPLAY_NAME 。 没有任何其他答案/列索引解决scheme为我工作。 以下是示例函数:

  /** * @param uri uri of file. * @param contentResolver access to server app. * @return the name of the file. */ def extractFileName(uri: Uri, contentResolver: ContentResolver): Option[String] = { var fileName: Option[String] = None if (uri.getScheme.equals("file")) { fileName = Option(uri.getLastPathSegment) } else if (uri.getScheme.equals("content")) { var cursor: Cursor = null try { // Query the server app to get the file's display name and size. cursor = contentResolver.query(uri, null, null, null, null) // Get the column indexes of the data in the Cursor, // move to the first row in the Cursor, get the data. if (cursor != null && cursor.moveToFirst()) { val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) fileName = Option(cursor.getString(nameIndex)) } } finally { if (cursor != null) { cursor.close() } } } fileName } 

首先,您需要将URI对象转换为URL对象,然后使用File对象来检索文件名:

 try { URL videoUrl = uri.toURL(); File tempFile = new File(videoUrl.getFile()); String fileName = tempFile.getName(); } catch (Exception e) { } 

就是这样,很简单。