代码之家  ›  专栏  ›  技术社区  ›  Sid

Android 6.0拒绝读取联系人权限

  •  0
  • Sid  · 技术社区  · 8 年前

    我想从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();
                }
    
            }
    
    }
    

    但它还是给出了一个例外。这里出了什么问题?非常感谢。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Andy    8 年前

    我并不完全熟悉如何获得联系人,但从我注意到的情况来看 getContacts() 方法总是在创建片段时被调用。因此,假设用户从未授予权限。您仍在尝试设置联系人列表。如果尚未授予权限,甚至不要首先费心设置列表。比如:

    //onCreate
    lv = getListView();
    
    if(ContextCompat.checkSelfPermission(this,
        Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
             getContacts();
     }
    

    此外,您可能希望更改逻辑以适应这种情况。所以删除该权限签入 showContacts() 如果已被请求,请将其移入 onCreate . getContacts 只有在您有权限的情况下才应调用。

        2
  •  -2
  •   Edd Perez    8 年前

    Android 6.0(API 23)需要在清单中使用权限,就像您的一样。

    把这个放在你的舱单上。

    <uses-permission-sdk-23 android:name="android.permission.READ_CONTACTS" />