官方API解释:
‘Content providers are one of the primary building blocks of Android applications, providing content to applications. They encapsulate data and provide it to applications through the single [ContentResolver]
interface. A content provider is only required if you need to share data between multiple applications. For example, the contacts data is used by multiple applications and must be stored in a content provider. If you don't need to share data amongst multiple applications you can use a database directly via [SQLiteDatabase]
.
详细信息参考API文档
二:内容提供者使用步骤
- 1,添加一个路径匹配器 详情见API文档
- 2,在静态代码块中添加匹配规则
- 3,暴露你想暴露的方法
示例代码:
1,创建工程 创建数据库表
2,创建一个类继承ContentProvider
3,在清单文件中注册内容提供者 添加一个要提示的属性
4,进行一系列的操作
/**
* 内容提供者的使用步骤
* @author Administrator
*
*/
public class MyProvider extends ContentProvider {
//[1]定义路径匹配器 详情见API文档
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final int QUERYSECCEED = 0;
private static final int INSERTSECCEED = 1;
private static final int UPDATESECCEED = 2;
private static final int DELETESECCEED = 3;
private MyOpenHelper helper;
//[2]在静态代码块中定义匹配规则 详情见API文档
static
{
/*
* addURI(String authority, String path, int code)
* authority:在清单文件中注册时候设置的authority com.mmk.provider
* path:要匹配的路径 这里的一个完整的uri路径 com.mmk.provider/query
* code:返回值
*/
sURIMatcher.addURI("com.mmk.provider", "query", QUERYSECCEED);
sURIMatcher.addURI("com.mmk.provider", "insert", INSERTSECCEED);
sURIMatcher.addURI("com.mmk.provider", "update", UPDATESECCEED);
sURIMatcher.addURI("com.mmk.provider", "delete", DELETESECCEED);
}
//初始化内容提供者
//在这里实例化数据库助手
@Override
public boolean onCreate() {
helper = new MyOpenHelper(getContext());
return false;
}
//[3]暴露自己想暴露的方法 (增删改查)
//数据库的查询操作
/* Uri uri:要匹配的路径
* String[] projection:The list of columns to put into the cursor. If null all columns are included
* 上面这行参数 要查询的列 null代表所有列
* String selection:查询的条件
* String[] selectionArgs:查询的条件的值
* String sortOrder:根据什么排序 null表示不排序
* (non-Javadoc)
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
//判断路径是否匹配正确
int code = sURIMatcher.match(uri);
//匹配正确 实现查询操作
if (code == QUERYSECCEED) {
//对数据库的操作必须获取SQLiteDatabase实例
SQLiteDatabase db = helper.getWritableDatabase();
Cursor cursor = db.query("info", projection, selection, selectionArgs, null, null, sortOrder);
return cursor;
} else {
throw new IllegalArgumentException("你的路径匹配不正确");
}
}
@Override
public String getType(Uri uri) {
return null;
}
//暴露数据库的添加数据方法
@Override
public Uri insert(Uri uri, ContentValues values) {
int code = sURIMatcher.match(uri);
if (code == INSERTSECCEED) {//进行添加操作
SQLiteDatabase db = helper.getWritableDatabase();
//返回值:the row ID of the newly inserted row, or -1 if an error occurred
//代表新插入的行的ID
long insert = db.insert("info", null, values);
//返回值是Uri类型 构建一个Uri对象
Uri uri2 = Uri.parse("com.zhang.insert/"+insert);
return uri2;
} else {
throw new IllegalArgumentException("你的路径不匹配");
}
}
//暴露删除方法
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int code = sURIMatcher.match(uri);
if (code == DELETESECCEED) {
SQLiteDatabase db = helper.getWritableDatabase();
//返回值 代表影响的行数
int delete = db.delete("info", selection, selectionArgs);
return delete;
} else {
throw new IllegalArgumentException("你的路径不匹配");
}
}
//暴露更新方法
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int code = sURIMatcher.match(uri);
if (code == UPDATESECCEED) {
SQLiteDatabase db = helper.getWritableDatabase();
//返回值代表影响的行数
int update = db.update("info", values, selection, selectionArgs);
return update;
} else {
throw new IllegalArgumentException("你的路径不匹配");
}
}
}
5,如果在日志中打印一些内容 则说明内容提供者提供内容成功
6,新建工程 获取内容解析者 对上一个工程的数据库进行操作
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void clickUpdate(View v) {
Uri uri = Uri.parse("content://com.mmk.provider/update");
ContentValues values = new ContentValues();
values.put("name", "杨子珊");
int update = getContentResolver().update(uri, values, "name=?", new String[]{"zhang"});
System.out.println(update);
}
public void clickDelete(View v) {
Uri uri = Uri.parse("content://com.mmk.provider/delete");
int delete = getContentResolver().delete(uri, "phone=?", new String[]{"1055"});
System.out.println(delete);
}
public void clickAdd(View v) {
Uri uri = Uri.parse("content://com.mmk.provider/insert");
ContentValues values = new ContentValues();
values.put("name", "zhang");
values.put("phone", "123");
Uri uri2 = getContentResolver().insert(uri, values);
System.out.println(uri);
System.out.println(uri2);
}
/**
* 点击事件
* 内容解析者解析上一个应用的数据
* @param v
*/
public void clickQuery(View v) {
//获取内容解析者实例
ContentResolver resolver = getContentResolver();
//读数据库进行操作
//uri:uri The URI, using the content:// scheme, for the content to retrieve.
Uri uri = Uri.parse("content://com.mmk.provider/query");
Cursor cursor = resolver.query(uri, null, null, null, null);
if (cursor != null && cursor.getCount() >= 0) {
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String phone = cursor.getString(2);
System.out.println("name:"+name +" phone:"+phone);
}
}
cursor.close();
}
}
注意:如果内容提供者中的而数据库改变了 在运行内容解析者工程之前 要先运行内容提供者工程
三:内容解析者获取手机中的联系人
1,来到这个路径下 到处该联系人数据库表
2,解读三张表
-
data表 data1这一列表示了所有联系人的所有信息
-
data表 raw_contact_id这一列 事实上就是 raw_contact表 中的 contact_id这一列
-
data表 mimetype列对应 mimetype表
3,读取手机联系人的步骤:
-
[1] 先读取raw_contact表 中的contact_id字段 从而知道一共有多少个联系人
-
[2]再读取data表 根据raw_contact_id字段读取data1字段和mimetype_id字段
看源码的步骤:
1,这个路径下的清单文件 找到
2,来到ContactsProvider2.java 文件下
示例代码:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getContacts();//获取手机联系人
}
/**
* 获取手机联系人方法
*/
private void getContacts() {
//手机联系人数据库已经用内容提供者暴露出来 用该内容解析者来获取数据
//[1]读取raw_contact表 查询contact_id字段 从而知道一共有多少联系人
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
Uri dataUri = Uri.parse("content://com.android.contacts/data");
Cursor cursor = getContentResolver().query(uri, new String[]{"contact_id"}, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
//这里的contact_id就是返回了当前手机联系人个数的id
String contact_id = cursor.getString(0);
// System.out.println("contact_id = "+contact_id);
//[2]根据raw_contact_id字段查询 data表 中的data1字段和mimetype_id字段
// Cursor dataCursor = getContentResolver().query(dataUri, new String[]{"data1","mimetype_id"}, "raw_contact_id=?", new String[]{"contact_id"}, null);
//注意了 这里查询的并不是data表 而是view_data表 而该表中没有mimetype_id字段 只有mimetype字段
Cursor dataCursor = getContentResolver().query(dataUri, new String[]{"data1","mimetype"}, "raw_contact_id=?", new String[]{contact_id}, null);
if (dataCursor != null && dataCursor.getCount() > 0) {
while (dataCursor.moveToNext()) {
String data1 = dataCursor.getString(0);
String mimetype = dataCursor.getString(1);
// System.out.println("data1:"+data1 + " mimetype:"+mimetype);
//根据mimetype来判断类型
if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) {
System.out.println("电话:"+data1);
} else if ("vnd.android.cursor.item/name".equals(mimetype)) {
System.out.println("姓名:"+data1);
}
}
}
}
}
}
}
网友评论