Android应用已分配给任何可能的文件 - 应仅分配给我的自定义文件

时间:2014-01-15 19:34:40

标签: android android-manifest mime-types email-attachments intentfilter

我正在尝试将我的Android应用分配到扩展名为“kka”的自定义文件(json内容)。 我希望能够在以下情况下打开我的应用并阅读* .kka文件: 1. * .kka作为电子邮件附件(gmail客户端) 2. * .kka作为存储在文件系统中的文件,例如下载/文件夹

我的AndroidManifest.xml文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mydomain.kka" >
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.mydomain.kka.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="file" android:pathPattern=".*\\.kka" android:mimeType="*/*"/>
                <data android:scheme="content" android:pathPattern=".*\\.kka" android:mimeType="application/stream-octet"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

这是我发现能够启动我的应用程序的唯一配置,可以将* .kka作为gmail客户端中的附件和文件系统中的文件进行点击。

问题是我的应用程序出现在我想要在文件系统上打开电子邮件附件或文件的每个可能的位置,无论它是什么类型的文件,因此我的KKATest应用程序位于已分配的应用程序列表中,例如XML,PDF,甚至APK等。 它似乎忽略了我在AndroidManifest文件中明确提到的文件扩展名。

这种情况发生在Android 4.4的Galaxy Nexus,Android 4.3的Galaxy S4等等。

我已经阅读了很多关于StackOverflow的建议,但没有人解决我的问题。我的清单文件出了什么问题?

3 个答案:

答案 0 :(得分:2)

我正在努力解决同样的问题。我需要从SD卡和电子邮件附件中打开我的文件。对我而言,这也是一种追踪和错误,但这是我的解决方案:

<intent-filter> <!-- Intent filter for opening files from system -->
            <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:host="*" />
            <data android:mimeType="*/*" />
            <data android:pathPattern=".*\\.locx" />
        </intent-filter>
        <intent-filter> <!-- Intent filter for open files from email -->
            <data android:scheme="content" />

            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />

            <data android:mimeType="application/octet-stream" />
            <data android:pathPattern=".*\\.locx" />
        </intent-filter>

locx显然是我的文件类型。 顺便说一句:我只使用Gmail应用程序进行测试,从其他论坛帖子中我了解到其他电子邮件应用可能会有所不同。

答案 1 :(得分:2)

实际上,正如您所指出的,某些电子邮件客户端会将mime类型替换为application / octed-stream。所以我最终使用了这样的意图过滤器:

<!-- Filters for handling local files -->
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.EDIT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="*/*" android:scheme="file" android:pathPattern=".*\\.mtype" android:host="*"/>
            </intent-filter>

<!-- Filter for email apps -->
        <intent-filter>
            <action android:name="android.intent.action.VIEW"></action>
            <category android:name="android.intent.category.DEFAULT"></category>
            <category android:name="android.intent.category.BROWSABLE"></category>
            <data android:scheme="content"/>
            <data android:mimeType="application/octet-stream"/>
            <data android:mimeType="application/mtype"/>
        </intent-filter>

这将使您的应用程序同时处理mtype和octet-stream。但在八位字节流的情况下,它可能实际上不是您的文件,因此您需要在应用程序中进行一些检查。这意味着获取文件名,并检查扩展名。为此,您可以通过意图使用在应用程序中处理的uri来查询内容提供者:

Cursor cursor = mContext.getContentResolver().query(data, null, null, null, null);
int fileNameColumnIndex = cursor.getColumnIndex("_display_name");         
if (fileNameColumnIndex != -1) {
    String fileName = cursor.getString(fileNameColumnIndex);
}

现在,有几种情况: 如果您使用了gmail客户端,那么&#34; _display_name&#34;存在; 如果您单击该文件,则在Downloader本机应用程序中,&#34; _display_name&#34;存在; 如果您使用本机电子邮件客户端,则不存在;在这种情况下,我提示用户先下载文件。如果他这样做,然后再次在电子邮件客户端中打开文件,它将实际打开该文件,它将由第一个intent-filter处理。

答案 2 :(得分:0)

我找到了一个解决方案(差不多),解决方案看起来像这样:

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mydomain.kka" >
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.mydomain.kka.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:host="*" android:mimeType="*/*" android:pathPattern=".*\.kka" android:scheme="file" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="application/custom-kka" android:scheme="content" />
            </intent-filter>
        </activity>
    </application>
</manifest>

我不知道为什么带有一个反斜杠(“\”)而不是两个(“\\”)的条目<data android:host="*" android:mimeType="*/*" android:pathPattern=".*\.kka" android:scheme="file" />解决了从文件系统打开所有可能文件的问题 - 现在我的应用程序仅打开* .kka文件......

打开附加到邮件的文件需要通过分配mime-type而不是文件扩展名来处理。我创建了自定义mime-type "application/custom-kka"并确保在使用该文件发送邮件时需要设置我的自定义mime-type以进行附件。

为此,我在电子邮件编写器代码中添加了一段代码:

...
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("application/custom-kka");
...

这应该保证我的附件适当的mime类型。不幸的是,少数设备上的android邮件客户端(gmail,通用邮件客户端)发送的邮件与我的mime类型不同,例如, "application/octet-stream;""<nothing here>;"但不希望"application/custom-kka;"我的应用无法识别分配给它的附件。

那是PhoneGap应用程序,所以我也有iOS版本,其中发送带有自定义mime类型的邮件完美无缺,Android应用程序可以识别附件。

也许有人有这样的问题可以提供帮助吗?