Android利用Intent读取和更新通讯录

一、简介
本节演示如何在安卓系统中通过用户配置文件(user profile)读取和更新该手机的所有联系人信息,以及如何导航到用户配置文件中的这些联系人。

二、基本概念
 1、什么是 User Profile

用户配置文件(user profile)保存的是机主信息以及该手机中所有联系人的信息。

假定手机所有者的名字为“Mao mao yu”,那么,user profile保存的就是“Mao mao yu”的通讯录(即机主所有联系人的姓名、电话、邮箱、……等信息)。在Android 4中,这个保存联系人信息的应用程序称为“People app”,而在Android 5.0及更高版本中,这个应用程序又改称为“Contacts app” 。

Android 6.0(API 23)模拟器已经包含了【通讯录】功能,利用它可直接手工添加手机所有者姓名及其联系人,如下图所示:

单击【通讯录】中的某个联系人,例如单击机主的名字(或者其他联系人的名字),就可以在显示的界面中修改这个人的姓名、电话、邮箱、住址等信息,或者添加新联系人,这个功能大家在手机上用的太熟了,这里就不多说了。

我们这一节的目标就是学习如何在自己的应用程序中通过代码去添加或修改这个用户配置文件(user profile)中的信息,而不是用它自身提供的功能去编辑。

2、权限要求

要在你的程序中读和写手机所有联系人的数据,你的应用程序必须具有Read_Contacts和Write_Contacts权限。另外,要读取和编辑用户配置文件(user profile),你的应用程序必须具有Read_Profile和Write_Profile权限。

或者说,必须具有下面的权限才能读写通讯录和机主的用户配置文件:

READ_CONTACTS

READ_PROFILE

WRITE_CONTACTS

WRITE_PROFILE

实际上,你手机上下载的各类应用程序,只要有对应的权限,都可以获取和修改你的通讯录(一般手机用户都不是搞计算机的,因此也不太关心什么权限不权限,直接按下一步点下去,结果是默认都给这些程序赋予了完全的读写权限)。或者说,只要你给这些应用程序赋予了对应的读写权限,那么你的通讯录实际上就没有一点安全可言了,这些程序想什么时候获取就可以什么时候获取(泄露出去真是太简单了),这也是为什么有那么多免费的手机应用拼命让你去下载和使用的原因。

下图是在VS2015中设置Read_Contacts和Read_Profile的办法(通过单击主菜单【项目】下的【属性】弹出此界面):

按照同样的办法,可继续设置WRITE_CONTACTS和WRITE_PROFILE权限。

3、获取通讯录信息(Reading Profile Data)

安卓早期的版本是通过ContactContracts.Contacts类来获取手机上所有联系人的列表信息的。从Android 4开始又提供了一个新的ContactsContact.Profile类,该类提供了对设备所有者用户配置文件(user profile)的访问,利用它即可获取和修改所有联系人的名称、电话号码等数据。

向 ContactsContact.Profile.ContentUri 发出查询即可读取配置文件的数据。例如,下面的代码读取该用户配置文件的显示名称:

var uri = ContactsContract.Contacts.ContentUri; string[] projection = { ContactsContract.Contacts.InterfaceConsts.DisplayName }; var cursor = ContentResolver.Query(uri, projection, null, null, null); if (cursor.MoveToFirst ()) { Console.WriteLine(cursor.GetString (cursor.GetColumnIndex (projection [0]))); }

