使用ContentProvider管理联系人_(1)开发contentprovider管理手机联系人信息项目。 (2)contentprovide-程序员宅基地

技术标签: 系统ContentProvider  ContentProvider  管理联系人  Android之旅  Android  

随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666)

Android系统提供了Contacts应用程序来管理联系人,而且还为联系人管理提供了ContentProvider。

下面通过一个实例来演示,实现查询系统所有联系人的姓名及其详细信息和添加联系人,代码如下:

读取联系人的Activity:

package com.lovo.activity;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.TextView;

import com.lovo.lesson15.R;

/**
 * 读取联系人的Activity
 * 
 * @author Administrator
 * 
 */
public class ReadContactActivity extends Activity {

	/**
	 * 保存联系人的姓名集合
	 */
	private ArrayList<String> namesList = new ArrayList<String>();
	/**
	 * 保存联系人详细信息的集合
	 */
	private ArrayList<ArrayList<String>> infoList = new ArrayList<ArrayList<String>>();
	private ExpandableListView elv;
	private Button addContactBtn;
	private BaseExpandableListAdapter adapter;

	/**
	 * 初始化集合
	 */
	public void initData() {
		namesList.clear();
		infoList.clear();
		// 查询联系人的基本信息
		// 系统联系人的URI:ContactsContract.Contacts.CONTENT_URI
		Cursor cursor = getContentResolver().query(
				ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
		while (cursor.moveToNext()) {
			// 获取联系人的ID
			int contactId = cursor.getInt(cursor
					.getColumnIndex(ContactsContract.Contacts._ID));
			// 获取联系人的姓名
			String name = cursor.getString(cursor
					.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
			namesList.add(name);

			// 存放每个联系人里面详细信息的集合,里面有电话号码和email
			ArrayList detailList = new ArrayList();
			// 查找电话号码
			// 获取系统联系人电话号码的URI:ContactsContract.CommonDataKinds.Phone.CONTENT_URI
			// 电话号码数据中对应联系人的ID列名:ContactsContract.CommonDataKinds.Phone.CONTACT_ID
			Cursor phoneCursor = getContentResolver().query(
					ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
					null,
					ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "="
							+ contactId, null, null);
			while (phoneCursor.moveToNext()) {
				String phoneNumber = phoneCursor
						.getString(phoneCursor
								.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
				detailList.add(phoneNumber);
			}
			phoneCursor.close();

			// 查找联系人的email
			// 获取联系人email的URI:ContactsContract.CommonDataKinds.Email.CONTENT_URI
			// email数据中对应联系人的ID列名:ContactsContract.CommonDataKinds.Email.CONTACT_ID
			Cursor emailCursor = getContentResolver().query(
					ContactsContract.CommonDataKinds.Email.CONTENT_URI,
					null,
					ContactsContract.CommonDataKinds.Email.CONTACT_ID + "="
							+ contactId, null, null);
			while (emailCursor.moveToNext()) {
				String email = emailCursor
						.getString(emailCursor
								.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
				detailList.add(email);
			}
			emailCursor.close();
			infoList.add(detailList);
		}
		cursor.close();
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.read_contact_main);
		initData();
		elv = (ExpandableListView) findViewById(R.id.read_contact_main_elv);
		addContactBtn = (Button) findViewById(R.id.read_contact_main_btn_add);
		addContactBtn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent(ReadContactActivity.this,
						SaveContactActivity.class);
				startActivity(intent);
			}
		});

		adapter = new BaseExpandableListAdapter() {

			@Override
			public boolean isChildSelectable(int groupPosition,
					int childPosition) {
				return true;
			}

			@Override
			public boolean hasStableIds() {
				return true;
			}

			@Override
			public View getGroupView(int groupPosition, boolean isExpanded,
					View convertView, ViewGroup parent) {
				TextView tv = new TextView(ReadContactActivity.this);
				tv.setText(namesList.get(groupPosition));
				tv.setPadding(50, 10, 10, 10);
				return tv;
			}

			@Override
			public long getGroupId(int groupPosition) {
				return groupPosition;
			}

			@Override
			public int getGroupCount() {
				return namesList.size();
			}

			@Override
			public Object getGroup(int groupPosition) {
				return namesList.get(groupPosition);
			}

			@Override
			public int getChildrenCount(int groupPosition) {
				return infoList.get(groupPosition).size();
			}

			@Override
			public View getChildView(int groupPosition, int childPosition,
					boolean isLastChild, View convertView, ViewGroup parent) {
				TextView tv = new TextView(ReadContactActivity.this);
				tv.setText(infoList.get(groupPosition).get(childPosition));
				tv.setPadding(10, 10, 10, 10);
				return tv;
			}

			@Override
			public long getChildId(int groupPosition, int childPosition) {
				return childPosition;
			}

			@Override
			public Object getChild(int groupPosition, int childPosition) {
				return infoList.get(groupPosition).get(childPosition);
			}
		};
		elv.setAdapter(adapter);
	}

