【发布时间】:2018-06-30 06:41:11
【问题描述】:
我有 2 个自定义文件扩展名 *.abc 和 *.xyz。
我已经为应该在Activity1 中打开具有*.abc 扩展名的文件并且应该在Activity2 中打开*.xyz 的活动编写了意图过滤器
那些具有序列化 java 对象而不是纯文本文件的文件。
这些是 AndroidManifest.xml
中这些活动的意图过滤器<activity
android:name=".ui.Activity1">
<intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.abc" />
</intent-filter>
</activity>
<activity
android:name=".ui.Activity2">
<intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.xyz" />
</intent-filter>
</activity>
我能够在 android 系统中注册这些扩展,并且我的应用程序活动显示在 Android 系统 UI 的应用程序选择器中
我在 logcat 中打印 URI 信息如下
Timber.i(uri.toString())
val mimeType = contentResolver.getType(uri)
Timber.i(mimeType)
从 WhatsApp
打开文件时的 Logcatcontent://com.whatsapp.provider.media/item/5237
application/octet-stream
从 Solid Explorer
打开文件时的 Logcatcontent://pl.solidexplorer2.files/storage/emulated/0/Download/File1.abc
application/*
但是当点击其中一个文件(自定义扩展名)时,它会将两个活动都显示为可打开的 Intent, 例如。如果单击文件 file1.abc,它 将扩展的意图过滤器显示为 Activity1 和 Activity2
我想让这些扩展活动特定 就像如果单击扩展名为 *.abc 的文件,它应该只有 Activity1 在 Android 系统 UI 的 Intent Chooser 中
我尝试了其他答案中解释的几种方法,但那些 不 似乎适用于具有 content type URI
的两种文件格式某些解决方案仅在从 Solid Explorer 等文件浏览器打开文件时有效,但在使用 MIME 类型作为媒体的 WhatsApp 等应用打开时无效
下面的意图过滤器与 Solid Explorer 一起正常工作。 它基于自定义文件扩展名过滤活动。但同样的 Intent Filter 不适用于 Android 系统的选择器对话框,因为它不适用于像 WhatsApp 或 Gmail 这样使用 Android 系统的 Intent 选择器的应用程序
<activity
android:name=".ui.Activity1">
<intent-filter>
<data
android:host="*"
android:mimeType="*/*"
android:pathPattern=".*\\.abc"
android:scheme="content" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
<activity
android:name=".ui.Activity2">
<intent-filter>
<data
android:host="*"
android:mimeType="*/*"
android:pathPattern=".*\\.xyz"
android:scheme="content" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
任何帮助将不胜感激。 谢谢。
【问题讨论】:
-
过滤文件扩展名将越来越没用。
Uri不需要文件扩展名,更不用说有意义的了。停止依赖文件扩展名。 -
@CommonsWare 所以你建议怎么做?如何为特定文件类型注册这些活动?
-
"我如何为特定文件类型注册这些活动?" ——你没有。您不能强迫其他开发人员(更不用说用户)使用您的自定义文件扩展名,甚至是自定义 MIME 类型。恕我直言,您使用 Java 序列化的决定是糟糕。如果您使用 XML 或 JSON,您至少可以依赖一些传统的 MIME 类型。就目前而言,无论您使用推送 (
<intent-filter>) 还是拉取 (ACTION_OPEN_DOCUMENT、ACTION_GET_CONTENT),您都必须满足于请求任何类型的文件,才能获得任何结果。 -
@CommonsWare 实际上我正在开发文本加密应用程序,因此不能像普通的纯文本数据持有者那样直接使用 XML 或 JSON。是的,我需要满足于请求任何类型的文件。难道没有另一种方法来实现这一点,而不依赖于用户每次都在它们之间进行选择
-
就个人而言,在这种情况下,我会使用 pull:
ACTION_OPEN_DOCUMENT,如果您的minSdkVersion低于 19,则加上ACTION_GET_CONTENT。这些对应于您在中看到的“文件打开”对话框其他 GUI 工具包。这至少将情况限制在用户在您的应用程序中并且特别希望将内容加载到其中的位置。使用 accept-everything<intent-filter>意味着你会不断出现在用户可能不想要你的地方,这会增加用户意外选择你的应用的机会。
标签: android android-intent intentfilter