基于Java语言的安卓编程之二十五通信录读取(上)

时间:2021-08-25 00:47:50

前一天我们学习了学习了通过Intent实现打开指定文件的方法。Intent是安卓程序种各组件之间进行交互的一种重要方式,通过指定它的标志、动作、数据以及类型,可以用指定的程序打开文件。

今天将学习读取安卓系统的通信录,效果如图1所示。

基于Java语言的安卓编程之二十五通信录读取(上)

图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中。