如何让Intent.ACTION_SEND适用于任何文件类型

时间:2014-03-31 14:37:17

标签: android android-intent

我使用以下代码段打开或共享设备存储中的任何文件(MyFile是我自己的类File,应该被视为File。标记String我通过Intent.ACTION_VIEWIntent_ACTION_SEND):

    public void openOrShare(String flag, MyFile f){
    try {
        MimeTypeMap mmap = MimeTypeMap.getSingleton();
        String type = MimeTypeMap.getFileExtensionFromUrl(f
                .getName());
        String ftype = mmap.getMimeTypeFromExtension(type);
        if (ftype == null)
            ftype = "*/*";
        Intent intent = new Intent(flag);
        Uri data = Uri.fromFile(f);
        intent.setDataAndType(data, ftype);
        startActivity(intent);
    } catch (ActivityNotFoundException e) {
        e.printStackTrace();
        Tools.gimmeToast(
                getActivity(),
                "no application found to handle this file type",
                Toast.LENGTH_LONG);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

传递Intent.ACTION_VIEW一切都适用于任何(也是自定义)类型,系统会创建一个选择器并列出应用程序,对于众所周知的文件,它会启动正确的Activity来立即处理文件

问题:传递Intent.ACTION_SEND似乎正在中途工作 - 它也创建了选择器,但大多数应用程序(Dropbox以及我测试过的更多)只是确认操作时,NPE崩溃。使用各种电子邮件客户端进行测试也失败了:它们不会像大多数其他应用程序一样崩溃,但会创建一条消息,并将Uri(如//storage/.....)放在To中字段(gmail)或者只是创建一个新的空消息,忽略Intent数据(yahoo!mail),而我希望它们将文件附加到新消息。

问题:分享任何文件类型我做错了什么?

修改

我发现如果使用intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f));它会有效,但是在尝试共享某些特定文件(例如.dat)时会遇到ActivityNotFoundException。据我所知,像Dropbox这样的应用程序支持添加任何文件类型。寻找解决方法。

2 个答案:

答案 0 :(得分:1)

如果您不知道文件的MIME类型,请不要设置它。

所以我会尝试:

Intent intent = new Intent(flag);
Uri data = Uri.fromFile(f);
String ftype = mmap.getMimeTypeFromExtension(type);
if (ftype != null) {
    intent.setDataAndType(data, ftype);
} else {
    intent.setData(data);
}

setDataAndType需要数据和显式mime类型(可能* / *不是)。

答案 1 :(得分:0)

没关系,我终于想通了。因此,这是一个工作解决方案,允许使用任何应用程序共享任何类型的数据*:

* 注意:下面的代码实际上还列出了可能无法处理特定文件类型的应用程序,这些应用程序(至少它们应该)通知用户如果是这种情况则不支持文件类型

    public void doShare(MyFile f) {
    try {
        Intent intent = new Intent(Intent.ACTION_SEND);
        MimeTypeMap mmap = MimeTypeMap.getSingleton();
        String type = MimeTypeMap.getFileExtensionFromUrl(f.getName());
        String ftype = mmap.getMimeTypeFromExtension(type);
        if (ftype == null)
            ftype = "*/*";
        intent.setType(ftype);
        intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f));
        startActivity(intent);
    } catch (ActivityNotFoundException e) {
        e.printStackTrace();
        Tools.gimmeToast(getActivity(),
                "no application found to handle this file type",
                Toast.LENGTH_LONG);
    } catch (Exception e) {
        e.printStackTrace();
    }
}