I am trying to read Contact names, phone #'s, and emails from the ContactsContract
URI, and I am getting a SecurityException
when I try to run the program. I have set the permission in the AndroidManifest.xml
file:
我试图读取联系人姓名、电话号码和来自ContactsContract URI的电子邮件,当我试图运行这个程序时,会得到一个SecurityException。我已经在安卓系统上设置了权限。xml文件:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="edu.smumn.cs394"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
**<uses-permission android:name="android.pemission.READ_CONTACTS"/>**
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".ReadPhoneNumbers"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>`
The following is the application code:
应用程序代码如下:
@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`
I get a security exception on the last line (resolver.query()
):
我在最后一行上得到一个安全异常(resolver.query()):
`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)
[...]`
[…]
I must be missing something, but I can't figure out what.
我一定是漏掉了什么,但我不知道是什么。
5 个解决方案
#1
9
Make sure you add it outside of the application tag. While developing for a target platform of 2.3.3 using Eclipse on Ubuntu, I had permission failures in the log file that indicated I needed this exact line while working on something similar. It wasn't until I moved the *uses-permission...READ_CONTACTS* line to outside the application tag that things worked.
确保您将它添加到应用程序标记之外。在Ubuntu上使用Eclipse开发目标平台2.3.3时,日志文件中出现了权限失败,这表明我在处理类似的事情时需要这一行。直到我得到了允许……READ_CONTACTS*行到应用程序标记之外的代码。
#2
16
Requesting Permissions at Run Time
在运行时请求权限
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.
从Android 6.0 (API级别23)开始,用户在应用程序运行时授予应用程序权限,而不是在安装应用程序时授予。
If the permission you need to add isn't listed under the normal permissions, you'll need to deal with "Runtime Permissions". Runtime permissions are permissions that are requested as they are needed while the app is running. These permissions will show a dialog to the user, similar to the following one:
如果您需要添加的权限不在正常权限下列出,那么您需要处理“运行时权限”。运行时权限是应用程序运行时所需的权限。这些权限将向用户显示一个对话框,类似于下面的对话框:
The first step when adding a "Runtime Permission" is to add it to the AndroidManifest:
添加“运行时权限”的第一步是将其添加到AndroidManifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.codepath.androidpermissionsdemo" >
<uses-permission android:name="android.permission.READ_CONTACTS" />
...
</manifest>
Next, you'll need to initiate the permission request and handle the result. The following code shows how to do this in the context of an Activity, but this is also possible from within a 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);
}
}
}
#3
6
Hello Steven the debug log trace tells you that you need ... requires android.permission.READ_CONTACTS
你好,Steven调试日志跟踪告诉您您需要……需要android.permission.READ_CONTACTS
so just try something by editing the Manifest.xml like adding another permission, let see if its not correctly readed.
所以只要编辑清单就可以了。xml就像添加另一个权限一样,让我们看看它是否读错了。
and check this line without **
检查这条线没有**
<uses-permission android:name="android.permission.READ_CONTACTS" />
dan
丹
#4
5
with the api 23, permission <uses-permission android:name="android.pemission.READ_CONTACTS"/>
dont work, change the api level in the emulator for api 22(lollipop) or lower
在api 23中,权限
#5
2
If the device is running Android 6.0 or higher, and your app's target SDK is 23 or higher: The app has to list the permissions in the manifest, and it must request each dangerous permission it needs while the app is running. The user can grant or deny each permission, and the app can continue to run with limited capabilities even if the user denies a permission request.
如果设备运行的是Android 6.0或更高版本,而应用程序的目标SDK为23或更高:应用程序必须在清单中列出权限,并且必须在应用程序运行时请求其需要的每个危险权限。用户可以授予或拒绝每个权限,而且即使用户拒绝了权限请求,应用程序也可以继续以有限的功能运行。
EXAMPLE:
例子:
//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
http://developer.android.com/training/permissions/requesting.html
#1
9
Make sure you add it outside of the application tag. While developing for a target platform of 2.3.3 using Eclipse on Ubuntu, I had permission failures in the log file that indicated I needed this exact line while working on something similar. It wasn't until I moved the *uses-permission...READ_CONTACTS* line to outside the application tag that things worked.
确保您将它添加到应用程序标记之外。在Ubuntu上使用Eclipse开发目标平台2.3.3时,日志文件中出现了权限失败,这表明我在处理类似的事情时需要这一行。直到我得到了允许……READ_CONTACTS*行到应用程序标记之外的代码。
#2
16
Requesting Permissions at Run Time
在运行时请求权限
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.
从Android 6.0 (API级别23)开始,用户在应用程序运行时授予应用程序权限,而不是在安装应用程序时授予。
If the permission you need to add isn't listed under the normal permissions, you'll need to deal with "Runtime Permissions". Runtime permissions are permissions that are requested as they are needed while the app is running. These permissions will show a dialog to the user, similar to the following one:
如果您需要添加的权限不在正常权限下列出,那么您需要处理“运行时权限”。运行时权限是应用程序运行时所需的权限。这些权限将向用户显示一个对话框,类似于下面的对话框:
The first step when adding a "Runtime Permission" is to add it to the AndroidManifest:
添加“运行时权限”的第一步是将其添加到AndroidManifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.codepath.androidpermissionsdemo" >
<uses-permission android:name="android.permission.READ_CONTACTS" />
...
</manifest>
Next, you'll need to initiate the permission request and handle the result. The following code shows how to do this in the context of an Activity, but this is also possible from within a 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);
}
}
}
#3
6
Hello Steven the debug log trace tells you that you need ... requires android.permission.READ_CONTACTS
你好,Steven调试日志跟踪告诉您您需要……需要android.permission.READ_CONTACTS
so just try something by editing the Manifest.xml like adding another permission, let see if its not correctly readed.
所以只要编辑清单就可以了。xml就像添加另一个权限一样,让我们看看它是否读错了。
and check this line without **
检查这条线没有**
<uses-permission android:name="android.permission.READ_CONTACTS" />
dan
丹
#4
5
with the api 23, permission <uses-permission android:name="android.pemission.READ_CONTACTS"/>
dont work, change the api level in the emulator for api 22(lollipop) or lower
在api 23中,权限
#5
2
If the device is running Android 6.0 or higher, and your app's target SDK is 23 or higher: The app has to list the permissions in the manifest, and it must request each dangerous permission it needs while the app is running. The user can grant or deny each permission, and the app can continue to run with limited capabilities even if the user denies a permission request.
如果设备运行的是Android 6.0或更高版本,而应用程序的目标SDK为23或更高:应用程序必须在清单中列出权限,并且必须在应用程序运行时请求其需要的每个危险权限。用户可以授予或拒绝每个权限,而且即使用户拒绝了权限请求,应用程序也可以继续以有限的功能运行。
EXAMPLE:
例子:
//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
http://developer.android.com/training/permissions/requesting.html