I have an OnClick method in which the following functionality is implemented:

 Intent intent = new Intent(); intent.setType("*/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent,"Выберите файл для загрузки "), 1); 

After that, a list of files is opened, after selecting we go to the OnActivityResult method and there we get the Intent that was sent in the OnClick method.

 @Override public void onActivityResult(int requestCode, int resultCode, Intent data) 

How can I get the file extension through the variable data ? I get the full path to the file on which I can get it but the name does not correspond to reality. For example, in my phone I have a media file called video0515.mp4 and in data I get the path to the file:

 Intent { dat=content://com.android.providers.media.documents/document/video:10515 flg=0x1 } 

and the extension does not work.

  • That's just in the URI and there is a link to the file content: //com.android.providers.media.documents/document/image%3A10734 - Heaven
  • There is nothing more sensible to pull out from there, or I was looking badly - Heaven
  • Returns null - Heaven

1 answer 1

To get the MIME type of a file from its URI, you need to write a small method:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Uri uri = data.getData(); String type = getMimeType(uri))); } 

The method of obtaining itself:

 public String getMimeType(Uri uri) { if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) { ContentResolver cr = this.getContentResolver(); mimeType = cr.getType(uri); } else { String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri .toString()); mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension( fileExtension.toLowerCase()); } return mimeType; } 

the type string will contain the MIME type of the file.
For example, for a JPG image, we get - image / jpg

The two branches in the methods are related to the fact that the URI of content files (like images, video, audio, and so on) have a different format than other files.

You can also get a "clean" file extension from its name. Due to the fact that in Android there is a very confusing file system, which is divided into content (and the content is also by type) and the files themselves, and depends on the API, the universal code for getting the extension is rather cumbersome. If necessary, you can choose a separate module that is appropriate for your task (for example, only image files on API 19 and above), and not copy all the code:

 // метод возвращает полный реальный путь до файла, включая имя и расширение public String getFilePath(Uri uri) { String selection = null; String[] selectionArgs = null; if (Build.VERSION.SDK_INT >= 19 && DocumentsContract.isDocumentUri(this, uri)) { if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); return Environment.getExternalStorageDirectory() + "/" + split[1]; } else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); uri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); } else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("image".equals(type)) { uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } selection = "_id=?"; selectionArgs = new String[]{split[1]}; } } if ("content".equalsIgnoreCase(uri.getScheme())) { String[] projection = {MediaStore.Images.Media.DATA}; Cursor cursor = null; try { cursor = getContentResolver().query(uri, projection, selection, selectionArgs, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); if (cursor.moveToFirst()) { return cursor.getString(column_index); } } catch (Exception e) { } finally { if (cursor != null) cursor.close(); } } else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } 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()); } // метод возвращает из полного пути расширение файла public String getFileExtension(String path) { int pos = path.lastIndexOf("."); if (pos != -1) return path.substring(pos + 1); else return ""; } 

Then getting the extension will happen like this:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Uri uri = data.getData(); String type = getFileExtension(getFilePath(uri))); } 

where the variable type is the file extension.
For example, for the file 1234.jpg it will be equal to jpg

To work on API 19 and above, permission is required in the manifest.

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

  • In the 1st case where we get a separate file extension ... I concatenate it with the file name and send it to the server, the file comes broken - Heaven
  • I parse this line and take the extension after "/" and substitute it in the file name - Heaven
  • I get the file name "image: 10734" + ".jpg" on the server, and I get the file name via File file = new File (uri.getPath ()); file.getName (); - Heaven
  • The file itself is called DSC_0156.JPG and in OnActivityResult this is not the name of the file - Heaven
  • @Heaven file = new File(uri.getPath()); file.getName(); file = new File(uri.getPath()); file.getName(); - for content files does not work, as you can see. - pavlofff