	// 添加联系人完成后回调此方法,更新adapter数据
	@Override
	protected void onResume() {
		super.onResume();
		initData();
		adapter.notifyDataSetChanged();
	}
}

读取联系人的布局XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/read_contact_main_btn_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="增加" />

    <ExpandableListView
        android:id="@+id/read_contact_main_elv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ExpandableListView>

</LinearLayout>

增加联系人的Activity:

package com.lovo.activity;

import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.view.View;
import android.widget.EditText;

import com.lovo.lesson15.R;

public class SaveContactActivity extends Activity {
	private EditText nameText;
	private EditText phoneText;
	private EditText emailText;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.add_contact_main);
		nameText = (EditText) findViewById(R.id.add_contact_main_et_name);
		phoneText = (EditText) findViewById(R.id.add_contact_main_et_phone);
		emailText = (EditText) findViewById(R.id.add_contact_main_et_email);
	}

	public void click(View v) {
		if (v.getId() == R.id.add_contact_main_btn_ok) {
			ContentValues values = new ContentValues();
			// 添加一条空数据并获取其ID,此ID为当前增加的联系人ID
			Uri uri = getContentResolver().insert(RawContacts.CONTENT_URI,
					values);
			// 使用工具类ContentUris来解析Uri中的ID
			long contactId = ContentUris.parseId(uri);
			// 添加联系人的姓名
			if (nameText.getText() != null
					&& !"".equals(nameText.getText().toString().trim())) {
				// 将ContentValues里面的所有内容清空
				values.clear();
				// 增加联系人ID
				values.put(Data.RAW_CONTACT_ID, contactId);
				// 指定要添加联系人姓名的MIME类型
				values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
				// 指定要添加联系人的姓名
				values.put(StructuredName.GIVEN_NAME, nameText.getText()
						.toString());
				// 添加联系人的姓名
				getContentResolver().insert(ContactsContract.Data.CONTENT_URI,
						values);
			}

			// 添加联系人的电话
			if (phoneText.getText() != null
					&& !"".equals(phoneText.getText().toString().trim())) {
				// 将ContentValues里面的所有内容清空
				values.clear();
				// 增加联系人ID
				values.put(Data.RAW_CONTACT_ID, contactId);
				// 指定要添加联系人电话的MIME类型
				values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
				// 指定要添加的联系人电话的类型
				values.put(Phone.TYPE, Phone.TYPE_MOBILE);
				// 制定要添加联系人的电话
				values.put(Phone.NUMBER, phoneText.getText().toString());
				// 添加联系人的电话
				getContentResolver().insert(ContactsContract.Data.CONTENT_URI,
						values);
			}

			// 添加联系人的email
			if (emailText.getText() != null
					&& !"".equals(emailText.getText().toString().trim())) {
				// 将ContentValues里面的所有内容清空
				values.clear();
				// 增加联系人ID
				values.put(Data.RAW_CONTACT_ID, contactId);
				// 指定要添加联系人email的MIME类型
				values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
				// 指定要添加的联系人email的类型
				values.put(Email.TYPE, Email.TYPE_HOME);
				// 指定要添加的联系人的email
				values.put(Email.DATA, emailText.getText().toString());
				// 添加联系人的email
				getContentResolver().insert(ContactsContract.Data.CONTENT_URI,
						values);
			}
			finish();
		}
		if (v.getId() == R.id.add_contact_main_btn_back) {
			finish();
		}
	}
}

