我想从android访问“读取联系人”权限。我已在清单文件中指定权限。
<uses-permission
android:name="android.permission.READ_CONTACTS" />
它在设备4.4.2上工作,但在6.0上崩溃,但有一个例外:
FATAL EXCEPTION: main
Process: com.example.siddhi.meavita, PID: 17612
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.siddhi.meavita/com.example.siddhi.meavita.ContactList}: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord{44abcb5 17612:com.example.siddhi.meavita/u0a158} (pid=17612, uid=10158) requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS
所以我环顾了一下So以找到解决方案,我知道android 6.0以后的版本有一个权限模型来请求权限。
因此,我阅读了以下链接:
https://developer.android.com/training/permissions/requesting.html
并遵循此处建议的代码:
Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord in Android Studio
我这样写代码:
public class ContactList extends ListActivity {
private ArrayList<contact> contact_list = null;
private contactAdapter mContactAdapter = null;
private ArrayList<contact> items;
boolean[] isChecked;
Cursor mCursor;
ListView lv;
public int RQS_PICK_CONTACT = 1;
private static final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contacts_list);
int permissionCheck = ContextCompat.checkSelfPermission(ContactList.this,
Manifest.permission.READ_CONTACTS);
contact_list = new ArrayList<contact>();
lv = getListView();
getContacts();
}
@SuppressWarnings("unused")
private void getContacts() {
String[] projection = new String[] {
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
ContactsContract.Contacts._ID };
mCursor = managedQuery(ContactsContract.Contacts.CONTENT_URI, null, null, null,null);
while (mCursor.moveToNext()) {
contact contact = new contact();
String contactId = mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts._ID));
contact.setContactName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
contact_list.add(contact);
}
isChecked = new boolean[mCursor.getCount()];
for (int i = 0; i < isChecked.length; i++) {
isChecked[i] = false;
}
showContacts();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RQS_PICK_CONTACT) {
if (resultCode == RESULT_OK) {
getContacts();
}
}
}
public class contactAdapter extends ArrayAdapter<contact> {
public contactAdapter(Context context, int textViewResourceId, ArrayList<contact> items1) {
super(context, textViewResourceId, items1);
items = items1;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder mViewHolder;
mViewHolder = new ViewHolder();
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.contact_list_item, parent, false);
mViewHolder.cb = (CheckBox) convertView.findViewById(R.id.checkBox);
mViewHolder.name = (TextView) convertView.findViewById(R.id.name);
convertView.setTag(mViewHolder);
if (isChecked[position] == true)
mViewHolder.cb.setChecked(true);
else
mViewHolder.cb.setChecked(false);
mViewHolder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean ischecked) {
if (buttonView.isChecked())
isChecked[position] = true;
else
isChecked[position] = false;
}
});
contact contacts = items.get(position);
if (contacts != null) {
if (mViewHolder.cb != null) {
mViewHolder.name.setText(contacts.getContactName());
}
}
return convertView;
}
}
public class ViewHolder {
CheckBox cb;
TextView name;
}
@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();
}
}
}
private void showContacts()
{
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 {
this.mContactAdapter = new contactAdapter(this, R.layout.contact_list_item, contact_list);
lv.setAdapter(this.mContactAdapter);
mCursor.close();
}
}
}
但它还是给出了一个例外。这里出了什么问题?非常感谢。