前一天我们学习了学习了通过Intent实现打开指定文件的方法。Intent是安卓程序种各组件之间进行交互的一种重要方式,通过指定它的标志、动作、数据以及类型,可以用指定的程序打开文件。
今天将学习读取安卓系统的通信录,效果如图1所示。
图1 读取通信录效果
读取通信录程序的流程主要分为两个步骤:第一个步骤是从安卓系统中得到通信录的数据;第二个步骤是将数据显示在界面中。
1 通信录数据的获取
通信录中的主要包含两种数据,一种是联系人姓名,另外一种是联系人号码。因此,首先定义一个类来表示通信录中的数据。
1.1 定义通信录数据类
在Eclipse中新建一个名为“GetMyPhoneNumber”的安卓项目,在“GetMyPhoneNumber->src->com.example.getmyphonenumber”包的右键菜单中选择“New->Class”,为项目添加一个名为“PhoneInfo”的类。该类表示通信录中的一个数据,即联系人姓名和联系人号码。
1.1.1 定义类的变量
该类包含两个String类型的变量,即姓名和和号码。
private StringphoneName;
private StringphoneNumber;
1.1.2 定义类的构造函数
该类的构造函数包含两个参数,即姓名和号码,并把这两个参数赋值给类的变量。
public PhoneInfo(String phoneName, String phoneNumber){
this.phoneName = phoneName;
this.phoneNumber = phoneNumber;
}
1.1.3 定义类的方法
由于该类中表示姓名和号码的变量都是私有的,因此外部不能直接访问这两个变量,需要定义定义方法来访问。
public String getPhoneName()
{
returnphoneName;
}
public String getPhoneNumber()
{
returnphoneNumber;
}
另外,还需要定义设置电话号码的方法
public void setPhoneNumber(String phoneNumber)
{
this.phoneNumber = phoneNumber;
}
1.2 定义获取通信录数据的类
在“GetMyPhoneNumber->src->com.example.getmyphonenumber”包的右键菜单中选择“New->Class”,为项目添加一个名为“GetNumber”的类。该类用来获取通信录中的数据。
1.2.1 定义保存数据的变量
在“GetNumber”类中,首先定义一个变量来保存通信录中的数据。
public static List<PhoneInfo> lists =new ArrayList<PhoneInfo>();
其中,List表示该变量是一个列表类型的变量,列表中的元素是在“1.1”中定义的PhoneInfo类;通过new关键字创建了ArrayList类的对象。将该变量定义为static的原因是,“GetNumber”类中获取通信录数据的方法是static的,因为static方法只能使用static的变量,因此将lists也定义为static。
1.2.2 定义获取数据的方法
在GetNumber”类中,定义一个名为“getNumber”的方法,在“1.2.1”中提到,该方法为static。
public static void getNumber(Contextcontext){
........
}
其中,参数context表示本应用程序的上下文。
(1)查询通信录
在getNumber()方法中,使用ContentResolver类对通信录进行查询。
在安卓系统中,每一个应用程序的数据都是采用私有的形式进行操作的,即这些数据都不能被外部应用程序所访问。如果我们的程序要访问通信录中的数据,就要使用内容提供器(ContentProvider)类,该类的主要功能是将不同的应用程序的数据操作标准统一起来。内容提供器类在程序操作中所提供的是一个操作的标准,所以如果想依靠此标准进行数据操作,就必须使用ContentResolver类。
在“getNumber”方法中,有如下代码:
Cursor cursor =context.getContentResolver().query(Phone.CONTENT_URI,null,null,null,null);
其中,context是“getNumber”方法的参数,表示本应用程序的上下文,通过该变量调用了Context类的getContentResolver()方法获取到了本应用程序包的ContentResolver类的实例;通过该实例调用ContentResolver类的query()方法对通信录进行查询,query()方法的格式为
public final Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
其中,参数uri要查询的内容(Uri类见“基于Java语言的安卓编程学习之文件打开”);projection指定了要查询哪些列的数据;selection指定了要查询哪些行的数据;selectionArgs指定了要查询的行的数量;sortOrder指定了行排列的顺序。返回值是游标(Cursor)接口的对象,游标接口用来指定数据库读写结果,可以通过Cursor接口的方法将数据逐一读出。
在以上代码中,query()方法的第一个参数Phone.CONTENT_URI表示通信录的URI,后面四个参数均设置为null,表示查询通信录中的所有行及所有列的数据,获取的通信录的数据用cursor来表示。
(2)读取通信录数据
接下来定义两个String类型的变量用来保存通信录中的姓名和号码。
String phoneNumber;
String phoneName;
之后,通过游标遍历通信录中的数据
while(cursor.moveToNext()){
phoneNumber=cursor.getString(cursor.getColumnIndex(Phone.NUMBER));
phoneName=cursor.getString(cursor.getColumnIndex(Phone.DISPLAY_NAME);
........
}
其中,moveToNext()方法的作用是将游标移动到下一行,即读取通信录的下一个数据,如果当前行已经是数据中的最后一行,则返回false,否则返回true;getString()方法的作用是获取指定列的数据,该方法的参数是指定列的索引值,而getColumnIndex()方法的作用是获取指定列的索引值,其中Phone.NUMBER表示号码列,Phone.DISPLAY_NAME表示姓名列。通过以上代码实现了遍历通信录中所有的姓名和号码。
(3)数据加入列表
在while()语句中,获取到了姓名和号码之后,接下来定义自定义类PhoneInfo的对象,之后将该对象加入到列表中。
PhoneInfo info = new PhoneInfo(phoneName, phoneNumber);
lists.add(info);
其中,phoneName和phoneNumber是获取到的姓名和号码,info是自定义类PhoneInfo的对象,最后通过List类的add方法将新建的info加入到列表lists中。