获取权限错误java.lang.SecurityException:获取电子邮件附件名称时在3.x Android设备上的权限拒绝

当我将启动模式设置为“singleInstance”时,我在MYApp中打开电子邮件时遇到问题。

我附加了示例Android项目,它从电子邮件附件中读取文件名并在屏幕上显示。 在onCreate的情况下工作正常但在应用程序启动模式为singleInstance时在onNewIntent中抛出错误。

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

                               

重现的步骤1)在设备上安装apk。 2)转到设备上的gmail本机应用程序,打开任何附件(office文档)进行查看。 3)选择LaunchMode应用程序以完成操作。 4)LaunchMode应用程序将在屏幕上显示文件名。

这个第一次工作正常(onCreate flow)但是当这个应用程序在后台切换时我再次尝试2,3,4步… app崩溃有错误

 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 

我需要解决这个问题,我需要有单个Application实例,并且还应该获得电子邮件附件名称。 请告诉我如果我在这里遗漏了什么。

我的问题是为什么它在onCreate的流程中起作用,并且在onNewIntent的情况下它不起作用

注意:1)与2.x手机一起使用2)在单顶启动模式下工作正常。 3)Gmail应用程序的一些更新。 链接到这里:

当您收到意图并且未使用您请求的权限( READ_GMAILWRITE_GMAIL )时,您可能获得了读取文件名的URI权限。 URI权限仅在您的应用程序finish() es之前有效,因此当您尝试恢复时,您将无法获得该权限。

这与你的经历是一致的 – 当意图是新鲜的时候它会起作用,但不是旧的。 我认为WRITE_GMAIL是一个签名权限,我猜READ_GMAIL 。 在那种情况下,你无能为力。 READ_ATTACHMENT可能是您要求的更合适的权限。

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

尝试从清单中删除uses-permission标记,看看您是否具有相同的体验。 您还可以通过检查其标志来尝试检查它的intent

 checkCallingOrSelfUriPermission(documentUri , Intent.FLAG_GRANT_READ_URI_PERMISSION) 

如果返回0,则表示您一直使用URI权限。

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

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