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 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 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"/>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/194633.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

图书管理系统源码,图书管理系统开发,图书借阅系统源码四TuShuManager应用程序MVC视图View

Asp.net web应用程序MVC之View视图 .ASP.NET MVC页面也就是要说的视图基本被放在Views文件夹下&#xff1b; 2.利用APS.NET MVC模板生成框架&#xff0c;Views文件夹下的默认页面为.cshtml页面&#xff1b; 3.ASP.NET MVC默认页面为Razor格式的页面&#xff0c;因此默认页面为.…

三、Lua变量

文章目录 一、变量分类二、变量赋值三、索引 一、变量分类 lua变量分为全局变量&#xff0c;局部变量。 全局变量&#xff1a;默认&#xff0c;全局有效。 局部变量&#xff1a;从作用范围开始到作用范围结束&#xff0c;需加local 修饰。 a1function ff()local b1 endprint(a…

spring boot的redis连接数过多导致redis服务器压力过大的一次问题排查

一、背景 在今天上午的时候&#xff0c;突然收到大量的sentry报错&#xff0c;都是关于redis连接超时的警告。 首先想到的是去查看redis的监控&#xff0c;发现那个时间段&#xff0c;redis的请求数剧增&#xff0c;cpu使用率和带宽都陡增双倍。 下面的是redis监控的cpu情况 …

Module build failed: Error: ENOENT: no such file or directory

前言 这个错误通常发生在Node.js 和 vue,js项目中&#xff0c;当你试图访问一个不存在的文件或目录时。在大多数情况下&#xff0c;这是因为你的代码试图打开一个不存在的文件&#xff0c;或者你的构建系统&#xff08;例如Webpack&#xff09;需要一个配置文件&#xff0c;但找…

程序员为什么要一直坚持写博客

shigen日更文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 今天的文章其实说和技术有关系也没有什么问题&#xff0c;算起来我日更文章已经快四个月了&#xff0c;从最初的…

四、Lua循环

文章目录 一、while(循环条件)二、for&#xff08;一&#xff09;数值for&#xff08;二&#xff09;泛型for&#xff08;三&#xff09;repeat util 既然同为编程语言&#xff0c;那么控制逻辑里的循环就不能缺少&#xff0c;它可以帮助我们实现有规律的重复操作&#xff0c;而…

洗地机应该怎么选?希亦、必胜、米博、添可、小米洗地机实测推荐

作为一个常年测评智能家居的博主&#xff0c;关于洗地机的测评使用这些年也积累了不少的体验感受。以至于常被周边的朋友问到&#xff0c;洗地机到底是不是真的好用&#xff1f;洗地机有什么优点吗&#xff1f;选购的时候应该怎么选呢&#xff1f;洗地机什么牌子比较好呢&#…

.NET6实现破解Modbus poll点表配置文件

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不仅仅是技术还有人心,人心不可测,海水不可量,唯有技术,才是深沉黑夜中的一座闪烁的灯塔 !序言 Modbus 协议是工控领域常见…

Elasticsearch:什么是非结构化数据?

非结构化数据定义 非结构化数据是指未按照设计的模型或结构组织的数据。 非结构化数据通常被归类为定性数据&#xff0c;可以是人类或机器生成的。 非结构化数据是最丰富的可用数据类型&#xff0c;经过分析后&#xff0c;可用于指导业务决策并在许多其他用例中实现业务目标。…

2015年五一杯数学建模B题空气污染问题研究解题全过程文档及程序

2015年五一杯数学建模 B题 空气污染问题研究 原题再现 近十年来&#xff0c;我国 GDP 持续快速增长&#xff0c;但经济增长模式相对传统落后&#xff0c;对生态平衡和自然环境造成一定的破坏&#xff0c;空气污染的弊病日益突出&#xff0c;特别是日益加重的雾霾天气已经干扰…

Node.js入门指南(五)

目录 MongoDB 介绍 下载与启动 命令行交互 Mongoose 代码模块化 图形化管理工具 hello&#xff0c;大家好&#xff01;上一篇文章我们介绍了express框架&#xff0c;这一篇文字主要介绍MongoDB。来对数据进行存储以及操作。 MongoDB 介绍 各位小伙伴应该多多少少都有接…

JMeter---BeanShell实现接口前置和后置操作

在JMeter中&#xff0c;可以使用BeanShell脚本来实现接口的前置和后置操作。 下面是使用BeanShell脚本实现接口前置和后置操作的步骤&#xff1a; 1、在测试计划中添加一个BeanShell前置处理器或后置处理器。 右键点击需要添加前置或后置操作的接口请求&#xff0c;选择&quo…

使用com组件编辑word

一个普通的窗体应用&#xff0c;6个button using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; u…

西南科技大学电路分析基础实验A1(元件伏安特性测试 )

目录 一、实验目的 二、实验设备 三、预习内容(如:基本原理、电路图、计算值等) 1、测定线性电阻的伏安特性 2、二极管伏安特性测试 3、测定实际电压源的伏安特性 四、实验数据及结果分析(预习写必要实验步骤和表格) 1、测定线性电阻的伏安特性 2、二极管伏安特性测…

RT-DETR改进 | 2023 | InnerEIoU、InnerSIoU、InnerWIoU、InnerDIoU等二十余种损失函数

论文地址&#xff1a;官方Inner-IoU论文地址点击即可跳转 官方代码地址&#xff1a;官方代码地址-官方只放出了两种结合方式CIoU、SIoU 本位改进地址&#xff1a; 文末提供完整代码块-包括InnerEIoU、InnerCIoU、InnerDIoU等七种结合方式和其AlphaIoU变种结合起来可以达到二十…

JAVA进阶之路JVM-1:jvm基本组成、java程序执行过程、java程序的跨平台、静态编译器、jvm执行方式

JVM基本组成 当线上系统突然宕机&#xff0c;系统无法访问&#xff0c;甚至直接OOM&#xff1b; 线上系统响应速度太慢&#xff0c;优化系统性能过程中发现CPU占用过高&#xff0c;原因也许是因为JVM的GC次数过于频繁 因此&#xff0c;新项目上线&#xff0c;需要设置JVM的各…

算法-技巧-中等-寻找重复数,环形链表|,||

记录一下算法题的学习13 这次代码中运用到的技巧是「Floyd 判圈算法」&#xff08;又称龟兔赛跑算法&#xff09;&#xff0c;它是一个检测链表是否有环的算法 我们想象乌龟tortoise和兔子rabbit在链表上移动&#xff0c;乌龟爬的慢&#xff0c;兔子爬的快&#xff0c;当乌龟和…

Unity EventSystem的一些理解和使用

Unity的EventSystem是用于处理用户输入和交互的系统。它是Unity UI系统的核心组件之一&#xff0c;可以用于捕捉和分发各种事件&#xff0c;例如点击、拖拽、按键、射线等。 常用的属性和方法有以下这些&#xff1a; 属性&#xff1a; current: 获取当前的EventSystem实例。…

数据结构--->单链表

文章目录 链表链表的分类 单链表单链表的存储结构单链表主要实现的接口函数单链表尾插动态申请新节点单链表头插单链表的尾删单链表的头删在指定位置之前插入单链表查找插入 在指定位置之后插删除指定位置元素删除指定位置之后的元素顺序输出链表销毁单链表 顺序表和单链表的区…