Thursday, October 9, 2014

Android MIME type without a ContentResolver

Sometimes in Android you'll find yourself needing a MIME type for a given Uri. The conventional wisdom is to use a ContentResolver, which is great if you have a Uri that a ContentProvider knows about. If you have a 'file://' Uri with no corresponding ContentProvider, the popular solution is to use the MimeTypeMap. Unfortunately, if you are dealing with files from the *nix world, files often do not have extensions making a MimeTypeMap based solution incomplete.

Instead, I use something like the below code that uses methods from the URLConnection class. Note that it only works if the Uri has a 'file://' prefix, and points to media that is local, and accessible by your application. It also assumes the extension (if present) is correct. If you don't trust the extensions, use the guessContentTypeFromStream method first. It should be easily modifiable to other Uris.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public static String getMimetypeFromUri(Uri uri) {
 /**
 * Returns a String representing the mimetype for a given Uri.
 *
 * @param uri  the uri to get a mimetype from
 * @return a String reprensenting the mimetype for the given uri,
 *         the 'generic' mimetype if a better one cannot be inferred
 */

 //First, try to guess from the path
 String resultMimetype;

 resultMimetype = URLConnection.guessContentTypeFromName(uri.toString());

 if (resultMimetype == null)
 {
  //Try to get the mimetype by reading the file
  File file = new File(uri.toString());
  FileInputStream fileInputStream;

  try
  {
   fileInputStream = new FileInputStream(file);

   resultMimetype = URLConnection.guessContentTypeFromStream(fileInputStream);

   fileInputStream.close();
  }
  catch (FileNotFoundException e) {
   e.printStackTrace();

   resultMimetype = "*/*";
  }
  catch (IOException e) {
   e.printStackTrace();

   resultMimetype = "*/*";
  }
 }

 return resultMimetype;
}

No comments:

Post a Comment