Home » Android » Android: should I use MimeTypeMap.getFileExtensionFromUrl()? [bugs]

Android: should I use MimeTypeMap.getFileExtensionFromUrl()? [bugs]

Posted by: admin May 14, 2020 Leave a comment

Questions:

For example, I wanted to get the file Extension from the file URL using the function below:

File name:

Greatest Hits - Lenny Kravitz (Booklet 01) [2000].jpg

Url of the file:

String url = "/mnt/sdcard/mydev/Greatest Hits - Lenny Kravitz (Booklet 01) [2000].jpg";

Function call:

String extension = MimeTypeMap.getFileExtensionFromUrl(url);

But I’m getting an exception on the function call. Is this a bug or a feature?

It works fine for file names that don’t contain that many foreign characters (such as paranthesis).

Is the function buggy? Am I missing something? How am I supposed to differentiate a bug from a feature? I’ve read the function description and it should work properly.

Do you personally use it in your projects? It doesn’t seem reliable.

How to&Answers:

When I test your code, no exception is thrown for me. Though the proper file extension “jpg” is not returned. I would not advise using MimeTypeMap. An easy way to obtain the file extension instead is as follows:

String file = "/mnt/sdcard/mydev/Greatest Hits - Lenny Kravitz (Booklet 01) [2000].jpg";
String exten = "";

int i = file.lastIndexOf('.');
if (i > 0) {
    exten = file.substring(i+1);
}

As to why MimeTypeMap.getFileExtensionFromUrl(url) fails? It’s expecting a properly formated URL String, which yours is not. You should first encode it using URLEncoder. For example:

String url = "/mnt/sdcard/mydev/Greatest Hits - Lenny Kravitz (Booklet 01) [2000].jpg";
url = URLEncoder.encode(url, "UTF-8");

This should allow MimeTypeMap.getFileExtensionFromUrl(url) to work properly but unfortunately it still doesn’t. Why? URLEncoder will change all spaces to a ‘+’ sign and getFileExtensionFromUrl considers that an invalid character. This part, IMHO, is a bug.

From my experience, most people don’t use this method. In fact, I never heard of it until you posted this question. Probably because finding a file extension is fairly trivial and most people write code similar to what I posted above.

Answer:

private String getMimeTypeFromPath(String path) { 
    String extension = path; 
    int lastDot = extension.lastIndexOf('.'); 
    if (lastDot != -1) { 
        extension = extension.substring(lastDot + 1); 
    } 
    // Convert the URI string to lower case to ensure compatibility with MimeTypeMap (see CB-2185). 
    extension = extension.toLowerCase(Locale.getDefault()); 
    if (extension.equals("3ga")) { 
        return "audio/3gpp"; 
    } else if (extension.equals("js")) { 
        // Missing from the map :(. 
        return "text/javascript"; 
    } 
    return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); 
} 

Answer:

I use this in my project and it works unless there certain characters in the file name,

I decided to not go the route of splitting the string myself.

I made a work around for the issue:

String ext = MimeTypeMap.getFileExtensionFromUrl(sanitizeFileName(Uri.encode(name)));

And i made this method to sanitize file names:

public static String sanitizeFileName(String name)
{
    byte[] invalidChars = new byte[]{34, 60, 62, 124, 0, 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, 58, 42, 63, 92, 47};
    for(byte i : invalidChars)
    {
        name = name.replace((char)i,'_');
    }
    return name;
}

The sanitize method is useful for other things as well.