特定文件扩展名的Android意图过滤器?

Posted

技术标签:

【中文标题】特定文件扩展名的Android意图过滤器?【英文标题】:Android intent filter for a particular file extension? 【发布时间】:2010-12-16 12:48:22 【问题描述】:

我希望能够从 'net 下载具有特定扩展名的文件,并将其传递给我的应用程序来处理它,但我无法弄清楚意图过滤器。文件类型不包含在 mimetypes 中,我尝试使用

<data android:path="*.ext" />

但我无法让它工作。

【问题讨论】:

【参考方案1】:

阅读本文 https://developer.android.com/training/sharing/receive ,这可能有助于开始。 然后在清单文件中在要打开的活动中注册接收器时尝试以下意图过滤器

<intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="content"/>
            <category android:name="android.intent.category.BROWSABLE"/>
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="application/your_extension" />
</intent-filter>

确保提供的扩展名不带“.”在里面

【讨论】:

【参考方案2】:

这是我在 AndroidManifest.xml 中定义我的活动以使其工作的方式。

<activity android:name="com.keepassdroid.PasswordActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="file" />
        <data android:mimeType="*/*" />
        <data android:pathPattern=".*\\.kdb" />
        <data android:host="*" />
    </intent-filter>
</activity>

filescheme 表示这应该在打开本地文件时发生(而不是像 HTTP 这样的协议)。

mimeType 可以设置为 */* 以匹配任何 mime 类型。

pathPattern 是您指定要匹配的扩展名的位置(在此示例中为 .kdb)。开头的.* 匹配任何字符序列。这些字符串需要双重转义,因此\\\\. 匹配文字句点。然后,以文件扩展名结束。 pathPattern 的一个警告是 .* 不是一个贪婪的匹配,就像你期望的那样,如果这是一个正则表达式。此模式将无法匹配在 .kdb 之前包含 . 的路径。有关此问题的更详细讨论和解决方法,请参阅here

最后,根据 Android 文档,hostscheme 属性都需要pathPattern 属性才能工作,因此只需将其设置为通配符以匹配任何内容。

现在,如果您在 Linda 文件管理器等应用程序中选择 .kdb 文件,我的应用程序会显示为一个选项。我应该注意,仅此一项并不允许您在浏览器中下载此文件类型,因为这仅在文件方案中注册。在您的手机上拥有像 Linda File Manager 这样的应用程序本身通常允许您下载任何文件类型。

【讨论】:

这在这里不起作用。首先使用 mimeType="",包没有安装在 Android 2.1 上,我得到一个 MalformedMimeTypeException。使用“*/”可以解决这个问题,但是,这个过滤器没有效果。我目前正在使用 Skyfire 浏览器进行测试,它不像标准的 Android 浏览器那样保留 mime 类型的下载。当点击 Skyfire 下载列表中的文件时,会广播一个简单的 VIEW 意图和文件数据。而且这个意图过滤器不匹配。 @Brian Pellin:当我被指向这篇文章时,我实际上正在寻找一种将 mime 类型绑定到 .kdbx 扩展名的方法,以允许 ES 文件资源管理器打开 kdbx 文件。显然,如果意图的 MIME 类型为空,则此意图过滤器将不起作用!!此外,可以有一个带有 EMPTY 字符串作为操作的意图,而只是一个 URI。 Google Docs 响应了该意图,因此它必须是有效的。 明确一点,mimeType 应该是 "*/*" 我想有些人忘记转义他们的 *s 这不适用于 Android 4。您应该在具有四个属性的 &lt;data&gt; 标记上使用。有 4 个标签是逻辑 OR——这适用于 Android 2——但 Android 4 更严格。见***.com/questions/20650378/… 如果\\\\. 匹配一个文字句点,为什么不使用它来形成.kdb 扩展名:\\\\.kdb【参考方案3】:

关于这个主题有很多错误信息,尤其是来自 Google 自己的文档。最好的,考虑到奇怪的逻辑,可能唯一真正的文档是源代码。

intent filter implementation 的逻辑几乎无法描述。 parser code 是另一个相关的难题。

以下过滤器非常接近合理的行为。路径模式确实适用于"file" 方案意图。

只要文件扩展名匹配,全局 mime 类型模式匹配就会匹配所有类型。这并不完美,但它是匹配 ES 文件资源管理器等文件管理器行为的唯一方法,并且仅限于 URI/文件扩展名匹配的意图。

