启动一个用于文件和MIME类型的意图?

20
我已经查看了所有类似的问题,但我无法明白我做错了什么。
我编写了一个应用程序,尝试启动各种文件,类似于文件浏览器。 当单击文件时,它会根据其关联的MIME类型尝试启动程序,或呈现“选择要启动的应用程序”对话框。
这是我用来启动的代码:
    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);

以下代码执行失败并生成错误:

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

现在,如果我安装OI文件管理器,它会打开而不是抛出此错误,然后如果我从其中单击同一文件,则会启动适当的对话框。

我注意到该特定文件的MIME类型失败了,但其他MIME类型(如.zip)返回值。

当MIME类型为null时,我是否遗漏了调用允许用户选择的对话框的某些内容?

我尝试了其他启动应用程序的变体,包括不设置MIME类型并仅使用.setData,但没有成功。

我希望发生的操作是:用户点击一个文件,如果它与一个应用程序相关联,那么该应用程序将启动,如果没有,用户将获得“使用下列应用程序完成操作”的对话框,其中列出了应用程序列表。

感谢您的任何建议。


Mimetype字符串中包含什么?请将其粘贴在这里。 - Vipul
看起来如果是有关联文件的话,它就是正确的 MIME 类型,但如果是没有绑定应用程序的东西,它就会变成 null。 - stonedonkey
2个回答

48

多亏了Open Intent的伙计们,在他们的文件管理器中,我第一次错过了答案,这是最终的结果:

    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);

如果在无法从系统中确定MIME类型时(即为null),使用"*/*"的MIME类型,它将触发适当的选择应用程序对话框。


7
警告!对于jpg格式的图片,mime类型应该是jpeg而不是jpg。如果您使用代码提取jpg扩展名,则无法正确设置mime类型,导致您无法查看图像。确保在设置jpg图像的mime类型时用jpeg替换jpg。 - Johann
谢谢你的帮助,但是在设置了intent.setDataAndType(data, type)之后,实际文件并没有被选择器选中,导致文件上传失败。 - Jatinkumar Patel
1
另外,MimeTypeMap.getFileExtensionFromUrl 无法很好地处理撇号:对于 "World'sHello.docx",它将返回一个空字符串,但对于 "WorldzHello.docx",它将返回 docx。 请参见正则表达式:https://github.com/android/platform_frameworks_base/blob/master/core/java/android/webkit/MimeTypeMap.java - Felix
非常有帮助。谢谢! - Seyyed
@AndroidDev 看起来在6.0.1中已经修复了。 - samus

1

您可以使用通用意图来打开文件,就像这个代码片段所提供的这里一样:

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();
    }
}     

但我通常看到应用程序在嵌套的if中检查文件扩展名,并最终尝试使用"text/plain"类型打开文件:

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

你可以在这个问题或者这个开源项目中看到完整的代码。希望这能帮到你。


我尝试了这两种方法,但都没有得到我想要的结果。第一个示例生成了相同的异常。第二个示例仅尝试启动理解text/plain作为MIME类型的应用程序,因此也不起作用。谢谢。 - stonedonkey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接