Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

android

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.

like image 465
Tool Avatar asked Jan 14 '13 14:01

Tool


3 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.

like image 148
Jay Soyer Avatar answered Nov 05 '22 23:11

Jay Soyer


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); 
} 
like image 34
WCG Avatar answered Nov 05 '22 22:11

WCG


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.

like image 1
Nicolas Tyler Avatar answered Nov 06 '22 00:11

Nicolas Tyler