得到许可错误. lang。SecurityException:对3的权限拒绝。获得电子邮件附件名称时使用的是x Android设备

时间:2021-03-31 13:21:48

I am facing issue in opening Email in MYApp when I made its launch mode to "singleInstance".

当我把它的启动模式改为“单一实例”时,我在MYApp中面临着打开邮件的问题。

I have attached sample Android project which reads file name from email attachment and displays it on screen. Works fine in case of onCreate but throws error in onNewIntent when apps launch mode is singleInstance.

我附上了样例Android项目,从邮件附件中读取文件名并显示在屏幕上。在onCreate的情况下工作得很好,但是当应用程序启动模式为singleInstance时,会在onNewIntent中抛出错误。

Launchmode.java

Launchmode.java

package your.namespace.launchmode;


public class LaunchModeActivity extends Activity {
    private static final int OPEN_ACT = 2;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    String name = getAttachmetName(getIntent());
    if(null != name)
    {
        TextView textv = (TextView) findViewById(R.id.attachmentnm);
        textv.setText(name);
    }
}

@Override
protected void onNewIntent(Intent savedInstanceState)
{
    super.onNewIntent(savedInstanceState);
    String name = getAttachmetName(savedInstanceState);
    if(null != name)
    {
        TextView textv = (TextView) findViewById(R.id.attachmentnm);
        textv.setText(name);
    }
}


private String getAttachmetName(Intent intent) {
    final Uri documentUri = intent.getData();
    if(null != documentUri){
    final String uriString = documentUri.toString();
    String documentFilename = null;


    final int mailIndexPos = uriString.lastIndexOf("/attachments");
    if (mailIndexPos != -1) {
        final Uri curi = documentUri;
        final String [] projection = new String[] {OpenableColumns.DISPLAY_NAME};
        final Cursor cursor = getApplicationContext().getContentResolver().query(curi, projection, null, null, null);
        if (cursor != null) {
            final int attIdx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
            if (attIdx != -1) {
                cursor.moveToFirst();
                documentFilename = cursor.getString(attIdx);                
            }
            cursor.close();
        }
    }
    return documentFilename;
    }
    return null;
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    super.onActivityResult(requestCode, resultCode, data);

    if((resultCode == RESULT_OK) && (requestCode == OPEN_ACT))
    {
        Log.d("LaunchMode", "Second activity returned");
    }
}

}

}

AndroidManifest

AndroidManifest

<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="your.namespace.launchmode"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-permission android:name="com.google.android.gm.permission.READ_GMAIL"/>
    <uses-permission android:name="com.google.android.gm.permission.WRITE_GMAIL"/>
    <uses-permission android:name="com.google.android.providers.gmail.permission.READ_GMAIL"/>
    <uses-permission android:name="com.google.android.providers.gmail.permission.WRITE_GMAIL"/>
    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:launchMode="singleInstance"
            android:name=".LaunchModeActivity" >
            <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.DEFAULT" />
                <!-- docx -->
                <data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
                <!-- xlsx -->
                <data android:mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
                <!-- pptx -->
                <data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
                <data android:mimeType="application/vnd.ms-excel" />
                <data android:mimeType="application/msword" />
                <data android:mimeType="application/vnd.ms-powerpoint" />
                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Steps to reproduce 1)Install apk on device. 2)Go to gmail native app on device, open any attachment(office document) to view. 3)Choose LaunchMode app to complete action. 4)LaunchMode app will display file name on screen.

1)在设备上安装apk。2)打开设备上的gmail本机应用,打开任何附件(office文档)查看。3)选择LaunchMode app完成动作。4)LaunchMode app将在屏幕上显示文件名。

This works fine for first time (onCreate flow) but when this app is switch in background and again I try 2,3,4 steps.. app crashes with error

这第一次运行得很好(onCreate flow),但当这个应用程序在后台切换时,我又尝试了2、3、4个步骤。应用程序崩溃的错误

E/DatabaseUtils(30615): java.lang.SecurityException: Permission Denial: reading com.google.android.gm.provider.MailProvider uri content://gmail-ls/qoconnect@gmail.com/messages/5/attachments/0.2/BEST/false from pid=32657, uid=10058 requires com.google.android.gm.permission.READ_GMAIL
E/DatabaseUtils(30615):     at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:309)
E/DatabaseUtils(30615):     at android.content.ContentProvider$Transport.bulkQuery(ContentProvider.java:178)
E/DatabaseUtils(30615):     at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:111)
E/DatabaseUtils(30615):     at android.os.Binder.execTransact(Binder.java:339)
E/DatabaseUtils(30615):     at dalvik.system.NativeStart.run(Native Method)
D/AndroidRuntime(32657): Shutting down VM

I need to fix this as, I need to have single instance of Application and should get email attachment name too. Please let me know If I am missing something here.

我需要解决这个问题,我需要有一个应用程序实例,并且也应该得到电子邮件附件的名称。如果我漏掉了什么,请告诉我。

My question here is why it work in flow of onCreate and it wont work in case of onNewIntent

我的问题是,为什么它在onCreate中工作,而在onNewIntent中就不能工作

Note: 1)Works fine with 2.x phones 2) Works fine with Single top launch mode. 3) Some updates on Gmail app.link here:

