我有2个自定义文件扩展名*.abc
和*.xyz
。
我已经为*.abc
中应该打开Activity1
扩展名的文件的活动写了 Intent过滤器,而*.xyz
应该Activity2
具有序列化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系统用户界面的应用程序选择器中
我在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/*
但是当点击任一文件(自定义扩展名)时,它会将两个活动显示为可打开的意图, 例如。如果点击文件file1.abc,显示两个扩展名的Intent Filters 为 Activity1和Activity2
我想制作扩展活动特定 就像点击带有扩展名* .abc的文件一样,它应该只有Android系统UI的Intent Chooser中的Activity1
我尝试了其他答案中解释的几种方法,但那些不似乎适用于内容类型URI
的文件格式某些解决方案仅在从 Solid Explorer 等文件浏览器打开文件时起作用,但在使用 MIME 类型作为媒体的WhatsApp等应用程序打开时无法正常工作
下面的Intent过滤器正确使用 Solid Explorer 。 它是基于自定义文件扩展名的过滤活动。但是同样的Intent Filter不适用于Android System的Chooser对话框,因为它在使用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>
任何帮助将不胜感激。 感谢。
答案 0 :(得分:0)
通过对每个Activity使用Intent Filters没有直接解决此问题的方法,因此我创建了 FileIntentActivity ,它接受以下Intent Filter
<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 或 Activity2private fun openActivityByType(fileType: FileType) {
when (fileType) {
FileType.ABC -> startActivity1()
FileType.XYZ -> startActivity2()
FileType.UNKNOWN -> showFileUnsupportedMessage()
}
}
这种方法通过在Android的Intent Chooser中仅显示1个文件意图活动而不是单个应用的多个活动,至少使用户交互不那么混乱。