安卓 Intent 过滤器无法工作

5
我的应用程序可以打开以下文件格式:
  • kml(application/vnd.google-earth.kml+xml)
  • kmz(application/vnd.google-earth.kmz)
  • gpx(application/gpx+xml)
我正在尝试设置正确的意图过滤器,以便当尝试打开这些文件类型时,我的应用程序会被建议,通过以下方案:
  • http
  • https
  • file
  • content
我期望以下过滤器可以捕获所有情况(除了名称中带有点的文件,但那是另一个问题):
<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="http" />
    <data android:scheme="https" />
    <data android:scheme="content" />

    <data android:pathPattern=".*\\.kml" />
    <data android:pathPattern=".*\\.kmz" />
    <data android:pathPattern=".*\\.gpx" />

    <data android:mimeType="application/vnd.google-earth.kml+xml" />
    <data android:mimeType="application/vnd.google-earth.kmz" />
    <data android:mimeType="application/gpx+xml" />

</intent-filter>

但如果文件浏览器未正确设置GPX内容类型,则即使使用“.gpx”扩展名命名,也无法识别GPX文件。 有人知道这个问题是什么吗?

我会将其设置为两个过滤器。一个是文件和扩展名,另一个是其他方案和MIME类型。目前,例如,如果内容具有正确的MIME类型,但路径没有这些扩展名之一(因为它很少对于“内容”),则您的过滤器将不匹配。总体而言,在Android上,文件扩展名是最不可靠的方法。 - CommonsWare
谢谢!我快要完成了,我有一个似乎可以处理所有情况的东西。为什么你要限制这2个过滤器的方案呢?为什么不使用一个过滤器来处理扩展名,另一个过滤器来处理MIME类型,两个过滤器都适用于所有方案呢? - Tim Autin
嗯,对于 httphttps,在我看来 MIME 类型会更加可靠。对于 content,经常是没有文件扩展名的。我倾向于采用较小的范围来减少出错的可能性。但是,如果你想在两个过滤器中应用所有四种方案,那也可能能行。 - CommonsWare
好的,谢谢!不过我会按照我说的去做,我更喜欢应用程序不能打开提供的文件,而不是应用程序不建议打开它可以处理的文件。 - Tim Autin
1个回答

11
所以这就是我最终得出的结果:
<!--Mime type set -->
<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="http" />
    <data android:scheme="https" />
    <data android:scheme="content" />

    <!-- Valid mime types -->
    <data android:mimeType="application/vnd.google-earth.kml+xml" />
    <data android:mimeType="application/vnd.google-earth.kmz" />
    <data android:mimeType="application/gpx+xml" />

    <!-- Invalid mime types used by some bad software -->
    <data android:mimeType="application/kml" />
    <data android:mimeType="application/kmz" />
    <data android:mimeType="application/gpx" />

    <data android:mimeType="application/kml+xml" />
    <data android:mimeType="application/kmz+xml" />

    <data android:mimeType="application/vnd.google-earth.kml" />
    <data android:mimeType="application/vnd.google-earth.gpx" />
    <data android:mimeType="application/vnd.google-earth.kmz+xml" />
    <data android:mimeType="application/vnd.google-earth.gpx+xml" />

    <data android:mimeType="text/kml" />
    <data android:mimeType="text/kmz" />
    <data android:mimeType="text/gpx" />

    <data android:mimeType="text/kml+xml" />
    <data android:mimeType="text/kmz+xml" />
    <data android:mimeType="text/gpx+xml" />

    <data android:mimeType="text/xml+kml" />
    <data android:mimeType="text/xml+kmz" />
    <data android:mimeType="text/xml+gpx" />

</intent-filter>

<!-- Mime type not set but valid extensions -->
<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="http" />
    <data android:scheme="https" />
    <data android:scheme="content" />

    <data android:host="*" />

    <data android:pathPattern="/.*..*..*..*..*\\.gpx" />
    <data android:pathPattern="/.*..*..*..*..*\\.kml" />
    <data android:pathPattern="/.*..*..*..*..*\\.kmz" />
    <data android:pathPattern="/.*..*..*..*\\.gpx" />
    <data android:pathPattern="/.*..*..*..*\\.kml" />
    <data android:pathPattern="/.*..*..*..*\\.kmz" />
    <data android:pathPattern="/.*..*..*\\.gpx" />
    <data android:pathPattern="/.*..*..*\\.kml" />
    <data android:pathPattern="/.*..*..*\\.kmz" />
    <data android:pathPattern="/.*..*\\.gpx" />
    <data android:pathPattern="/.*..*\\.kml" />
    <data android:pathPattern="/.*..*\\.kmz" />
    <data android:pathPattern="/.*\\.gpx" />
    <data android:pathPattern="/.*\\.kml" />
    <data android:pathPattern="/.*\\.kmz" />

</intent-filter>

<!-- Invalid mime type but valid extensions -->
<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="http" />
    <data android:scheme="https" />
    <data android:scheme="content" />

    <data android:host="*" />
    <data android:mimeType="*/*" />

    <data android:pathPattern="/.*..*..*..*..*\\.gpx" />
    <data android:pathPattern="/.*..*..*..*..*\\.kml" />
    <data android:pathPattern="/.*..*..*..*..*\\.kmz" />
    <data android:pathPattern="/.*..*..*..*\\.gpx" />
    <data android:pathPattern="/.*..*..*..*\\.kml" />
    <data android:pathPattern="/.*..*..*..*\\.kmz" />
    <data android:pathPattern="/.*..*..*\\.gpx" />
    <data android:pathPattern="/.*..*..*\\.kml" />
    <data android:pathPattern="/.*..*..*\\.kmz" />
    <data android:pathPattern="/.*..*\\.gpx" />
    <data android:pathPattern="/.*..*\\.kml" />
    <data android:pathPattern="/.*..*\\.kmz" />
    <data android:pathPattern="/.*\\.gpx" />
    <data android:pathPattern="/.*\\.kml" />
    <data android:pathPattern="/.*\\.kmz" />

</intent-filter>

在我测试的所有文件管理器上都似乎可以工作(FX、ES、Astro、File Commander)。

(对于那些想知道奇怪路径模式的人,请参见pathPattern to match file extension does not work if a period exists elsewhere in the file name?


如果我没记错的话,是的,它可以! - Tim Autin
2
这是我在网上找到的唯一一个对我有效的intent-filter示例。谢谢! - Anthony.

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