增加联系人的布局XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="联系人的姓名" />

    <EditText
        android:id="@+id/add_contact_main_et_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="联系人的电话" />

    <EditText
        android:id="@+id/add_contact_main_et_phone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="联系人的email" />

    <EditText
        android:id="@+id/add_contact_main_et_email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/add_contact_main_btn_ok"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="click"
            android:text="保存" />

        <Button
            android:id="@+id/add_contact_main_btn_back"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:onClick="click"
            android:text="返回" />
    </LinearLayout>

</LinearLayout>

要读取系统联系人,不要忘了加上如下权限:

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







 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u010142437/article/details/9256351

智能推荐

艾美捷Epigentek DNA样品的超声能量处理方案-程序员宅基地

文章浏览阅读15次。空化气泡的大小和相应的空化能量可以通过调整完全标度的振幅水平来操纵和数字控制。通过强调超声技术中的更高通量处理和防止样品污染,Epigentek EpiSonic超声仪可以轻松集成到现有的实验室工作流程中,并且特别适合与表观遗传学和下一代应用的兼容性。Epigentek的EpiSonic已成为一种有效的剪切设备,用于在染色质免疫沉淀技术中制备染色质样品,以及用于下一代测序平台的DNA文库制备。该装置的经济性及其多重样品的能力使其成为每个实验室拥有的经济高效的工具,而不仅仅是核心设施。

11、合宙Air模块Luat开发:通过http协议获取天气信息_合宙获取天气-程序员宅基地

文章浏览阅读4.2k次,点赞3次,收藏14次。目录点击这里查看所有博文  本系列博客,理论上适用于合宙的Air202、Air268、Air720x、Air720S以及最近发布的Air720U(我还没拿到样机,应该也能支持)。  先不管支不支持,如果你用的是合宙的模块,那都不妨一试,也许会有意外收获。  我使用的是Air720SL模块,如果在其他模块上不能用,那就是底层core固件暂时还没有支持,这里的代码是没有问题的。例程仅供参考!..._合宙获取天气

EasyMesh和802.11s对比-程序员宅基地

文章浏览阅读7.7k次,点赞2次,收藏41次。1 关于meshMesh的意思是网状物,以前读书的时候,在自动化领域有传感器自组网,zigbee、蓝牙等无线方式实现各个网络节点消息通信,通过各种算法,保证整个网络中所有节点信息能经过多跳最终传递到目的地,用于数据采集。十多年过去了,在无线路由器领域又把这个mesh概念翻炒了一下,各大品牌都推出了mesh路由器,大多数是3个为一组,实现在面积较大的住宅里,增强wifi覆盖范围,智能在多热点之间切换,提升上网体验。因为节点基本上在3个以内,所以mesh的算法不必太复杂,组网形式比较简单。各厂家都自定义了组_802.11s

线程的几种状态_线程状态-程序员宅基地

文章浏览阅读5.2k次,点赞8次,收藏21次。线程的几种状态_线程状态

stack的常见用法详解_stack函数用法-程序员宅基地

文章浏览阅读4.2w次,点赞124次,收藏688次。stack翻译为栈,是STL中实现的一个后进先出的容器。要使用 stack,应先添加头文件include<stack>,并在头文件下面加上“ using namespacestd;"1. stack的定义其定义的写法和其他STL容器相同, typename可以任意基本数据类型或容器:stack<typename> name;2. stack容器内元素的访问..._stack函数用法

2018.11.16javascript课上随笔(DOM)-程序员宅基地

文章浏览阅读71次。<li> <a href = "“#”>-</a></li><li>子节点:文本节点(回车),元素节点,文本节点。不同节点树:  节点(各种类型节点)childNodes:返回子节点的所有子节点的集合,包含任何类型、元素节点(元素类型节点):child。node.getAttribute(at...

