针对特定活动的文件扩展名的意图过滤器

时间:2018-01-21 14:34:37

标签: android android-intent intentfilter

我有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

打开文件时的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/*

但是当点击任一文件(自定义扩展名)时,它会将两个活动显示为可打开的意图, 例如。如果点击文件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>

任何帮助将不胜感激。 感谢。

1 个答案:

答案 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 Activity2
private fun openActivityByType(fileType: FileType) {
    when (fileType) {
        FileType.ABC -> startActivity1()
        FileType.XYZ -> startActivity2()
        FileType.UNKNOWN -> showFileUnsupportedMessage()
    }
}

这种方法通过在Android的Intent Chooser中仅显示1个文件意图活动而不是单个应用的多个活动,至少使用户交互不那么混乱