4、更新联系人信息(Update the User's Profile)

应用程序只要有对应的读写权限,就可以像其他普通的应用程序一样与用户配置文件(user profile)中的数据进行交互。例如,调用ContentResolver.Update方法可更新配置文件中的显示名称,该方法通过ContactsContract.Profile.ContentRawContactsUri属性检索Uri,如下面的代码所示:

var values = new ContentValues (); values.Put (ContactsContract.Contacts.InterfaceConsts.DisplayName, "Mao mao yu"); ContentResolver.Update (ContactsContract.Profile.ContentRawContactsUri,values, null, null);

注意:不能显式创建用户配置文件(user's profiile),否则将出现异常。

接下来,可创建一个ReadBackName方法,如下面的代码所示。调用此方法可验证添加到用户配置文件的名称是否确实被更新了。在这个方法中,首先获取用户的配置文件的 URI 并配置投影,从此配置文件中仅仅读取一列 (用户的显示名称)。为了访问用户的配置文件数据,接下来创建了一个游标对象。如果成功地初始化游标,则它被移动到用户配置文件中的第一项。在此位置 (用户显示名称) 的第一列中读取名称并将其打印到控制台。如果这些操作成功,ReadBackName 返回 true;否则返回 false。

bool ReadBackName() { Android.Net.Uri uri = ContactsContract.Profile.ContentUri; string[] projection = { ContactsContract.Contacts.InterfaceConsts.DisplayName }; var cursor = ContentResolver.Query(uri, projection, null, null, null); if (cursor != null) { if (cursor.MoveToFirst()) { Console.WriteLine(cursor.GetString(cursor.GetColumnIndex(projection[0]))); return true; } } return false; }

添加一个ViewProfile方法,该方法会自动调用Contacts App显示user profile中的信息:

void ViewProfile () { Intent intent = new Intent (Intent.ActionView, ContactsContract.Profile.ContentUri); StartActivity (intent); }

注意:仅在Android 4及更高版本中才可以使用手机所有者的用户配置文件。另外,在用户配置文件可以更新之前,必须先手动创建联系人。

关于ContactContracts.Profile 的更多信息,请参见 ContactsContract.Profile 类。

三、示例—ch1204ReadContacts
 本示例演示如何获取通讯录中的联系人。

1、运行截图

单击【读取通讯录】按钮,即得到下面右侧的截图。

单击【修改机主信息】按钮,即得到下面的修改界面:

下图是在Android 4.4.2(API 19)下运行的结果:

2、主要设计步骤

(1)设置权限

在VS2015开发环境下,选择主菜单的【项目】à【ContactsDemo属性】,在弹出的窗口中勾选下面的权限:

READ_CONTACTS

READ_PROFILE

WRITE_CONTACTS

WRITE_PROFILE

或者在【解决方案资源管理器】中,鼠标双击项目的【Properties】进入设置界面,然后勾选上面的选项。

设置完毕后,在AndroidManifest.xml文件中就会自动添加下面的代码:

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

(2)添加改ch1204_Main.axml文件

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:background="@android:color/background_light" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:text="读取通讯录" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/btnRead" /> <Button android:text="修改机主信息" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/btnUpdate" /> </LinearLayout>

(3)添加ch1204_ContactListItem.axml文件

在Resources/layout/下添加该文件。

<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="15dip" />

(4)添加ch1204ReadContactActivity.cs文件

using System.Collections.Generic; using Android.App; using Android.Content; using Android.OS; using Android.Widget; using Android.Provider; namespace MyDemos.SrcDemos { [Activity(Label = "【例12-4】读取和更新通讯录")] public class ch1204ReadContactActivity : ListActivity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); var uri = ContactsContract.Contacts.ContentUri; string[] projection = { ContactsContract.Contacts.InterfaceConsts.Id, ContactsContract.Contacts.InterfaceConsts.DisplayName }; var cursor = ContentResolver.Query(uri, projection, null, null, null); var contactList = new List<string>(); if (cursor.MoveToFirst()) { do { contactList.Add(cursor.GetString(cursor.GetColumnIndex(projection[1]))); } while (cursor.MoveToNext()); } cuesor.Close(); ListAdapter = new ArrayAdapter<string>(this, Resource.Layout.ch1204_ContactListItem, contactList); } } }

注意该类继承自ListActivity,不是继承自Activity。

(5)添加ch1204ReadContactsMain.cs文件

using Android.App; using Android.Content; using Android.OS; using Android.Widget; using Android.Provider; namespace MyDemos.SrcDemos { [Activity(Label = "【例12-4】读取和更新通讯录")] public class ch1204ReadContactsMain : Activity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.ch1204_Main); var btnRead = FindViewById<Button>(Resource.Id.btnRead); btnRead.Click += delegate { StartActivity(typeof(ch1204ReadContactActivity)); }; var btnUpdate = FindViewById<Button>(Resource.Id.btnUpdate); btnUpdate.Click += delegate { NameOwner(); if (ReadBackName()) { Intent intent = new Intent(Intent.ActionView, ContactsContract.Profile.ContentUri); StartActivity(intent); } }; } /// <summary> /// 定义手机机主的名字 /// </summary> void NameOwner() { ContentValues values = new ContentValues(); //将“Rainmj”插入到已存在的user profile中 values.Put(ContactsContract.Contacts.InterfaceConsts.DisplayName, "Rainmj"); //更新user profile ContentResolver.Update(ContactsContract.Profile.ContentRawContactsUri, values, null, null); } /// <summary> /// 检查“更新user profile”是否成功 /// </summary> /// <returns></returns> bool ReadBackName() { //获取user profile的Uri Android.Net.Uri uri = ContactsContract.Profile.ContentUri; //配置投影,指定准备从user profile中读取的列 string[] projection = { ContactsContract.Contacts.InterfaceConsts.DisplayName }; var cursor = ContentResolver.Query(uri, projection, null, null, null); if (cursor != null) { if (cursor.MoveToFirst()) { cursor.Close(); //Console.WriteLine(cursor.GetString(cursor.GetColumnIndex(projection[0]))); return true; } } return false; } } }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-09-20 04:05:52