随便推点

layui.extend的一点知识 第三方模块base 路径_layui extend-程序员宅基地

文章浏览阅读3.4k次。//config的设置是全局的layui.config({ base: '/res/js/' //假设这是你存放拓展模块的根目录}).extend({ //设定模块别名 mymod: 'mymod' //如果 mymod.js 是在根目录,也可以不用设定别名 ,mod1: 'admin/mod1' //相对于上述 base 目录的子目录}); //你也可以忽略 base 设定的根目录,直接在 extend 指定路径(主要:该功能为 layui 2.2.0 新增)layui.exten_layui extend

5G云计算:5G网络的分层思想_5g分层结构-程序员宅基地

文章浏览阅读3.2k次,点赞6次,收藏13次。分层思想分层思想分层思想-1分层思想-2分层思想-2OSI七层参考模型物理层和数据链路层物理层数据链路层网络层传输层会话层表示层应用层OSI七层模型的分层结构TCP/IP协议族的组成数据封装过程数据解封装过程PDU设备与层的对应关系各层通信分层思想分层思想-1在现实生活种,我们在喝牛奶时,未必了解他的生产过程,我们所接触的或许只是从超时购买牛奶。分层思想-2平时我们在网络时也未必知道数据的传输过程我们的所考虑的就是可以传就可以,不用管他时怎么传输的分层思想-2将复杂的流程分解为几个功能_5g分层结构

基于二值化图像转GCode的单向扫描实现-程序员宅基地

文章浏览阅读191次。在激光雕刻中,单向扫描(Unidirectional Scanning)是一种雕刻技术,其中激光头只在一个方向上移动,而不是来回移动。这种移动方式主要应用于通过激光逐行扫描图像表面的过程。具体而言,单向扫描的过程通常包括以下步骤:横向移动(X轴): 激光头沿X轴方向移动到图像的一侧。纵向移动(Y轴): 激光头沿Y轴方向开始逐行移动,刻蚀图像表面。这一过程是单向的,即在每一行上激光头只在一个方向上移动。返回横向移动: 一旦一行完成,激光头返回到图像的一侧,准备进行下一行的刻蚀。

算法随笔:强连通分量-程序员宅基地

文章浏览阅读577次。强连通:在有向图G中,如果两个点u和v是互相可达的,即从u出发可以到达v,从v出发也可以到达u,则成u和v是强连通的。强连通分量:如果一个有向图G不是强连通图,那么可以把它分成躲个子图,其中每个子图的内部是强连通的,而且这些子图已经扩展到最大,不能与子图外的任一点强连通,成这样的一个“极大连通”子图是G的一个强连通分量(SCC)。强连通分量的一些性质:(1)一个点必须有出度和入度,才会与其他点强连通。(2)把一个SCC从图中挖掉,不影响其他点的强连通性。_强连通分量

Django(2)|templates模板+静态资源目录static_django templates-程序员宅基地

文章浏览阅读3.9k次,点赞5次,收藏18次。在做web开发,要给用户提供一个页面,页面包括静态页面+数据,两者结合起来就是完整的可视化的页面,django的模板系统支持这种功能,首先需要写一个静态页面,然后通过python的模板语法将数据渲染上去。1.创建一个templates目录2.配置。_django templates

linux下的GPU测试软件,Ubuntu等Linux系统显卡性能测试软件 Unigine 3D-程序员宅基地

文章浏览阅读1.7k次。Ubuntu等Linux系统显卡性能测试软件 Unigine 3DUbuntu Intel显卡驱动安装,请参考:ATI和NVIDIA显卡请在软件和更新中的附加驱动中安装。 这里推荐: 运行后,F9就可评分,已测试显卡有K2000 2GB 900+分,GT330m 1GB 340+ 分,GT620 1GB 340+ 分,四代i5核显340+ 分,还有写博客的小盒子100+ 分。relaybot@re...

推荐文章

热门文章

相关标签