运行显示"未找到任何联系人,请检查uri,"

MainActivity类

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    final Uri uri= ContactsContract.Contacts.CONTENT_URI;  //Android联系人uri
    ListView listView;  //列表控件
    ChooseAdapter myAdapter;  //列表适配器
    List<Contact> contacts;  //存放联系人列表(姓名+手机号),
    List<String> receiverName = new ArrayList<String>();  //短信接收人的姓名
    List<String> receiverPhone = new ArrayList<String>();  //短信接收人的手机号
    String receiverPhones; //短信接收人的手机号字符串,中间以分号分隔
    ImageView backBtn;  //作为返回按钮
    ImageView imageButton;  //作为选择确认按钮

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);//取消对应用程序标题栏的显示
        setContentView(R.layout.activity_main);
        //权限处理
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.READ_CONTACTS},1);
        }else {
            new GetContact().execute(); // 调用内部类,执行异步任务,获得联系人
            //getContacts();initView();  //阻塞式、耗时,联系人个数较多时出现白屏
        }
        //控件对象监听
        backBtn =  findViewById(R.id.onBack);backBtn.setOnClickListener(this);
        imageButton =  findViewById(R.id.imageButton);imageButton.setOnClickListener(this);
        contacts = new ArrayList<Contact>();
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case 1:
                if(grantResults.length>0){
                    for(int result : grantResults){
                        if(result != PackageManager.PERMISSION_GRANTED){
                            Toast.makeText(this, "权限不足!", Toast.LENGTH_SHORT).show();
                            finish();
                            return;
                        }
                    }
                }
                new GetContact().execute();  //执行异步线程
                break;
        }
    }
    @Override    //监听实现按钮功能的两个图像
    public void onClick(View arg0) {
        switch (arg0.getId()) {
            case R.id.onBack:
                finish();
                break;
            case R.id.imageButton:
                setMessageToSome();  //向选择的联系人群发短信
                break;
        }
    }
    //考虑到目前手机联系人数量日前增多,使用异步任务类以免阻塞UI主线程
    class GetContact extends AsyncTask<String, Integer, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Toast.makeText(MainActivity.this, "联系人信息加载中,稍候...", Toast.LENGTH_SHORT).show();
        }
        @Override
        protected String doInBackground(String... arg0) {  //接收单个值或数组,还可以接收离散变量
            getContacts();//获取所有联系人并存放至contacts
            return null;
        }
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            initView();  //呈现视图
        }
    }
    private void getContacts() {  //获得所有联系人
        Contact tmpContact;  //声明自定义实体类对象
        contacts.clear();
        Cursor cursor =getContentResolver().query(uri,null,null,null,
                ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
        if (cursor.moveToFirst()) {  //如果选择了记录
            int idColumn = cursor.getColumnIndex(ContactsContract.Contacts._ID);
            int displayNameColumn = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
            do{  //循环遍历
                tmpContact = new Contact();
                String contactId = cursor.getString(idColumn); //获得联系人ID
                String disPlayName = cursor.getString(displayNameColumn); //获得联系人姓名
                //联系人的电话数量,没有这返回值为0
                int phoneCount = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
                tmpContact.setName(disPlayName);
                if (phoneCount > 0) {
                    // 获得联系人的电话号码
                    Cursor phones = getContentResolver().query(
                            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                            null,
                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID+" = " + contactId, null, null);
                    if (phones.moveToFirst()) {
                        String tmpPhone = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        //有些手机(如小米)登记手机号,多了2位空格,如155 2764 3858
                        //手机号以“1”打头
                        if(tmpPhone.length() >= 11&&tmpPhone.substring(0, 1).equals("1"))
                            tmpContact.setPhone(tmpPhone);
                    }
                }
                if(tmpContact.getPhone()!= null) {
                    contacts.add(tmpContact);
                    Log.i("myTag",tmpContact.toString());
                }else{
                    Log.i("myTag","none");
                }
            } while (cursor.moveToNext());
        }
    }
    void initView() {   //呈现供勾选联系人的界面
        listView =  findViewById(R.id.listView);
        myAdapter = new ChooseAdapter(this, contacts);
        listView.setAdapter(myAdapter);
        listView.setItemsCanFocus(false);
        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        //列表项选择监听,同时进行了勾选或取消勾选操作
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(MainActivity.this,
                        "点击了id为" + position + "的联系人!", Toast.LENGTH_SHORT).show();
                ListItemView listItemView = (ListItemView) view.getTag();
                boolean check = listItemView.checkBox.isChecked();
                if (check) {
                    listItemView.checkBox.setChecked(false);
                    check = false;
                } else {
                    listItemView.checkBox.setChecked(true);
                    check = true;
                }
                ChooseAdapter.checkResult.put(position, check);
            }
        });
        if (contacts.size()>0) {
            listView.setClickable(true);
            myAdapter.refresh(contacts);  //调用适配器类定义的方法
        }else{
            Toast.makeText(MainActivity.this, "未找到任何联系人,请检查uri,", Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    //先构建对话框内容和群发的手机号,调用系统的短信程序,向选择的联系人发送短信
    public void setMessageToSome() {
        //选择了联系人进入短信编辑界面时,可能还会按返回键重新选择。所以,调用本方法前,重新统计
        receiverName.clear();receiverPhone.clear();
        for (int i = 0; i < ChooseAdapter.checkResult.size(); i++) {
            if (ChooseAdapter.checkResult.get(i)) {
                receiverName.add(contacts.get(i).getName());
                receiverPhone.add(contacts.get(i).getPhone());
            }
        }

        if (receiverName.size() == 0) {     //未勾选联系人
            new AlertDialog.Builder(this).setTitle("没有选中任何记录").setPositiveButton("确定", null).show();
        } else {
            StringBuilder sb = new StringBuilder();
            sb.append("接收人:" + receiverName.get(0));
            receiverPhones = receiverPhone.get(0);
            for (int i = 1; i < receiverName.size(); i++) {
                sb.append("," + receiverName.get(i));  //构建对话框的内容,姓名之间用逗号分隔
                receiverPhones += ";" + receiverPhone.get(i);  //群发的手机号码之间要求用分号分隔
            }
            new AlertDialog.Builder(this)
                    .setTitle("是否确定?")
                    .setMessage(sb)
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface arg0, int arg1) {
                            //使用系统的短信程序
                            Intent intent=new Intent(Intent.ACTION_VIEW);
                            //短信界面中显示的接收人字符串由接收人电话字符串决定
                            intent.setData(Uri.parse("sms:"+receiverPhones+"?body=这儿写群发短信内容"));
                            startActivity(intent);  //调用系统的短信程序
                        }
                    })
                    .setNegativeButton("取消", null)
                    .show();
        }
    }
}


Contact类

class Contact {  //自定义的实体类
    private String name;
    private String phone;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "Contact{" + "name='" + name + '\'' + ", phone='" + phone + '\'' + '}';
    }
}

提示是在以下代码行提示的:

img


说明contacts这里面没有获取到联系人的数据,那你就要检查下 ContactsContract.Contacts.CONTENT_URI这个是不是正确的获取联系人的接口,其次,代码中哪个地方将数据放入到 了contacts中,有可能根本就没有放任何数据到contacts中。调试下代码看看