注:1)适用于2。x phone 2)在单顶发射模式下运行良好。3) Gmail app.link:

2 个解决方案

#1


5  

You likely got a URI permission to read the file name when you received the intent and aren't using the permissions that you requested (READ_GMAIL and WRITE_GMAIL). The URI permission is valid only until your application finish()es, so you won't have it when you try to resume.

当您收到意图并没有使用您所请求的权限(READ_GMAIL和WRITE_GMAIL)时,您可能获得了读取文件名的URI权限。URI权限只有在应用程序完成时才有效,所以当您试图恢复时就不会得到它。

That's consistent with your experiences - it works when the intent is fresh, but not old ones. I think that WRITE_GMAIL is a signature permission and I am guessing that READ_GMAIL is as well. In that case, there is not much you can do. READ_ATTACHMENT might be a more appropriate permission for you to request.

这与你的经验是一致的——当你的意图是新鲜的,而不是旧的,它就会起作用。我认为WRITE_GMAIL是一个签名权限,我猜READ_GMAIL也是。在这种情况下,你无能为力。READ_ATTACHMENT可能是您请求的更合适的权限。

More on URI permissions: http://developer.android.com/guide/topics/security/permissions.html#uri

关于URI权限的更多信息:http://developer.android.com/guide/topics/security/permissions.html# URI

Try removing the uses-permission tags from your manifest and see if you have the same experience. You can also try to examine the intent when you receive it by checking its flags.

尝试从您的manifest中删除use -permission标签,看看您是否有相同的体验。您还可以通过检查其标志来尝试检查意图。

checkCallingOrSelfUriPermission(documentUri , Intent.FLAG_GRANT_READ_URI_PERMISSION)

If you get 0 returned, you have been using URI permissions.

如果返回0,则一直在使用URI权限。

#2


0  

Like skoke said, you can no longer read from GMail if the intent that gave your permission is not fresh, i.e., it must be the original activity intent. If your intent is from onNewIntent then it probably won't succeed.

就像skoke所说的,如果给你许可的意图不是新鲜的,你就不能再从GMail中读取。,必须是原始的活动意图。如果你的意图是来自onNewIntent,那么它很可能不会成功。

My solution isn't beautiful but seems to be working. In my onResume I called a custom function to see if I could access the Gmail content. If not, I showed the user a message and asked them to close the app and try again. Hey, at least it doesn't crash.

我的解决方案并不漂亮,但似乎很有效。在onResume中,我调用了一个自定义函数,查看是否可以访问Gmail内容。如果没有,我向用户显示一条消息,让他们关闭应用程序,然后再试一次。嘿,至少它不会崩溃。

#1


5  

You likely got a URI permission to read the file name when you received the intent and aren't using the permissions that you requested (READ_GMAIL and WRITE_GMAIL). The URI permission is valid only until your application finish()es, so you won't have it when you try to resume.

当您收到意图并没有使用您所请求的权限(READ_GMAIL和WRITE_GMAIL)时,您可能获得了读取文件名的URI权限。URI权限只有在应用程序完成时才有效,所以当您试图恢复时就不会得到它。

That's consistent with your experiences - it works when the intent is fresh, but not old ones. I think that WRITE_GMAIL is a signature permission and I am guessing that READ_GMAIL is as well. In that case, there is not much you can do. READ_ATTACHMENT might be a more appropriate permission for you to request.

这与你的经验是一致的——当你的意图是新鲜的,而不是旧的,它就会起作用。我认为WRITE_GMAIL是一个签名权限,我猜READ_GMAIL也是。在这种情况下,你无能为力。READ_ATTACHMENT可能是您请求的更合适的权限。

More on URI permissions: http://developer.android.com/guide/topics/security/permissions.html#uri

关于URI权限的更多信息:http://developer.android.com/guide/topics/security/permissions.html# URI

Try removing the uses-permission tags from your manifest and see if you have the same experience. You can also try to examine the intent when you receive it by checking its flags.

尝试从您的manifest中删除use -permission标签,看看您是否有相同的体验。您还可以通过检查其标志来尝试检查意图。

checkCallingOrSelfUriPermission(documentUri , Intent.FLAG_GRANT_READ_URI_PERMISSION)

If you get 0 returned, you have been using URI permissions.

如果返回0,则一直在使用URI权限。

#2


0  

Like skoke said, you can no longer read from GMail if the intent that gave your permission is not fresh, i.e., it must be the original activity intent. If your intent is from onNewIntent then it probably won't succeed.

就像skoke所说的,如果给你许可的意图不是新鲜的,你就不能再从GMail中读取。,必须是原始的活动意图。如果你的意图是来自onNewIntent,那么它很可能不会成功。

My solution isn't beautiful but seems to be working. In my onResume I called a custom function to see if I could access the Gmail content. If not, I showed the user a message and asked them to close the app and try again. Hey, at least it doesn't crash.

我的解决方案并不漂亮,但似乎很有效。在onResume中,我调用了一个自定义函数,查看是否可以访问Gmail内容。如果没有,我向用户显示一条消息,让他们关闭应用程序,然后再试一次。嘿,至少它不会崩溃。