java.lang.SecurityException试图从Android Contacts URI读取

我正在尝试从ContactsContract URI中读取联系人姓名,电话号码和电子邮件,当我尝试运行该程序时,我收到了SecurityException 。 我在AndroidManifest.xml文件中设置了权限

   ****         ` 

以下是应用程序代码:

  @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.contact_list); ContentResolver resolver = getContentResolver(); Cursor c = resolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); //[...] Work through data here` 

我在最后一行( resolver.query() )得到一个安全exception:

 `03-08 07:41:40.812: ERROR/AndroidRuntime(416): FATAL EXCEPTION: main 03-08 07:41:40.812: ERROR/AndroidRuntime(416): java.lang.RuntimeException: Unable to start activity ComponentInfo{edu.smumn.cs394/edu.smumn.cs394.ReadPhoneNumbers}: java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://com.android.contacts/contacts from pid=416, uid=10037 requires android.permission.READ_CONTACTS [...] 03-08 07:41:40.812: ERROR/AndroidRuntime(416): Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://com.android.contacts/contacts from pid=416, uid=10037 requires android.permission.READ_CONTACTS [...] 03-08 07:41:40.812: ERROR/AndroidRuntime(416): at edu.smumn.cs394.ReadPhoneNumbers.onCreate(ReadPhoneNumbers.java:30) 

[…]`

我必须遗漏一些东西,但我无法弄清楚是什么。

确保将其添加到应用程序标记之外。 在Ubuntu上使用Eclipse开发2.3.3的目标平台时,我在日志文件中有权限失败,表明在处理类似的事情时我需要这个确切的行。 直到我将* uses-permission … READ_CONTACTS *行移到应用程序标记之外才能工作。

在运行时请求权限

从Android 6.0(API级别23)开始,用户在应用程序运行时向应用程序授予权限,而不是在安装应用程序时。

如果您需要添加的权限未列在正常权限下,则需要处理“运行时权限”。 运行时权限是应用程序运行时所需的权限。 这些权限将向用户显示一个对话框,类似于以下内容:

在此处输入图像描述

添加“运行时权限”的第一步是将其添加到AndroidManifest:

   ...  

接下来,您需要启动权限请求并处理结果。 以下代码显示了如何在Activity的上下文中执行此操作,但也可以在Fragment中执行此操作。

 // MainActivity.java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // In an actual app, you'd want to request a permission when the user performs an action // that requires that permission. getPermissionToReadUserContacts(); } // Identifier for the permission request private static final int READ_CONTACTS_PERMISSIONS_REQUEST = 1; // Called when the user is performing an action which requires the app to read the // user's contacts public void getPermissionToReadUserContacts() { // 1) Use the support library version ContextCompat.checkSelfPermission(...) to avoid // checking the build version since Context.checkSelfPermission(...) is only available // in Marshmallow // 2) Always check for permission (even if permission has already been granted) // since the user can revoke permissions at any time through Settings if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { // The permission is NOT already granted. // Check if the user has been asked about this permission already and denied // it. If so, we want to give more explanation about why the permission is needed. if (shouldShowRequestPermissionRationale( Manifest.permission.READ_CONTACTS)) { // Show our own UI to explain to the user why we need to read the contacts // before actually requesting the permission and showing the default UI } // Fire off an async request to actually get the permission // This will show the standard permission request dialog UI requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, READ_CONTACTS_PERMISSIONS_REQUEST); } } // Callback with the request from calling requestPermissions(...) @Override public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) { // Make sure it's our original READ_CONTACTS request if (requestCode == READ_CONTACTS_PERMISSIONS_REQUEST) { if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(this, "Read Contacts permission granted", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "Read Contacts permission denied", Toast.LENGTH_SHORT).show(); } } else { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } } 

Hello Steven调试日志跟踪告诉您需要…需要android.permission.READ_CONTACTS

所以只需通过编辑Manifest.xml来尝试一些内容,比如添加另一个权限,看看它是否被正确加入。

并检查此行没有**

  

使用api 23,权限不起作用,在api 22(棒棒糖)或更低版本的模拟器中更改api级别

如果设备运行的是Android 6.0或更高版本,并且您的应用的目标SDK为23或更高:应用必须列出清单中的权限,并且必须在应用运行时请求其所需的每个危险权限。 用户可以授予或拒绝每个权限,即使用户拒绝权限请求,应用程序也可以继续以有限的function运行。

例:

  //thisActivity is the running activity if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, Manifest.permission.READ_CONTACTS)) { // Show an expanation to the user *asynchronously* -- don't block // this thread waiting for the user's response! After the user // sees the explanation, try again to request the permission. } else { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS); // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an // app-defined int constant. The callback method gets the // result of the request. } } 

http://developer.android.com/training/permissions/requesting.html