我没有在此处包含像 "http" 这样的其他方案,但它们可能在所有这些过滤器上都可以正常工作。

奇怪的方案是"content",它的扩展名对过滤器不可用。但只要提供商声明了您的 MIME 类型(例如,Gmail 将不受阻碍地传递附件的 MIME 类型),过滤器就会匹配。

需要注意的问题:

    请注意,过滤器中没有任何行为一致,这是一个特殊情况的迷宫,并将违反最小意外原则作为设计目标。没有一个模式匹配算法遵循相同的语法或行为。缺少字段有时是通配符,有时不是。数据元素中的属性有时必须放在一起,有时会忽略分组。真的可以做得更好。 必须指定 schemehost 才能匹配 path 规则(目前与 Google 的 API 指南相反)。 至少 ES File Explorer 会生成 MIME 类型为 "" 的 Intent,其过滤方式与 null 非常不同,无法显式匹配,只能通过有风险的 "*/*" 过滤器匹配。李> "*/*" 过滤器不会匹配具有 null MIME 类型的 Intent - 这需要针对这种特定情况使用单独的过滤器,而根本没有 MIME 类型。 "content" 方案只能通过 MIME 类型匹配,因为原始文件名在意图中不可用(至少在 Gmail 中)。 单独的"data" 元素中的属性分组(几乎)与解释无关,除了hostport 的特定例外 - 它们确实配对在一起。其他所有内容在 "data" 元素内或 "data" 元素之间没有特定关联。

考虑到这一切,下面是一个 cmets 示例:

<!--
     Capture content by MIME type, which is how Gmail broadcasts
     attachment open requests.  pathPattern and file extensions
     are ignored, so the MIME type *MUST* be explicit, otherwise
     we will match absolutely every file opened.
-->
<intent-filter
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:priority="50" >
    <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" />
    <data android:scheme="content" />
    <data android:mimeType="application/vnd.my-type" />
</intent-filter>

<!--
     Capture file open requests (pathPattern is honoured) where no
     MIME type is provided in the Intent.  An Intent with a null
     MIME type will never be matched by a filter with a set MIME
     type, so we need a second intent-filter if we wish to also
     match files with this extension and a non-null MIME type
     (even if it is non-null but zero length).
-->
<intent-filter
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:priority="50" >
    <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" />
    <data android:host="*" />

    <!--
         Work around Android's ugly primitive PatternMatcher
         implementation that can't cope with finding a . early in
         the path unless it's explicitly matched.
    -->
    <data android:pathPattern=".*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
</intent-filter>

<!--
     Capture file open requests (pathPattern is honoured) where a
     (possibly blank) MIME type is provided in the Intent.  This
     filter may only be necessary for supporting ES File Explorer,
     which has the probably buggy behaviour of using an Intent
     with a MIME type that is set but zero-length.  It's
     impossible to match such a type except by using a global
     wildcard.
-->
<intent-filter
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:priority="50" >
    <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" />
    <data android:host="*" />
    <data android:mimeType="*/*" />

    <!--
         Work around Android's ugly primitive PatternMatcher
         implementation that can't cope with finding a . early in
         the path unless it's explicitly matched.
    -->
    <data android:pathPattern=".*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
</intent-filter>

【讨论】:

很高兴您能经受住对 \\.. 一遍又一遍和其他怪癖的许多明显需求。谷歌应该在 4.2 之前解决这个问题,到底是什么。唉,我仍然有您的示例似乎无法解决的情况。像“.gblorb”这样的 6 个 cha 扩展名是否存在一些问题,我的代码在 3 个字母或更少的情况下可以正常工作? 我认为这个问题和类似问题的最佳答案!可悲的是,只要不可能通过文件扩展名匹配内容意图(正如您在 5. 中指出的那样),就不可能在不匹配错误意图的情况下可靠地过滤所有正确的意图。这是针对您无法使用自定义 mime 类型的情况。因此,只要 Android 不为此提供解决方案,它就会成为应用程序中的文件选择器……我不想让用户对不一致的行为感到困惑。 非常感谢.. 你让我很开心.. 在我的情况下,我不得不在所有三个选项中将 MimeType 更改为 &lt;data android:mimeType="*/*" /&gt;,它对包括 Google Drive 和 Gmail 在内的所有应用程序都很有效。 非常感谢@David Sainty。你结束了我 24 小时试图弄清楚如何处理它的痛苦。我试过 ***.com/q/18577860/6110285 , ***.com/a/8599921/6110285 和更多类似的。这是唯一一个有效的。 很遗憾,无法使用“内容”方案过滤文件扩展名。它使问题在现代 Android 版本上无法解决(当您无法期望正确的 mime 类型时)。【参考方案4】:

2020 年更新

Android 已向意图过滤器的内容 URI 和 MIME-Type 发展。

问题

内容 URI 不一定必须包含文件的扩展名或名称,并且在提供内容/文件的不同应用程序之间会有所不同。

以下是来自不同电子邮件应用程序的一些示例内容 URI,用于相同电子邮件附件:

Gmail -> content://com.google.android.gm.sapi/some_email@gmail.com/message_attachment_external/%23thread-a%3Ar332738858767305663/%23msg-a%3Ar-5439466788231005876/0.1?account_type=com.google&amp;mimeType=application%2Foctet-stream&amp;rendition=1

展望 -> content://com.microsoft.office.outlook.fileprovider/outlookfile/data/data/com.microsoft.office.outlook/cache/file-download/file--2146063402/filename.customextention

三星电子邮件应用程序 -> content://com.samsung.android.email.attachmentprovider/1/1/RAW

正如所见,它们都是不同的,并且不保证包含与您的实际文件相关的任何内容。因此,您不能像大多数人建议的那样使用android:pathPattern

电子邮件附件的解决方案

<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="content"/>
    <data android:host="*"/>

    <!--  Required for Gmail and Samsung Email App  -->
    <data android:mimeType="application/octet-stream"/>

    <!--  Required for Outlook  -->
    <data android:mimeType="application/my-custom-extension"/>
</intent-filter>

通过测试,我发现了 Gmail、Outlook 和三星电子邮件使用的 MIME 类型,并将它们添加到我的意图过滤器中。

注意事项/注意事项

我发现通过上述解决方案,如果我打开任何二进制类型的文件,它会自动启动我的应用程序。如果我们无法解析文件,我会在我的活动中通过显示失败状态来处理此问题。我认为这是一个非常罕见的事件,因此可以接受。

如果不将&lt;data android:mimeType="*/*"/&gt; 添加到我的意图过滤器,我找不到任何方法来通过文件浏览器启动我的应用程序。我不能使用它,因为它会在用户点击他们手机上的 any 文件(不仅仅是自定义文件扩展文件)时启动我的应用程序。我不建议将其添加到您的意图过滤器中。

最后的想法

目前没有优雅的解决方案可以将您的应用与 Android 中的特定扩展类型相关联。这是我在我的情况下能做的最好的事情。

【讨论】:

非常感谢,它可以工作,于 2020 年 10 月测试,来自 android 7 我不明白这么简单的功能在Android上是不可能做到的。【参考方案5】:

当 Intent 满足 intent-filter 时,这些是 intent-filter 要求:(想象一个清单)。

任何匹配的&lt;action&gt; 任何匹配的&lt;category&gt; 任何匹配的&lt;data mimeType&gt;(简单修复:“/”)

可选:

