Android : 获取、添加、手机联系人-ContentResolver简单应用

示例图:

MainActivity.java

package com.example.mygetdata;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.OperationApplicationException;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    //组件
    private Button btnGet,btnAdd;

    private ListView listView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnGet = findViewById(R.id.btn_getDate);
        btnAdd = findViewById(R.id.btn_addData);

        listView = findViewById(R.id.list_view);


        //事件
        btnGet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //获取联系人的方法
                getContacts();
            }


        });

        //添加联系人事件
        btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addContacts();
            }
        });

        //从6.0系统开始,需要动态获取权限
        int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS);
        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 0);
        }

    }

    //获取联系人
    @SuppressLint("Range")
    private void getContacts() {
        //获取内容解析对象
        ContentResolver contentResolver = getContentResolver();

        //需要解析的uri 获取系统手机的
        Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;


        /**查询数据  什么条件都没设置   查询所有信息
         * 得到一个游标对象
         * projection 显示哪些列
         * selection : 条件
         *sortOrder : 排序
         */
         Cursor cursor = contentResolver.query(uri,null,null,null,null);


         List<String> arrData = new ArrayList<>();
         //循环遍历游标
        while (cursor.moveToNext()){
            //查到名字
           String name= cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
           //电话号
            String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

            // 把数据添加到 集合
            arrData.add("姓名:"+name+"---"+number);
        }
        //关闭游标资源
        cursor.close();

        // 适配器
        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this,R.layout.list_data_layout,arrData);

        //往容器中添加适配器
        listView.setAdapter(arrayAdapter);


    }

    //添加联系人
    private void addContacts(){
        try {

        //获取内容解析对象
        ContentResolver contentResolver = getContentResolver();

        //需要解析的uri  数据中的2个表
        Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
        Uri dataUri = Uri.parse("content://com.android.contacts/data");

        //批量插入数据
        ArrayList<ContentProviderOperation> operations = new ArrayList<>();

        ContentProviderOperation cpo = ContentProviderOperation.newInsert(uri).withValue("account_name",null).build();
        operations.add(cpo);

        //名字
        ContentProviderOperation cpo2 = ContentProviderOperation.newInsert(dataUri)
                .withValueBackReference("raw_contact_id",0)
                .withValue("mimetype","vnd.android.cursor.item/name")
                .withValue("data2","添加测试")
                .build();
        operations.add(cpo2);
        //电话号码
        ContentProviderOperation cpo3 = ContentProviderOperation.newInsert(dataUri)
                .withValueBackReference("raw_contact_id",0)
                .withValue("mimetype","vnd.android.cursor.item/phone_v2")
                .withValue("data1","1111111111")
                .withValue("data2","2")
                .build();
        operations.add(cpo3);

        //邮箱
        ContentProviderOperation cpo4 = ContentProviderOperation.newInsert(dataUri)
                .withValueBackReference("raw_contact_id",0)
                .withValue("mimetype","vnd.android.cursor.item/email_v2")
                .withValue("data1","1750691615@qq.com")
                .withValue("data2","2")
                .build();
        operations.add(cpo4);



            // 批量插入数据 把内容添加到手机
            contentResolver.applyBatch("com.android.contacts",operations);
            // 弹框
            Toast.makeText(getApplicationContext(),"添加成功",Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            Log.e("TAG",e.getMessage());
            Toast.makeText(getApplicationContext(),"添加失败"+e.getMessage(),Toast.LENGTH_SHORT).show();
        }


    }

    //请求权限结果
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode){
            case 0:
                if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    Toast.makeText(MainActivity.this, "联系人权限授权成功", Toast.LENGTH_SHORT).show();

                    //从6.0系统开始,需要动态获取权限
                    int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS);
                    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
                        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CONTACTS}, 1);
                    }
                }
                break;
            case 1:
                if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    Toast.makeText(MainActivity.this, "写入联系人权限授权成功", Toast.LENGTH_SHORT).show();
                }
                break;
            default:

                break;
        }
    }
}

activity_main.xml

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_getDate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="获取联系人"
        android:textSize="24sp"
        />
    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="500dp"
        />

    <Button
        android:id="@+id/btn_addData"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="添加联系人"
        android:textSize="24sp"
        />
</LinearLayout>

list_data_layout.xml

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:textColor="#ff00ff"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="22sp"
    />

AndroidMainifest.xml 加入 读写权限

复制代码
<!-- 配置权限 读写-->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
相关推荐
《源码好优多》40 分钟前
基于Java Springboot出租车管理网站
java·开发语言·spring boot
老码沉思录4 小时前
Android开发实战班 -应用架构 - MVVM 架构模式
android·架构
·云扬·5 小时前
Java IO 与 BIO、NIO、AIO 详解
java·开发语言·笔记·学习·nio·1024程序员节
求积分不加C5 小时前
Spring Boot中使用AOP和反射机制设计一个的幂等注解(两种持久化模式),简单易懂教程
java·spring boot·后端
枫叶_v5 小时前
【SpringBoot】26 实体映射工具(MapStruct)
java·spring boot·后端
东方巴黎~Sunsiny5 小时前
java-图算法
java·开发语言·算法
2401_857617626 小时前
汽车资讯新趋势:Spring Boot技术解读
java·spring boot·后端
小林学习编程7 小时前
从零开始理解Spring Security的认证与授权
java·后端·spring
写bug的羊羊7 小时前
Spring Boot整合Nacos启动时 Failed to rename context [nacos] as [xxx]
java·spring boot·后端
努力的小陈^O^7 小时前
docker学习笔记跟常用命令总结
java·笔记·docker·云原生