权限拒绝:从android Studio中的ProcessRecord打开提供商com.android.providers.contacts.ContactsProvider2
当我试图从手机读取联系人,并且在清单文件中包含了权限拒绝:从android Studio中的ProcessRecord打开提供商com.android.providers.contacts.ContactsProvider2,android,android-studio,permissions,contacts,android-contacts,Android,Android Studio,Permissions,Contacts,Android Contacts,当我试图从手机读取联系人,并且在清单文件中包含了read\u contacts权限时,我遇到了此错误。奇怪的是,它在Eclipse中运行得很好,但当我将我的项目转换为Gradle并在Android Studio中运行时,我发现了这个错误 logcat说: 权限拒绝:从ProcessRecord{302f069 29282:com.GP/u0a322}(pid=29282,uid=10322)打开提供程序com.android.providers.contacts.contacts Provide
read\u contacts
权限时,我遇到了此错误。奇怪的是,它在Eclipse中运行得很好,但当我将我的项目转换为Gradle并在Android Studio中运行时,我发现了这个错误
logcat说:
权限拒绝:从ProcessRecord{302f069 29282:com.GP/u0a322}(pid=29282,uid=10322)打开提供程序com.android.providers.contacts.contacts Provider2需要android.Permission.READ_contacts或android.Permission.WRITE_contacts
以下是清单代码:
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<!-- Read Contacts from phone -->
<uses-permission android:name="android.permission.read_contacts" />
<uses-permission android:name="android.permission.read_phone_state" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
我的问题是,我使用的是棉花糖模拟器,它对我们如何向用户请求权限做了一些更改。因此,即使在添加了权限之后,它仍然不断地请求权限 由于棉花糖更新在运行时请求权限,读取联系人权限不起作用。示例代码是
import android.Manifest;
import android.content.ContentResolver;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Build;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
// The ListView
private ListView lstNames;
// Request code for READ_CONTACTS. It can be any number > 0.
private static final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Find the list view
this.lstNames = (ListView) findViewById(R.id.lstNames);
// Read and show the contacts
showContacts();
}
/**
* Show the contacts in the ListView.
*/
private void showContacts() {
// Check the SDK version and whether the permission is already granted or not.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
//After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method
} else {
// Android version is lesser than 6.0 or the permission is already granted.
List<String> contacts = getContactNames();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, contacts);
lstNames.setAdapter(adapter);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission is granted
showContacts();
} else {
Toast.makeText(this, "Until you grant the permission, we canot display the names", Toast.LENGTH_SHORT).show();
}
}
}
/**
* Read the name of all the contacts.
*
* @return a list of names.
*/
private List<String> getContactNames() {
List<String> contacts = new ArrayList<>();
// Get the ContentResolver
ContentResolver cr = getContentResolver();
// Get the Cursor of all the contacts
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
// Move the cursor to first. Also check whether the cursor is empty or not.
if (cursor.moveToFirst()) {
// Iterate through the cursor
do {
// Get the contacts name
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contacts.add(name);
} while (cursor.moveToNext());
}
// Close the curosor
cursor.close();
return contacts;
}
}
导入android.Manifest;
导入android.content.ContentResolver;
导入android.content.pm.PackageManager;
导入android.database.Cursor;
导入android.os.Build;
导入android.provider.contacts合同;
导入android.support.v7.app.AppActivity;
导入android.os.Bundle;
导入android.util.Log;
导入android.widget.ArrayAdapter;
导入android.widget.ListView;
导入android.widget.Toast;
导入java.util.ArrayList;
导入java.util.List;
公共类MainActivity扩展了AppCompatActivity{
//列表视图
私有列表视图名称;
//READ_联系人的请求代码。它可以是任何大于0的号码。
私有静态最终整数权限\请求\读取\联系人=100;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//查找列表视图
this.lstNames=(ListView)findViewById(R.id.lstNames);
//阅读并显示联系人
showContacts();
}
/**
*在列表视图中显示联系人。
*/
私人通讯录(){
//检查SDK版本以及权限是否已授予。
if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.M&&checkSelfPermission(Manifest.permission.READ\u CONTACTS)!=PackageManager.permission\u已授予){
requestPermissions(新字符串[]{Manifest.permission.READ\u CONTACTS},PERMISSIONS\u REQUEST\u READ\u CONTACTS);
//在此之后,您将等待onRequestPermissionsResult(int,String[],int[])重写方法中的回调
}否则{
//Android版本低于6.0或已授予权限。
列出联系人=getContactNames();
ArrayAdapter=新的ArrayAdapter(这是android.R.layout.simple\u list\u item\u 1,contacts);
lstNames.setAdapter(适配器);
}
}
@凌驾
public void onRequestPermissionsResult(int-requestCode,字符串[]权限,
int[]格兰特结果){
if(requestCode==权限\请求\读取\联系人){
if(grantResults[0]==已授予PackageManager.权限){
//许可被授予
showContacts();
}否则{
Toast.makeText(这是“在您授予许可之前,我们不能显示名称”,Toast.LENGTH_SHORT.show();
}
}
}
/**
*读取所有联系人的姓名。
*
*@返回姓名列表。
*/
私有列表getContactNames(){
列表联系人=新建ArrayList();
//获取ContentResolver
ContentResolver cr=getContentResolver();
//获取所有联系人的光标
Cursor Cursor=cr.query(ContactsContract.Contacts.CONTENT_URI,null,null,null);
//将光标移动到第一个。同时检查光标是否为空。
if(cursor.moveToFirst()){
//遍历光标
做{
//获取联系人名称
字符串名称=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_name));
联系人。添加(姓名);
}while(cursor.moveToNext());
}
//关闭curosor
cursor.close();
返回联系人;
}
}
示例屏幕截图:
我从获得了以下源代码。只有当应用程序的targetSdkVersion(在清单中指定)为23或更高时,才会使用新的运行时权限方案。因此,避免该问题的一种方法是使targetSdkVersion低于23。请参见此处的说明:
Google Play限制使用高风险或敏感权限,包括短信或通话记录权限组。所以简而言之,即使你在运行时请求许可,你的应用程序也很有可能不被允许进入Google Play 不过你可以申请一个例外。Google Play将根据具体情况审查请求并批准例外情况。
这里提到了允许例外的标准。根据谷歌关于请求许可的文档,在处理时要记住以下几点 例如,假设您在中同时列出了READ_联系人和WRITE_联系人 你的应用程序清单 如果您请求READ_联系人且用户授权 权限,然后您请求写入系统中的联系人 立即授予您该权限,而无需与 用户
我也遇到了同样的问题,我已经指定了,但即使如此,它仍不断询问我是否尝试过这样做,但我的例外情况仍然是一样的。它可以在4.4.2设备上运行,我得到了联系人列表,但当我在6.0上运行应用程序时,它崩溃了,只有一个例外@奎师那这个答案不能再是一个答案了