任何匹配的&lt;data scheme&gt;(简单修复:&lt;data android:scheme="file" /&gt; &lt;data android:scheme="content" /&gt;

任何匹配的&lt;data host&gt;(简单修复:“*”)

任何匹配的&lt;data pathPattern/etc.&gt;(例如.*\\.0cc

定义多个&lt;data $type=""&gt; 元素会检查$type 框,如果任何&lt;data $type=&gt; 匹配Intent

省略 mimeType 会破坏您的 intent-filter,即使它看似多余。省略 &lt;data scheme/host/pathPattern&gt; 会使您的过滤器匹配所有内容。

https://f-droid.org/en/packages/de.k3b.android.intentintercept/ 是一款旨在接收所有意图的应用,并允许您检查意图。我了解到通过简单文件管理器打开的无法识别的文件扩展名是使用 MIME 类型application/octet-stream 提供的。

https://***.com/a/4621284/2683842 报告&lt;data pathPattern=&gt; .*xyz 在它看到的第一个x 处中止,如果后面没有yz,将立即失败。所以/sdcard/.hidden/foo.0cc 不会通过.*\\.0cc,除非你改用.*\\..*\\.0cc

我没有验证此解决方法是否必要。

最终结果:

<activity android:name=".Ft2NsfActivity">

    <intent-filter>
        <action android:name="android.intent.action.VIEW" />

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

        <data android:scheme="file" />
        <data android:scheme="content" />
        <data android:host="*" />
        <data android:pathPattern=".*\\.ftm"/>
        <data android:pathPattern=".*\\..*\\.ftm"/>
        <data android:pathPattern=".*\\..*\\..*\\.ftm"/>
        <data android:pathPattern=".*\\..*\\..*\\..*\\.ftm"/>
        <data android:pathPattern=".*\\.0cc"/>
        <data android:pathPattern=".*\\..*\\.0cc"/>
        <data android:pathPattern=".*\\..*\\..*\\.0cc"/>
        <data android:pathPattern=".*\\..*\\..*\\..*\\.0cc"/>
        <data android:mimeType="*/*" />
    </intent-filter>

</activity>

【讨论】:

【参考方案6】:

多年来,我一直试图让它工作,并且基本上尝试了所有建议的解决方案,但仍然无法让 Android 识别特定的文件扩展名。我有一个带有"*/*" mimetype 的意图过滤器,这似乎是唯一有效的东西,文件浏览器现在将我的应用程序列为打开文件的选项,但是我的应用程序现在显示为打开任何类型的选项即使我已经使用 pathPattern 标记指定了特定的文件扩展名,文件也是如此。到目前为止,即使我尝试查看/编辑联系人列表中的联系人,Android 也会询问我是否要使用我的应用程序来查看联系人,而这只是发生这种情况的众多情况之一,非常非常烦人。

最终我发现这个 google 群组帖子有一个类似的问题,一位实际的 Android 框架工程师回答了这个问题。她解释说,android 对文件扩展一无所知,只知道 MIME 类型 (https://groups.google.com/forum/#!topic/android-developers/a7qsSl3vQq0)。

所以从我所见、尝试和阅读的情况来看,Android 根本无法区分文件扩展名,而 pathPattern 标签基本上是对时间和精力的巨大浪费。如果您有幸只需要某种 mime 类型的文件(例如文本、视频或音频),则可以使用具有 mime 类型的意图过滤器。如果您需要特定的文件扩展名或 Android 不知道的 MIME 类型,那么您就不走运了。

如果我在这方面有任何错误,请告诉我,到目前为止,我已经阅读了所有帖子并尝试了我能找到的所有建议的解决方案,但都没有奏效。

我可以再写一两页来说明这类事情在 Android 中的普遍性以及开发人员体验的糟糕程度,但我会为您省去我愤怒的咆哮;)。希望我为某人省去了一些麻烦。

【讨论】:

赞成你,因为你的回答提供了一个有用的链接,而反对者没有发表评论。抱歉,有时那样会不友好,但不要就此放弃。【参考方案7】:

对于 VIEW 或 SEND 操作,如果后缀未在 Android 的 system=wide MIME 数据库中注册为 MIME 类型,上述方法均不能正常工作。我发现指定后缀的唯一设置包括android:mimeType="*/*",但随后该操作会针对所有文件触发。显然不是你想要的!

如果不将 mime 和后缀添加到 Android mime 数据库,我找不到任何合适的解决方案,到目前为止,我还没有找到解决方法。如果有人知道,指针会很棒。

【讨论】:

【参考方案8】:

上面布莱恩的回答让我成功了 90%。为了完成它,对于我使用的 mime 类型

android:mimeType="*/*"

我怀疑以前的发帖者试图发布相同的细节,但是尽管引用了斜杠星号作为代码,*** 将其显示为一个斜杠。

【讨论】:

有了这个,你将处理所有文件类型,这真的很烦人(好吧,除非你的应用确实处理了所有事情)...... 这很糟糕。请不要在您的应用中执行此操作。【参考方案9】:

我必须承认,在 Android 上打开电子邮件附件和文件系统文件的简单任务是有史以来最令人抓狂的体验之一。处理太多或太少的文件很容易。但要做到恰到好处是很难的。 *** 上发布的大多数解决方案对我来说都无法正常工作。

我的要求是:

让我的应用处理我的应用共享的附件 让我的应用处理文件存储中由我的应用生成并具有特定扩展名的文件

执行此任务的最佳方法可能是为您的附件指定自定义 MIME 类型。您可能还会选择自定义文件扩展名。因此,假设我们的应用名为“Cool App”,我们生成的文件附件以“.cool”结尾。

这是我最接近目标的一次,而且效果很好……令人满意。

<!-- Register to handle email attachments -->
<!-- WARNING: Do NOT use android:host="*" for these as they will not work properly -->
<intent-filter>
    <!-- needed for properly formatted email messages -->
    <data
        android:scheme="content"
        android:mimeType="application/vnd.coolapp"
        android:pathPattern=".*\\.cool" />
    <!-- needed for mangled email messages -->
    <data
        android:scheme="content"
        android:mimeType="application/coolapp"
        android:pathPattern=".*\\.cool" />
    <!-- needed for mangled email messages -->
    <data
        android:scheme="content"
        android:mimeType="application/octet-stream"
        android:pathPattern=".*\\.cool" />

    <action android:name="android.intent.action.VIEW" />

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

<!-- Register to handle file opening -->
<intent-filter>
    <data android:scheme="file"
          android:mimeType="*/*"
          android:pathPattern=".*\\.cool"
          android:host="*"/>

    <action android:name="android.intent.action.VIEW" />

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

注意事项:

pathPattern 似乎或多或少地被附件忽略(使用android:scheme="content" 时)。如果有人让 pathPattern 只响应某些模式,我会很高兴看到如何。 如果我添加了android:host="*" 属性,Gmail 应用拒绝在选择器中列出我的应用。 如果合并这些 intent-filter 块,它可能仍然有效,但我尚未验证这一点。 要在下载文件时处理来自浏览器的请求,可以使用android:scheme="http"。请注意,某些浏览器可能会弄乱android:mimeType,因此请尝试使用android:mimeType="*/*" 并在调试器中检查实际通过的内容,然后加强过滤,以免最终成为处理所有事情的烦人应用程序. 某些文件资源管理器也会弄乱文件的 MIME 类型。以上intent-filter 已在 Galaxy S3 上使用三星的“我的文件”应用程序进行了测试。 FX Explorer 仍然拒绝正确打开文件,我还注意到应用程序图标未用于文件。同样,如果有人让它工作,请在下面发表评论。

我希望您会发现这很有用,并且您不必浪费时间来研究所有可能的组合。有改进的余地,所以欢迎 cmets。

【讨论】:

这对我来说是一个可行的解决方案。为 Content-Scheme 和 File-Scheme 注册一个单独的 就可以了!谢谢! 谢谢!为我工作。 Galaxy S6 上的 Gmail 应用程序和三星我的文件应用程序都能够使用您的解决方案使用我的应用程序打开文件! “应用名称”到底是什么? (在我的例子中,人类可读的应用名称中有空格。) @WilliamJockusch 看起来@DavidSainty 只是将应用程序名称存储在字符串资源文件中。空格应该没问题。用于意图过滤器的android:label 的字符串是用户将在选择器菜单中看到的字符串。默认情况下使用应用程序名称。 我应该为“Google Drive”应用程序使用什么?【参考方案10】:

使用以下过滤器从浏览器、gmail 和文件浏览器打开(已测试)。 注意:请不要合并两个过滤器,这会使浏览器忽略您的应用程序(已测试)。

        <intent-filter>
            <action android:name="android.intent.action.VIEW"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.BROWSABLE"/>

            <data android:scheme="file" android:pathPattern=".*\\.ext" android:mimeType="application/*"/>
            <data android:scheme="content" android:pathPattern=".*\\.ext" android:mimeType="application/*"/>
        </intent-filter>

        <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>
            <data android:scheme="http"
                  android:host="*"
                  android:pathPattern=".*\\.ext" />
            <data android:scheme="https"
                  android:host="*"
                  android:pathPattern=".*\\.ext" />
            <data android:scheme="ftp"
                  android:host="*"
                  android:pathPattern=".*\\.ext" />

        </intent-filter>

【讨论】:

你用 Gmail 附件测试过这个答案吗?【参考方案11】:

我自己一直在为自定义文件扩展名而苦苦挣扎。经过大量搜索,我找到了this web page,当您的路径在路径中的其他位置包含匹配模式的第一个字符时,发布者发现 Android 的 patternMatcher 类(用于 Intent-Filters 中的 pathPattern 匹配)具有意外行为(例如,如果您尝试匹配“*.xyz”,则如果您的路径中前面有一个“x”,则 patternMatcher 类将停止)。这是他找到的解决方法,并为我工作,虽然它有点像黑客:

PatternMatcher 用于 IntentFilter 的 pathPattern 但是, PatternMatcher 的算法对我来说很奇怪。这是算法 Android PatternMatcher。

如果字符串中间有“.*”模式的“下一个字符”, PatternMatcher 在该点停止循环。 (参见 PatternMatcher.java 的 Android 框架。)

例如。字符串:“这是我的附件”模式:“.att.”。安卓 PatternMatcher 进入循环匹配 '.' 模式直到遇到下一个 模式的字符(在这个例子中,'a')所以,'.' 匹配循环 停在索引 8 - 'is' 和 'my' 之间的 'a'。因此这个结果 匹配返回“假”。

很奇怪,不是吗。要解决这个问题 - 实际上减少 可能性 - 开发人员应该使用烦人的愚蠢 pathPattern。

例如。目标:匹配包含“消息”的uri路径。

<intent-filter>
...
<data android:pathPattern=".*message.*" />
<data android:pathPattern=".*m.*message.*" />
<data android:pathPattern=".*m.*m.*message.*" />
<data android:pathPattern=".*m.*m.*m.*message.*" />
<data android:pathPattern=".*m.*m.*m.*m.*message.*" />
...
</intent-filter>

在与自定义文件扩展名匹配时尤其会发出此问题。

【讨论】:

对于任何感兴趣的人,一个问题已记录在code.google.com【参考方案12】:

如果您希望直接从 Gmail、Dropbox 或任何内置 android 文件工具打开文件,请使用以下代码(删除 'android:host="*"' 使文件无法被 gmail 访问):

<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="content" android:pathPattern=".*\\.kdb" 
          android:mimeType="application/octet-stream"/>


</intent-filter>

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="file" android:mimeType="*/*"     
          android:pathPattern=".*\\.kdb"/>
</intent-filter>

数据过滤器必须按照 Android 4.x 版本写在一个语句中

【讨论】:

我一直在尝试一切,试图让 android 浏览器下载和打开正常工作。您的解决方案适用于 android 本机浏览器和 android chrome,但是 android firefox 似乎仍然在文本窗口中打开我的文件。它是一种自定义 mime 类型和自定义扩展。以前只有扩展,它只在 Firefox 中工作。现在它可以在除 Firefox(包括 gmail)之外的任何地方使用。我仍在测试它,但我只想指出这里存在一组新的跨浏览器问题。【参考方案13】:

在 Android 4 上,规则变得比以前更加严格。使用:

    <data
      android:host=""
      android:mimeType="*/*"
      android:pathPattern=".*\\.ext"
      android:scheme="file"
    ></data>

【讨论】:

【参考方案14】:

Brian 的回答非常接近,但在尝试使用您自己的自定义扩展名(不需要方案或主机)打开文件时,这是一种干净且无错误的方法来调用您的应用程序:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:mimeType="*/*" />
    <data android:pathPattern="*.*\\.kdb" />
</intent-filter>

【讨论】:

Android 文档指出 pathPattern 属性仅在指定方案和主机时才有意义,并且我已经验证了这一点:developer.android.com/guide/topics/manifest/data-element.html -1;这将匹配 any 文件; Brian 的评论是正确的,并且对 mimeType="/" 进行了细微修改,他的原始示例非常完美。 这个帖子如果是很久以前的,但是没有“/”不安装。您需要“*/*”,它将匹配任何文件类型(不确定,如果您要这么说的话)。因此,您的程序可能会被要求打开视频或 mp3。我还没有找到解决办法。 您应该使用一个具有四个属性的&lt;data&gt; 标签。您的解决方案可能适用于 Android 2 — 但规则变得更加严格:***.com/questions/20650378/… 奇怪的 pathPattern 是怎么回事?并且hostscheme 是必需的!【参考方案15】:

而不是android:path,请尝试android:mimeType,其值为该特定内容的MIME 类型。此外,android:path 不接受通配符 - 为此使用 android:pathPattern

【讨论】:

“文件类型不包含在 mimetypes 中”?您正在下载的内容类型仍然应该有一个 mimetype,即使它不使用相同的词。 内容类型有一个 mimetype,但该文件是由第三方应用程序生成的,该应用程序在其上添加了不同的扩展名,因此我认为它不会被识别为该 mimetype。

以上是关于特定文件扩展名的Android意图过滤器?的主要内容,如果未能解决你的问题,请参考以下文章

打开电子邮件附件时如何获取文件名和扩展名

正确的 Android 意图过滤器配置以将文件类型与 Activity 关联?

如何在android中使用意图过滤器获取数据

如何使用 subString() 在 Android 中的特定文件夹中找到文件的扩展名 [重复]

在原生 Android 文件选择器中按 mime 类型或扩展名过滤

扩展 Android 的默认 Gmail/电子邮件应用程序