从我的应用程序android中的gmail应用程序读取附件的安全性异常

时间:2014-03-27 05:54:23

标签: android

在我们的应用程序中,我们需要从电子邮件客户端读取附件并将​​其上传到服务器。 对于默认的android电子邮件客户端,一切正常,但对于面向

的gmail应用程序
java.lang.SecurityException: Permission Denial: opening provider   com.google.android.gm.provider.MailProvider from ProcessRecord (pid=11298, uid=10068) requires com.google.android.gm.permission.READ_GMAIL or com.google.android.gm.permission.WRITE_GMAIL

甚至尝试过授予Gmail读写权限但无效。

观察

  

它适用于Nexus,但对于三星设备4.2和4.1,如果第一次创建活动,则最初工作正常,但如果活动在背景中抛出上述异常。

尝试使用以下代码获取附件文件名。

    Cursor cursor = getContentResolver().query(openIntent.getData(),
            new String[] { MediaStore.MediaColumns.DISPLAY_NAME }, null,
            null, null);

    cursor.moveToFirst();
    int nameIndex = cursor
            .getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
    if (nameIndex >= 0) {
        NCUtil.clickedImageTitle = cursor.getString(nameIndex);
        path = cursor.getString(nameIndex);
    }
    cursor.close();

我的清单文件

        <activity
        android:name="com.ncomputing.vspacemobile.NCMainActivity"
        android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
        android:excludeFromRecents="true"
        android:launchMode="singleTask"
        android:screenOrientation="sensorPortait"
        android:theme="@android:style/Theme.NoTitleBar"
        android:windowSoftInputMode="adjustPan" >

        <!-- For email attachments -->
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />

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

            <data android:mimeType="application/pdf" />
            <data android:mimeType="application/msword" />
            <data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
            <data android:mimeType="application/vnd.ms-excel" />
            <data android:mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
            <data android:mimeType="application/vnd.ms-powerpoint" />
            <data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
            <data android:mimeType="text/plain" />
            <data android:mimeType="text/comma-separated-values" />
            <data android:mimeType="application/rtf" />
        </intent-filter>
    </activity>

用户权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

请告诉我们如何才能使其正常工作,我需要将活动启动模式设为singleTask并访问附件。

3 个答案:

答案 0 :(得分:5)

intent过滤器需要内容和文件方案类型,mimetype application / octetstream

<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=".*\\.inform" android:mimeType="application/octet-stream"/>
<data android:scheme="content" android:pathPattern=".*\\.inform" android:mimeType="application/octet-stream"/>

根据Android文档,&#34;如果没有为intent过滤器指定方案,则忽略所有其他URI属性。&#34;删除了scheme和URI属性后,过滤意图的唯一方法是使用Mime类型,我们都知道自定义文件扩展名没有注册的mime类型。

供参考,URI的格式为:

scheme://host:port/path
pathPrefix
pathPattern

所以没有方案,所有这些都会下降。在发现上述内容后,我尝试了显而易见的事情 - 使用&#34; *&#34;对于该计划,甚至尝试过&#34; 。*&#34;。这些都没有奏效。我希望其他人可以继承我的考验。但我认为这与选择正确的方案有关。不幸的是,我所知道的唯一方案是http https内容和文件,以上都不是神奇的子弹。

<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/*" host="*" android:pathPattern=".*.ext" android:scheme="content" />
</intent-filter>

此意图将导致gmail显示“下载/预览”按钮。实际上,当.ext文件作为附件发送到常规电子邮件客户端时,这也会导致您的应用程序打开。

来源:

Android get attached filename from gmail app Intent filter to download attachment from gmail apps on Android

答案 1 :(得分:3)

当被调用的应用程序的任务完成时,Android的ActivityManager会自动清除每个URI的权限。由于每个URI权限通常是通过设置Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET授予的,因此当该任务进入后台时该任务会被清除(因此,如果再次从启动器启动Gmail,则不会打开附件查看器)。见docs for details

这是设计上的,没有办法让它发挥作用。您必须使用此权限授予方案构建您的应用程序。您可以在启动应用程序时阅读整个附件,转储到临时文件/数据库,然后使用服务继续在后台上传。

不确定您正在构建哪个应用,但通常从隐私和安全角度来看,将您的附件上传到第三方服务器的应用听起来是个糟糕的主意。

答案 2 :(得分:0)

要阅读电子邮件附件,您需要这些权限......

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.email.permission.READ_ATTACHMENT" />

注意: READ_EXTERNAL_STORAGE假定WRITE_EXTERNAL_STORAGE,但最好将其添加为最佳做法。 互联网:应用程序可能会从需要互联网的提供商处提取,因为这是电子邮件。

提示:通过为每个mime类型创建一个单独的类来保持代码清洁。

    <activity
        android:name=".KmlReader"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:label="@string/title_activity_map"
        android:parentActivityName="com.gosylvester.bestrides.ImageTextListViewActivity"
        android:theme="@style/Theme.AppCompat" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.gosylvester.bestrides.ImageTextListViewActivity" />

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

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

            <data android:mimeType="application/vnd.google-earth.kml+xml" />
        </intent-filter>
    </activity>