安卓(android)读取手机通讯录【Android移动开发基础案例教程(第2版)黑马程序员】
一、实验目的(如果代码有错漏,可在代码地址查看)
1.熟悉内容提供者(Content Provider)的概念和作用。
2.掌握内容提供者的创建和使用方法。
4.掌握内容URI的结构和用途。
二、实验条件
1.熟悉内容提供者的工作原理。
2.掌握内容提供者访问其他应用程序数据的方式。
三、实验内容
1.创建程序,添加recyclerview库。
2.添加界面控件,取消默认标题栏。
3.搭建通讯录列表条目界面布局。
4.封装联系人信息实体类。
5.编写通讯录列表的适配器。
6.实现显示通讯录界面数据的功能。
7.添加读取系统通讯录的权限,运行程序。
四、实验指导
正在layout包下:
1.activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"tools:context=".MainActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>
2.activity_contact.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=".ContactActivity"><TextViewandroid:id="@+id/textView"android:layout_width="match_parent"android:layout_height="50dp"android:gravity="center"android:padding="5dp"android:background="#BFDC9E"android:textSize="20sp"android:textColor="@color/black"android:text="通讯录" /><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rv_contact"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_margin="2dp"android:background="#F2F4E2"/>
</LinearLayout>
3.contact_item
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="5dp"android:padding="8dp"android:background="@drawable/item_bg"><ImageViewandroid:id="@+id/iv_photo"android:layout_width="60dp"android:layout_height="60dp"android:layout_centerVertical="true"app:srcCompat="@drawable/user" /><TextViewandroid:id="@+id/tv_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignTop="@+id/iv_photo"android:layout_marginTop="5dp"android:layout_toEndOf="@+id/iv_photo"android:layout_marginStart="20dp"android:textColor="@color/black"android:text="李雷" /><TextViewandroid:id="@+id/tv_phone"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignBottom="@+id/iv_photo"android:layout_marginBottom="5dp"android:layout_toEndOf="@+id/iv_photo"android:layout_marginStart="20dp"android:textColor="@color/black"android:text="13520677894" />
</RelativeLayout>
Java代码:
package cn.itcast.contacts;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.widget.Toast;import java.util.ArrayList;
import java.util.List;public class ContactActivity extends AppCompatActivity {private RecyclerView recyclerView;@SuppressLint("MissingInflatedId")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_contact);init();}private void init() {recyclerView = findViewById(R.id.rv_contact);recyclerView.setLayoutManager(new LinearLayoutManager(this));getPermissions();}String[] permissionList;//申请权限public void getPermissions() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {permissionList = new String[]{"android.permission.READ_CONTACTS"};ArrayList<String> list = new ArrayList<>();for (String s : permissionList) {if (ActivityCompat.checkSelfPermission(ContactActivity.this, s) !=PackageManager.PERMISSION_GRANTED) {list.add(s);}}if (list.size() > 0) {ActivityCompat.requestPermissions(ContactActivity.this, list.toArray(list.toArray(new String[list.size()])),1);} else {setDate();}} else {setDate();}}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == 1) {for (int i = 0; i < permissions.length; i ++) {if(permissions[i].equals("android.permission.READ_CONTACTS") &&grantResults[i] == PackageManager.PERMISSION_GRANTED) {Toast.makeText(this, "读取通讯录权限申请成功", Toast.LENGTH_SHORT).show();setDate();} else {Toast.makeText(this, "读取通讯录权限申请失败", Toast.LENGTH_SHORT).show();}}}}private void setDate() {List<ContactInfo> contactInfoList = getContacts();ContactAdapter adapter = new ContactAdapter(ContactActivity.this , contactInfoList);recyclerView.setAdapter(adapter);}//获取通讯录数据private List<ContactInfo> getContacts() {List<ContactInfo> contactInfos = new ArrayList<>();Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null,null,null,null);while ( cursor.moveToNext() ) {@SuppressLint("Range") String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));@SuppressLint("Range") String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));@SuppressLint("Range") int isHas = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));if (isHas > 0) {Cursor cursor1 = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + id,null, null);while (cursor1.moveToNext()) {ContactInfo contactInfo = new ContactInfo();contactInfo.setContactName(name);@SuppressLint("Range") String number = cursor1.getString(cursor1.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).trim();number = number.replace(" ","");number = number.replace("-","");contactInfo.setPhoneNumber(number);contactInfos.add(contactInfo);}cursor1.close();}}cursor.close();return contactInfos;}
}
package cn.itcast.contacts;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;import java.util.List;public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.MyViewHolder> {private Context context;private List<ContactInfo> contactInfoList;public ContactAdapter(Context context, List<ContactInfo> contactInfoList) {this.context = context;this.contactInfoList = contactInfoList;}@NonNull@Overridepublic MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {MyViewHolder holder = new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.contact_item,parent,false));return holder;}@Overridepublic void onBindViewHolder(@NonNull MyViewHolder holder, int position) {holder.tv_name.setText((CharSequence) contactInfoList.get(position).getContactName());holder.tv_phone.setText((CharSequence) contactInfoList.get(position).getPhoneNumber());}@Overridepublic int getItemCount() {return contactInfoList.size();}class MyViewHolder extends RecyclerView.ViewHolder {TextView tv_name, tv_phone;ImageView iv_photo;public MyViewHolder(@NonNull View itemView) {super(itemView);iv_photo = itemView.findViewById(R.id.iv_photo);tv_name = itemView.findViewById(R.id.tv_name);tv_phone = itemView.findViewById(R.id.tv_phone);}}
}
package cn.itcast.contacts;public class ContactInfo {private String contactName;private String phoneNumber;public String getContactName() {return contactName;}public void setContactName(String contactName) {this.contactName = contactName;}public String getPhoneNumber() {return phoneNumber;}public void setPhoneNumber(String phoneNumber) {this.phoneNumber = phoneNumber;}
}
package cn.itcast.contacts;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}
}
五:代码下载地址:
android: 实现注册界面、实现注册界面、饭堂小广播、音乐播放器、记事本、读取手机通讯录、学生管理系统 - Gitee.com
相关文章:
安卓(android)读取手机通讯录【Android移动开发基础案例教程(第2版)黑马程序员】
一、实验目的(如果代码有错漏,可在代码地址查看) 1.熟悉内容提供者(Content Provider)的概念和作用。 2.掌握内容提供者的创建和使用方法。 4.掌握内容URI的结构和用途。 二、实验条件 1.熟悉内容提供者的工作原理。 2.掌握内容提供者访问其…...
【Qt】常用的容器
Qt提供了多个基于模板的容器类,这些容器类可用于存储指定类型的数据项。例如常用的字符串列表类 QStringList 可用来操作一个 QList<QString>列表。 Qt的容器类比标准模板库(standard template library,STL)中的容器类更轻巧、使用更安全且更易于使…...
基于UKF-IMM无迹卡尔曼滤波与交互式多模型的轨迹跟踪算法matlab仿真,对比EKF-IMM和UKF
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于UKF-IMM无迹卡尔曼滤波与交互式多模型的轨迹跟踪算法matlab仿真,对比EKF-IMM和UKF。 2.测试软件版本以及运行结果展示 MATLAB2022A版本运行 3.核心程序 .…...
分布式事务组件Seata简介与使用,搭配Nacos统一管理服务端和客户端配置
文章目录 一. Seata简介二. 官方文档三. Seata分布式事务代码实现0. 环境简介1. 添加undo_log表2. 添加依赖3. 添加配置4. 开启Seata事务管理5. 启动演示 四. Seata Server配置Nacos1. 修改配置类型2. 创建Nacos配置 五. Seata Client配置Nacos1. 增加Seata关联Nacos的配置2. 在…...
JavaScript常用的内置构造函数
JavaScript作为一种广泛应用的编程语言,提供了丰富的内置构造函数,帮助开发者处理不同类型的数据和操作。这些内置构造函数在创建和操作对象时非常有用。本文将详细介绍JavaScript中常用的内置构造函数及其用途。 常用内置构造函数概述 1. Object Obj…...
25寒假算法刷题 | Day1 | LeetCode 240. 搜索二维矩阵 II,148. 排序链表
目录 240. 搜索二维矩阵 II题目描述题解 148. 排序链表题目描述题解 240. 搜索二维矩阵 II 点此跳转题目链接 题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。每列的元素从上到…...
MQTT知识
MQTT协议 MQTT 是一种基于发布/订阅模式的轻量级消息传输协议,专门针对低带宽和不稳定网络环境的物联网应用而设计,可以用极少的代码为联网设备提供实时可靠的消息服务。MQTT 协议广泛应用于物联网、移动互联网、智能硬件、车联网、智慧城市、远程医疗、…...
【机器学习与数据挖掘实战】案例11:基于灰色预测和SVR的企业所得税预测分析
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈机器学习与数据挖掘实战 ⌋ ⌋ ⌋ 机器学习是人工智能的一个分支,专注于让计算机系统通过数据学习和改进。它利用统计和计算方法,使模型能够从数据中自动提取特征并做出预测或决策。数据挖掘则是从大型数据集中发现模式、关联…...
新一代搜索引擎,是 ES 的15倍?
Manticore Search介绍 Manticore Search 是一个使用 C 开发的高性能搜索引擎,创建于 2017 年,其前身是 Sphinx Search 。Manticore Search 充分利用了 Sphinx,显着改进了它的功能,修复了数百个错误,几乎完全重写了代码…...
使用 Context API 管理临时状态,避免 Redux/Zustand 的持久化陷阱
在开发 React Native 应用时,我们经常需要管理全局状态,比如用户信息、主题设置、网络状态等。而对于某些临时状态,例如 数据同步进行中的状态 (isSyncing),我们应该选择什么方式来管理它? 在项目开发过程中ÿ…...
PyTorch框架——基于深度学习YOLOv8神经网络学生课堂行为检测识别系统
基于YOLOv8深度学习的学生课堂行为检测识别系统,其能识别三种学生课堂行为:names: [举手, 读书, 写字] 具体图片见如下: 第一步:YOLOv8介绍 YOLOv8 是 ultralytics 公司在 2023 年 1月 10 号开源的 YOLOv5 的下一个重大更新版本…...
word2vec 实战应用介绍
Word2Vec 是一种由 Google 在 2013 年推出的重要词嵌入模型,通过将单词映射为低维向量,实现了对自然语言处理任务的高效支持。其核心思想是利用深度学习技术,通过训练大量文本数据,将单词表示为稠密的向量形式,从而捕捉单词之间的语义和语法关系。以下是关于 Word2Vec 实战…...
C# 操作符重载对象详解
.NET学习资料 .NET学习资料 .NET学习资料 一、操作符重载的概念 在 C# 中,操作符重载允许我们为自定义的类或结构体定义操作符的行为。通常,我们熟悉的操作符,如加法()、减法(-)、乘法&#…...
python学opencv|读取图像(五十四)使用cv2.blur()函数实现图像像素均值处理
【1】引言 前序学习进程中,对图像的操作均基于各个像素点上的BGR值不同而展开。 对于彩色图像,每个像素点上的BGR值为三个整数,因为是三通道图像;对于灰度图像,各个像素上的BGR值是一个整数,因为这是单通…...
CNN的各种知识点(四): 非极大值抑制(Non-Maximum Suppression, NMS)
非极大值抑制(Non-Maximum Suppression, NMS) 1. 非极大值抑制(Non-Maximum Suppression, NMS)概念:算法步骤:具体例子:PyTorch实现: 总结: 1. 非极大值抑制(…...
虚幻基础16:locomotion direction
locomotion locomotion:角色运动系统的总称:包含移动、奔跑、跳跃、转向等。 locomotion direction 玩家输入 玩家输入:通常代表玩家想要的移动方向。 direction 可以计算当前朝向与移动方向的Δ。从而实现朝向与移动(玩家输入)方向的分…...
C++游戏开发实战:从引擎架构到物理碰撞
📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 1. 引言 C 是游戏开发中最受欢迎的编程语言之一,因其高性能、低延迟和强大的底层控制能力,被广泛用于游戏…...
代理模式——C++实现
目录 1. 代理模式简介 2. 代码示例 1. 代理模式简介 代理模式是一种行为型模式。 代理模式的定义:由于某些原因需要给某对象提供一个代理以控制该对象的访问。这时,访问对象不适合或者不能直接访问引用目标对象,代理对象作为访问对象和目标…...
什么情况下,C#需要手动进行资源分配和释放?什么又是非托管资源?
扩展:如何使用C#的using语句释放资源?什么是IDisposable接口?与垃圾回收有什么关系?-CSDN博客 托管资源的回收有GC自动触发,而非托管资源需要手动释放。 在 C# 中,非托管资源是指那些不由 CLR(…...
LeetCode 2909. 元素和最小的山形三元组 II
**### LeetCode 2909. 元素和最小的山形三元组 II 问题描述 给定一个下标从 0 开始的整数数组 nums,我们需要找到一个“山形三元组”(i, j, k)满足以下条件: i < j < knums[i] < nums[j] 且 nums[k] < nums[j] 并…...
【技术拆解】从EAIDK-610到SCARA机械臂:一个象棋机器人如何实现“眼、脑、手”协同对弈
1. 象棋机器人的“眼”:OpenCV视觉识别系统 象棋机器人的视觉系统就像人类的眼睛,它需要准确识别棋盘状态和棋子位置。我们选用OpenCV作为核心图像处理库,配合EAIDK-610开发板的摄像头模块,实现了毫米级精度的棋子定位。 在实际…...
LabVIEW数据记录编程:生产者-消费者模式与TDMS文件实战
1. 项目概述:为什么数据记录是自动化测试的“定海神针”干了这么多年自动化测试和工业测控,我越来越觉得,一个系统稳不稳,关键看它的数据记录环节扎不扎实。你可能花了大把时间把传感器信号调理得漂漂亮亮,把控制算法写…...
用两个三极管+稳压管,手把手教你搭一个简易5V LDO(附原理图、PCB与实测避坑)
用两个三极管稳压管搭建简易5V LDO:从原理图到实测的完整避坑指南 在电子设计领域,线性稳压器(LDO)是电源管理的基础模块。虽然市面上有大量成熟的LDO芯片,但用分立元件搭建一个简易LDO仍然是理解电源原理的绝佳实践。本文将带你用最常见的SS…...
Python量化交易框架moltfi:从回测到实盘的轻量级解决方案
1. 项目概述:一个为现代金融科技而生的开源量化框架如果你在金融科技或者量化交易领域摸爬滚打过一段时间,大概率会和我有同样的感受:市面上的开源量化框架,要么是“巨无霸”级别的庞然大物,功能齐全但学习曲线陡峭&am…...
自建个人数字图书馆:基于Go+Vue+SQLite的Alexandria部署与优化指南
1. 项目概述:一个现代数字图书馆的诞生如果你和我一样,是个重度数字内容爱好者,硬盘里塞满了从各种渠道收集的电子书、论文、技术文档、漫画,甚至是整理好的网页存档,那你一定体会过那种“找东西”的痛苦。文件散落在不…...
5步搭建Sunshine游戏串流服务器:打造你的私人云游戏平台
5步搭建Sunshine游戏串流服务器:打造你的私人云游戏平台 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine是一款功能强大的自托管游戏串流服务器,专…...
从稀疏重构到精准定位:OMP-CS算法在DOA估计中的实战解析
1. 从稀疏信号到空间定位:OMP-CS算法的核心逻辑 第一次接触OMP-CS算法时,我盯着那堆数学公式发呆了半小时。直到把天线阵列想象成麦克风阵列,事情突然变得简单——这不就是通过多个麦克风判断声音方向的升级版吗?在雷达和通信系统…...
V-REP/CoppeliaSim机器人仿真进阶:Graph模块3D轨迹可视化与数据导出实战解析
1. Graph模块基础与3D轨迹可视化原理 在机器人仿真中,轨迹可视化就像给机械臂装上了"运动摄像机"。V-REP/CoppeliaSim的Graph模块就是这个摄像机的核心部件,它能记录机械臂末端执行器在三维空间中的每一个细微动作。我刚开始用这个功能时&…...
题解:学而思编程 3或5的倍数
本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。 欢迎大…...
