Android · ContentProvider学习

 

一、Content Provider基本概念

1、ContentProvider为存储和获取数据提供了统一的接口。ContentProvide对数据进行封装,不用关心数据存储的细节。使用表的形式来组织数据。image

2、使用ContentProvider可以在不同的应用程序之间共享数据。

3、Android为常见的一些数据提供了默认的ContentProvider(包括音频、视频、图片和通讯录等)。

ContentProvider所提供的函数: query(),insert(),update(),delete(),getType(),onCreate()等。

 

二、URI统一资源标识符)的使用方法

为系统的每一个资源给其一个名字,比方说通话记录。

1、每一个ContentProvider都拥有一个公共的URI,这个URI用于表示这个ContentProvider所提供的数据。

2、Android所提供的ContentProvider都存放在android.provider包中。 将其分为A,B,C,D 4个部分:

image

A:标准前缀,用来说明一个Content Provider控制这些数据,无法改变的;"content://"

B:URI 的标识,它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的 类名。这个标识在元素的 authorities属性中说明:一般是定义该ContentProvider的包.类的名称;"content://hx.android.text.myprovider"

C:路径,通俗的讲就是数据库中要操作的表的名字

D:如果URI中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示返回全部

Uri写法1

Uri uri = Uri.parsecontent://media/internal/images") 这个URI将返回设备上存储的所有图片 
content://contacts/people/  这个URI将返回设备上的所有联系人信息
content://contacts/people/45 这个URI返回单个结果(联系人信息中ID为45的联系人记录)

Uri写法2

Uri person = ContentUris.withAppendedId(People.CONTENT_URI,  45);

然后执行数据查询:  Cursor cur = managedQuery(person, null, null, null);

这个查询返回一个包含所有数据字段的游标,我们可以通过迭代这个游标来获取所有的数据:

 

三、ContentProvider的使用

实现: 应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法

自己实现ContentProvider不常见,因为可能不需要和别的应用程序交换数据。

因此下面主要介绍ContentProvider的使用

  • 从Android 2.0 SDK开始有关联系人provider的类从android.provider.Contacts变成了android.provider.ContactsContract
  • ContactsContract的子类ContactsContract.Contacts是一张表,代表了所有联系人的统计信息。比如联系人ID(—ID),查询键(LOOKUP_KEY),联系人的姓名(DISPLAY_NAME_PRIMARY),头像的id(PHOTO_ID)以及群组的id等等
  • 在新的Contacts API中,联系人数据被安排三个主要的表中:contacts, raw contacts and data. 结构如下图所示:

一个contact(联系人)记录关联一个或多个RawContact(联系人来源,如Gmail)记录,每个RawContact记录又关联多个data(email, phone number等等)记录

 

 

package com.example.manhua;

import java.util.ArrayList;

import android.app.ListActivity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends ListActivity {
	
/*
 * ListActivity的默认布局由一个位于屏幕中心的全屏列表构成。
 * 如果你不想使用默认的布局,可以在onCreate()方法中通过setContentView()方法设定你自己的布局。
 * 如果指定你自己定制的布局,你的布局中必须包含一个id为"@id/android:list"的ListView。 
 * 若你还指定了一个id为"@id/android:empty"的view,当ListView中没有数据要显示时,
 * 这个view就会被显示,同时 ListView会被隐藏。
 * */
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//setContentView(R.layout.activity_main);
		displayRecords();
	}

	
	//  <uses-permission android:name="android.permission.READ_CONTACTS"/>
	private void displayRecords() {
		Uri contactsUri = ContactsContract.Contacts.CONTENT_URI;
		// 该数组中包含了所有要返回的字段
		String proj1[] = new String[] { ContactsContract.Contacts.DISPLAY_NAME,
				ContactsContract.Contacts.HAS_PHONE_NUMBER , ContactsContract.Contacts.LOOKUP_KEY};
		// declare a ArrayList object to store the data that will present to the
		// user
		Cursor curContacts = getContentResolver().query(contactsUri, proj1,
				null, null, null);
		ArrayList<String> contactsList = new ArrayList<String>();
		String allPhoneNo = "";
		if (curContacts.getCount() > 0) {
			while (curContacts.moveToNext()) {
				// get all the phone numbers if exist
				if (curContacts.getInt(1) > 0) {
					allPhoneNo = getAllPhoneNumbers(curContacts.getString(2));
				}
				contactsList.add(curContacts.getString(0) + " , " + allPhoneNo);
				allPhoneNo = "";
			}
		}
		// binding the data to ListView
		setListAdapter(new ArrayAdapter<String>(this,
				android.R.layout.simple_list_item_1, contactsList));
		ListView lv = getListView();
		lv.setTextFilterEnabled(true);
	}

	/**
	 * Get all the phone numbers of a specific contact person
	 * 
	 * @param lookUp_Key
	 *            lookUp key for a specific contact
	 * @return a string containing all the phone numbers
	 */
	public String getAllPhoneNumbers(String lookUp_Key) {
		String allPhoneNo = "";

		// Phone info are stored in the ContactsContract.Data table
		Uri phoneUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
		String[] proj2 = { ContactsContract.CommonDataKinds.Phone.NUMBER };
		// using lookUp key to search the phone numbers
		String selection = ContactsContract.Data.LOOKUP_KEY + "=?";

		Cursor cur = getContentResolver().query(phoneUri, proj2, selection,
				new String[] { lookUp_Key }, null);
		while (cur.moveToNext()) {
			allPhoneNo += cur.getString(0) + " ";
		}

		return allPhoneNo;
	}
}

 

由于读取联系人比较的占用资源,为了提高用户的体验度。考虑将读取的过程放在线程里完成,推荐使用AsyncTask类

posted @ 2014-12-10 10:58  Man_华  阅读(189)  评论(0编辑  收藏  举报