20

I've reviewed all the similar questions here, but I can't for the life of me figure out what I'm doing wrong.

I've written an application that tries to launch various files, sort of a file browser. When a file is clicked, it tries to launch the program based on its associated MIME type or it presents the "Choose Application to Launch" dialog.

Here's the code I'm using to launch:

    File file = new File(app.mediaPath() + "/" +_mediaFiles.get(position));

    Intent myIntent = new Intent(android.content.Intent.ACTION_VIEW);

    String extension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString());
    String mimetype = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
    myIntent.setDataAndType(Uri.fromFile(file),mimetype);
    startActivity(myIntent);

This fails and generates the error:

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=file:///file:/mnt/sdcard/roms/nes/Baseball_simulator.nes }

Now if I install OI File Manager for instance, it opens instead of this error being thrown, and then if I click the same file from within in it, it launches the approriate dialogs.

I have noticed that the MIME type for that particular file fails, but other mime types like .zip do return values.

Am I missing something that when the MIME type is null to call a dialog that lets the user select?

I've tried other variations of launching the app, including not setting the MIME type and only using .setData with no success.

The action I want to happen is, a user clicks a file, if it's associated with an application that app launches, if not, the user gets the "Complete action using" dialog with a list of apps.

Thanks for any advice.

Arnold Spence
  • 21,942
  • 7
  • 74
  • 67
stonedonkey
  • 713
  • 1
  • 8
  • 18
  • what is coming in mimetype string?? paste it here – Vipul Jun 17 '12 at 04:33
  • Looks like if it's something that has an associated file it's the correct MIME type, but if it's something that hasn't been tied to an app it comes through null.. – stonedonkey Jun 18 '12 at 15:02

2 Answers2

48

Well thanks to the Open Intent guys, I missed the answer the first time through their code in their file manager, here's what I ended up with:

    File file = new File(filePath);
    MimeTypeMap map = MimeTypeMap.getSingleton();
    String ext = MimeTypeMap.getFileExtensionFromUrl(file.getName());
    String type = map.getMimeTypeFromExtension(ext);

    if (type == null)
        type = "*/*";

    Intent intent = new Intent(Intent.ACTION_VIEW);
    Uri data = Uri.fromFile(file);

    intent.setDataAndType(data, type);

    startActivity(intent);

If you use a mime type of "* / *" when you can't determine it from the system(it is null) it fires the appropriate select application dialog.

hasanghaforian
  • 13,858
  • 11
  • 76
  • 167
stonedonkey
  • 713
  • 1
  • 8
  • 18
  • 7
    WARNING! - For jpgs, the mime type is jpeg and NOT jpg. Using your code, if you extract the jpg extension, it will not set the mime type correctly and as a result, you will not be able to view the image. Make sure to replace jpg with jpeg when setting the mime type for jpg images. – Johann Jul 25 '13 at 17:25
  • thanks its help me but actual file not chooser after setting intent.setDataAndType(data, type); file upload failed. – Jatinkumar Patel Feb 19 '15 at 05:30
  • 1
    Also, The MimeTypeMap.getFileExtensionFromUrl can't handle apostrophes well: it will return an empty string for "World'sHello.docx", but will return docx for "WorldzHello.docx". See Regex Here: https://github.com/android/platform_frameworks_base/blob/master/core/java/android/webkit/MimeTypeMap.java – Felix Oct 26 '15 at 12:58
  • Very helpful. Thanks! – Seyyed Feb 17 '16 at 11:10
  • @AndroidDev Appears fixed in 6.0.1. – samus Jul 11 '17 at 20:44
1

You can use generic intents to open files,like this snippet code that is proposed here:

private void openFile(File aFile){
    try {
        Intent myIntent = new Intent(android.content.Intent.VIEW_ACTION,
        new ContentURI("file://" + aFile.getAbsolutePath()));
        startActivity(myIntent);
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
}     

But I usually see that Applications checks the file's extension in nested if and finally try to open file with "text/plain" type:

Intent generic = new Intent();
generic.setAction(android.content.Intent.ACTION_VIEW);
generic.setDataAndType(Uri.fromFile(file), "text/plain");     
try {
    startActivity(generic);
    } catch(ActivityNotFoundException e) {
    ...
}     

You can see complete code in this question or in this open source project. I hope this help you.

Community
  • 1
  • 1
hasanghaforian
  • 13,858
  • 11
  • 76
  • 167
  • I tried both of these and neither results in the result I'm looking for. The first example generates the same exception. The second tries to launch only apps that understand text/plain as a mime type so that won't work either. Thanks though. – stonedonkey Jun 18 '12 at 15:00