我有 2 个自定义文件扩展名 *.abc
和 *.xyz
。
我已经为 Activity 编写了 Intent 过滤器,其中具有*.abc
扩展名的文件应在Activity1
和*.xyz中打开
应该在 Activity2
这些文件具有序列化java对象而不是纯文本文件。
这些是 AndroidManifest.xml 中这些 Activity 的 Intent 过滤器
<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 系统中注册这些扩展,并且我的应用程序 Activity 显示在 Android 系统 UI 的应用程序选择器中
我正在 logcat 中打印 URI 信息,如下
Timber.i(uri.toString())
val mimeType = contentResolver.getType(uri)
Timber.i(mimeType)
从 WhatsApp 打开文件时的 Logcat
content://com.whatsapp.provider.media/item/5237
application/octet-stream
从 Solid Explorer 打开文件时的 Logcat
content://pl.solidexplorer2.files/storage/emulated/0/Download/File1.abc
application/*
但是当点击任一文件(自定义扩展)时,它会将两个 Activity 显示为可打开的 Intent , 例如。如果单击文件 file1.abc,它将扩展的两个 Intent 过滤器显示为Activity1 和 Activity2
我想让这些扩展程序针对特定 Activity 就像如果点击扩展名为 *.abc 的文件,它在 Android 系统 UI 的 Intent Chooser 中应该只有 Activity1
我尝试了其他答案中解释的几种方法,但那些不似乎对于具有内容类型URI的两种文件格式都能正常工作
某些解决方案仅在从 Solid Explorer 等文件浏览器打开文件时有效,但在从 WhatsApp 等使用 MIME 类型作为媒体的应用程序打开时无效
下面的 Intent 过滤器可以与 Solid Explorer 正确配合使用。 它根据自定义文件扩展名过滤 Activity 。但相同的 Intent Filter 不适用于 Android 系统的选择器对话框,因为它不适用于使用 Android 系统的 Intent Chooser 的 WhatsApp 或 Gmail 等应用
<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>
任何帮助将不胜感激。 谢谢。
最佳答案
通过对每个 Activity 使用 Intent 过滤器没有直接解决此问题的方法,因此我创建了接受以下 Intent 过滤器的 FileIntentActivity
<intent-filter
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
此FileIntentActivity用于接受任何文件格式,然后根据使用引用的游标从内容URI转换的文件扩展名来决定进一步的操作this answer
fun getFileName(uri: Uri): String {
lateinit var cursor: Cursor
lateinit var result: String
try {
cursor = appContext.contentResolver.query(uri, null, null, null, null)
if(cursor!=null && cursor.moveToFirst()){
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME))
}
return result
} finally {
cursor.close()
}
}
private fun getFileType(fileName: String): FileType {
return when (fileExtension) {
FileFormats.ABC_FILE_FORMAT -> FileType.ABC
FileFormats.XYZ_FILE_FORMAT -> FileType.XYZ
else -> FileType.UNKNOWN
}
}
并根据FileType打开Activity1或Activity2
private fun openActivityByType(fileType: FileType) {
when (fileType) {
FileType.ABC -> startActivity1()
FileType.XYZ -> startActivity2()
FileType.UNKNOWN -> showFileUnsupportedMessage()
}
}
这种方法至少可以让用户交互不那么困惑,因为它仅在 Android 的 Intent Chooser 中显示 1 个文件 Intent Activity ,而不是单个应用程序的多个 Activity 。
关于android - 针对特定 Activity 的文件扩展名 Intent 过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48367934/