Android利用Intent读取和更新通讯录的相关文章

Android利用Intent实现读取图片操作_Android

本文实例演示如何从图库(Gallery)中读取图像并用ImageView将它显示出来,供大家参考,具体内容如下 运行本示例前,需要先利用相机模拟拍摄一些图片到图库中. 1.运行截图    2.主要设计步骤 (1)添加ch1203_ReadGallery.axml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.androi

Android利用Intent实现记事本功能(NotePad)_Android

本文实例为大家分享了Intent如何实现一个简单的记事本功能的演示过程,供大家参考,具体内容如下 1.运行截图 单击右上角[-]会弹出[添加]菜单项,长按某条记录会弹出快捷菜单[删除]项. 2.主要设计步骤 (1)添加引用 鼠标右击[引用]à[添加引用],在弹出的窗口中勾选"System.Data"和"System.Data.SQlite",如下图所示: 注意:不需要通过NuGet添加SQLite程序包,只需要按这种方式添加即可. (2)添加图片 到Android

Android利用Intent实现读取图片操作

本文实例演示如何从图库(Gallery)中读取图像并用ImageView将它显示出来,供大家参考,具体内容如下 运行本示例前,需要先利用相机模拟拍摄一些图片到图库中. 1.运行截图 2.主要设计步骤 (1)添加ch1203_ReadGallery.axml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.c

Android利用Intent启动和关闭Activity_Android

一.简介 Android应用程序中一般都有多个Activity,在Activity中,通过调用StartActivity方法,并在该方法的参数中传递Intent对象,就可以实现不同Activity之间的切换和数据传递. 通过StartActivity方法传递intent对象来启动另一个Activity时,可分为两类: l 显式启动:在创建的Intent对象中明确指定启动的是哪个Activity: l 隐式启动:安卓系统根据Intent的动作和数据决定应该启动哪个Activity. 1.显式启动A

Android利用Intent实现记事本功能(NotePad)

本文实例为大家分享了Intent如何实现一个简单的记事本功能的演示过程,供大家参考,具体内容如下 1.运行截图 单击右上角[-]会弹出[添加]菜单项,长按某条记录会弹出快捷菜单[删除]项. 2.主要设计步骤 (1)添加引用 鼠标右击[引用]à[添加引用],在弹出的窗口中勾选"System.Data"和"System.Data.SQlite",如下图所示: 注意:不需要通过NuGet添加SQLite程序包,只需要按这种方式添加即可. (2)添加图片 到Android

Android利用Intent启动和关闭Activity

一.简介 Android应用程序中一般都有多个Activity,在Activity中,通过调用StartActivity方法,并在该方法的参数中传递Intent对象,就可以实现不同Activity之间的切换和数据传递. 通过StartActivity方法传递intent对象来启动另一个Activity时,可分为两类: l 显式启动:在创建的Intent对象中明确指定启动的是哪个Activity: l 隐式启动:安卓系统根据Intent的动作和数据决定应该启动哪个Activity. 1.显式启动A

Android开发之利用Intent实现数据传递的方法_Android

本文实例讲述了Android利用Intent实现数据传递的方法.分享给大家供大家参考,具体如下: 在Android开发过程中,很多人都熟悉Intent,这是个用于在多个View之间共享数据的类.本节主要讲述通过点选ListView中的文本,把文本中的URL加载到一个新的页面上,并且打印出来.为了方便,我先把前面一篇<Android开发之利用jsoup解析HTML页面的方法>的代码重新贴一下,因为在上一节后,代码做了少许修改: try { doc = Jsoup.parse(new URL(&q

Android开发之利用Intent实现数据传递的方法

本文实例讲述了Android利用Intent实现数据传递的方法.分享给大家供大家参考,具体如下: 在Android开发过程中,很多人都熟悉Intent,这是个用于在多个View之间共享数据的类.本节主要讲述通过点选ListView中的文本,把文本中的URL加载到一个新的页面上,并且打印出来.为了方便,我先把前面一篇<Android开发之利用jsoup解析HTML页面的方法>的代码重新贴一下,因为在上一节后,代码做了少许修改: try { doc = Jsoup.parse(new URL(&q

Android通讯录联系人的读取、更新、插入、删除等方法

TestContacts.java: package waga.android.study.TestContacts; import android.app.Activity; import android.content.ContentResolver; import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.provider.Contacts