Gmail附件和自定义扩展

7
我目前正在开发一款Android应用程序,可以读取带有自定义扩展名的文件。 其中一个必要的功能是,当用户收到附件为“我们的扩展名”的电子邮件时,该应用程序必须由Gmail提供。
我进行了一些研究,并发现Android上的Gmail客户端不依赖于扩展名,因为在启动意图的数据中,所提供的文件没有扩展名。它只依赖于邮件客户端提供的MIME类型。
问题在于,我们的自定义文件在邮件客户端之间的检测方式不同。例如,如果我使用Gmail网页向自己发送自定义文件,则MIME类型被检测为application/octet-stream。如果我的朋友使用苹果邮件桌面软件发送,则检测为text/xml(这很好)。在另一个邮件客户端Evolution上,MIME类型为text/plain...
我们的应用程序无法处理所有这些类型!否则,它将被提供给每种类型的附件...
有什么解决办法吗?
4个回答

3

解决使用自定义扩展名打开文件的问题,已在 Gmail < 4.2、Gmail 4.2、Google Drive 和文件浏览器中进行测试

发送文件的代码:

sendIntent.setType("application/calc1");

Intent-filter :

           <!-- Filter to open file with gmail version < 4.2 -->
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />

            <data android:mimeType="application/calc1" />
            <data android:pathPattern=".*\\.calc1" />
            <data android:host="*" />
        </intent-filter>

        <!-- Filter to open with file browser or google drive -->
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />

            <data android:scheme="file" />
            <data android:mimeType="*/*" />
            <data android:pathPattern=".*\\.calc1" />
            <data android:host="*" />
        </intent-filter>

        <!-- Filter to open file with gmail version 4.2 -->
        <!-- Save file first with "save" button otherwise gmail crashes -->
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />

            <data android:mimeType="application/octet-stream" />
            <data android:pathPattern=".*\\.calc1" />
            <data android:host="*" />
        </intent-filter>

2

虽然我花了几天的时间来解决所有问题,但是从Gmail中实现这一点是可能的。

重要意图数据

act=android.intent.action.VIEW
dat=file:///mnt/sdcard/Download/Availability Focus.inform
typ=application/octet-stream
flg=0x80001 cmp=air.com.extension/.AppEntry

能够捕获它的Intent Filter(下面有一些注释)
  <intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.BROWSABLE"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="file" android:pathPattern=".*\\.inform" android:mimeType="application/octet-stream"/>
    <data android:scheme="content" android:pathPattern=".*\\.inform" android:mimeType="application/octet-stream"/>
  </intent-filter>

必须同时提供内容方案和文件方案。缺少内容方案,gmail将完全忽略您的过滤器,这似乎是一个错误。没有文件方案,gmail将会抛出一个错误,说它不知道从意图中启动哪个应用程序。

07-19 15:38:19.160: ERROR/Gmail(2220): Coun't find Activity for intent

在两种方案都存在的情况下,应用程序会接收到已下载和预览文件的意图。它们需要以不同的方式处理。


我刚刚测试了一下,它适用于运行在Android 4.0.3上的Gmail 4.1.2。但是当我使用运行在Android 2.3.6上的Gmail 2.3.6打开同一封电子邮件时,我甚至没有打开附件的选项。 - Frank Harper
已在 Android 4.2 上测试通过 Gmail 4.2.1 版本,运行良好。谢谢。 - Medo
3
在测试时,请确保您还尝试打开一个带有不同扩展名的附件,该扩展名尚未与任何应用程序关联。您会发现,您的“intent-filter”也将匹配它。我认为原因是您没有“host”属性,没有该属性,“pathPattern”将被忽略(developer.android.com/guide/topics/manifest/data-element.html)。如果您添加“android:host =”*“”,那么您的“intent-filter”将突然不再匹配。问题似乎在于“content://” URI 不包含文件名(developer.android.com/reference/android/content/ContentUris.html)。 - adam-p

0

编辑:这个答案已经有3年了。我没有时间测试其他的答案,但我的显然已经过时,请查看本主题的其他答案!

我没有找到任何解决方案,唯一的方法是使用mime-type,所以你必须祈祷你的附件能被识别为已知的mime-type,并处理它。这意味着如果您的文件被识别为html,您将会干扰其他应用程序。

您需要处理一个文件无法被您的应用程序读取的情况,并显示一个弹出窗口通知用户您无法读取该文件。

也许再过一两年,Gmail 就会提供一个很好的 API ...

顺便说一下,最新版本的 Gmail 添加了一个下载按钮,您必须处理它以避免崩溃,它通过创建一个带有 URI 的新文件来工作。


0

您仍然可以为Gmail匹配扩展名

<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/*" host="*" android:pathPattern=".*\\.mht" android:scheme="content" />
</intent-filter>

将MIME类型更改为/,它只会匹配扩展名。


抱歉,我之前没有看到你的回答,如果它有效,我会尽快尝试并编辑我的回答。 - NitroG42
抱歉,但它不起作用,Gmail只使用mime类型进行意图。 - NitroG42
可以正常工作。我有下载和预览按钮。在一部原装的Galaxy S手机和一台Galaxy S II平板电脑上进行了测试。 - Authman Apatira

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