Android ContentProvider共享数据

ContentProvider的基本概念
a.ContentProvider为存储和读取数据提供了统一的接口
b.使用ContentProvider,应用程序可以实现数据共享
c.android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)

1.数据模型
Content Provider 将其存储的数据以数据表的形式提供给访问者,在数据表中每一行为一条记录,每一列为具有特定类型和意义的数据。每一条数据记录都包括一个 "_ID" 数值字段,改字段唯一标识一条数据。

2.Uri
Uri,每一个Content Provider 都对外提供一个能够唯一标识自己数据集(dataset)的公开URI, 如果一个Content Provider管理多个数据集,其将会为每个数据集分配一个独立的URI。所有的Content Provider 的URI 都以"content://" 开头,其中"content:"是用来标识数据是由Content Provider管理的 schema。

在几乎所有的Content Provider 的操作中都会用到Uri,因此一般来讲,如果是自己开发的Content Provider,最好将URI定义为常量,这样在简化开发的同时也提高了代码的可维护性。

我们将Uri分为A,B,C,D 4个部分:

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

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

C:路径,Uri下的某一个Item,就像网站一样,主网页下包含很多小网页。这里通俗的讲就是你要操作的数据库中表的名字(比如我操作的表为person),或者你也可以自己定义,记得在使用的时候保持一致就ok了,如"content://com.lamp.provider.personprovider/person"

D:如果Uri中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示对全部记录进行操作,例如content://com.lamp.provider.personprovider/person 针对表中所有记录
content://com.lamp.provider.personprovider/person/5 针对id为5的记录

UriMatcher:用于匹配Uri,它的用法如下:
1.首先把你需要匹配Uri路径全部给注册上。

1.常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码(-1)。
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

2.注册匹配的Uri
//content://com.lamp.provider.personprovider/person 针对表中所有记录,如果匹配该路径,返回1
uriMatcher.addURI(authority, "person", 1);

//content://com.lamp.provider.personprovider/person/# 针对符合条件的记录,如果匹配该路径,返回2
uriMatcher.addURI(authority, "person/#",2);


3.注册完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法对输入的Uri进行匹配,如果匹 配就返回匹配码,匹配码是调用 addURI()方法传入的第三个参数,假设匹配 content://com.lamp.provider.personprovider/person 路径,返回的匹配码为1。

ContentUris:用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
withAppendedId(uri, id)用于为路径加上ID部分
parseId(uri)方法用于从路径中获取ID部分


下面是一个小例子来说明ContentProvider的使用
1.新建一个类来继承ContentProvider

package com.lamp.db;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.text.TextUtils;

import com.lamp.service.DataBaseOpenHelper;

public class PersonContentProvider extends ContentProvider {

private DataBaseOpenHelper dbHelper = null;
private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final int ALLPERSON = 1;
private static final int PERSON = 2;
private static final String authority = "com.lamp.provider.personprovider";
private static String TABLENAME = "person";
static{
//content://com.lamp.provider.personprovider/person 针对表中所有记录,如果匹配该路径,返回1
uriMatcher.addURI(authority, TABLENAME, ALLPERSON);

//content://com.lamp.provider.personprovider/person/# 针对符合条件的记录,如果匹配该路径,返回2
uriMatcher.addURI(authority, TABLENAME + "/#", PERSON);
}

@Override
public boolean onCreate() {
dbHelper = new DataBaseOpenHelper(this.getContext());
return true;
}

//删除数据
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase database = dbHelper.getWritableDatabase();
int count = 0;
switch (uriMatcher.match(uri)) {
case ALLPERSON:
count = database.delete(TABLENAME, selection, selectionArgs);
break;
case PERSON:
long personid = ContentUris.parseId(uri);
String where = TextUtils.isEmpty(selection)?"personid=?":selection + " personid=?";
String[] params = new String[]{String.valueOf(personid)};
if(!TextUtils.isEmpty(selection) && selectionArgs!=null){
params = new String[selectionArgs.length+1];
for (int i = 0; i < selectionArgs.length; i++) {
params[i] = selectionArgs[i];
}
params[selectionArgs.length] = String.valueOf(personid);
}
count = database.delete(TABLENAME, where, params);
break;
default:
throw new IllegalArgumentException("参数错误" + uri);
}
return count;
}

@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case ALLPERSON:
return "vnd.android.cursor.dir/personprovider.person";
case PERSON:
return "vnd.android.cursor.item/personprovider.person";
default:
throw new IllegalArgumentException("参数错误" + uri);
}
}

//插入数据
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase database = dbHelper.getWritableDatabase();
long id = 0;
switch (uriMatcher.match(uri)) {
case ALLPERSON:
id = database.insert(TABLENAME, "name", values);
return ContentUris.withAppendedId(uri, id);
case PERSON:
id = database.insert(TABLENAME, "name", values);
String uriString = uri.toString();
uriString = uriString.substring(0, uriString.lastIndexOf("/")) + id;
return Uri.parse(uriString);
default:
throw new IllegalArgumentException("参数错误" + uri);
}
}


//查询数据
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
SQLiteDatabase database = dbHelper.getWritableDatabase();
switch (uriMatcher.match(uri)) {
case ALLPERSON:
return database.query(TABLENAME, projection, selection, selectionArgs, null, null, sortOrder);
case PERSON:
long personid = ContentUris.parseId(uri);
String where = TextUtils.isEmpty(selection)?"personid=?":selection + " personid=?";
String[] params = new String[]{String.valueOf(personid)};
if(!TextUtils.isEmpty(selection) && selectionArgs!=null){
params = new String[selectionArgs.length+1];
for (int i = 0; i < selectionArgs.length; i++) {
params[i] = selectionArgs[i];
}
params[selectionArgs.length] = String.valueOf(personid);
}
return database.query(TABLENAME, projection, where, params, null, null, sortOrder);
default:
throw new IllegalArgumentException("参数错误" + uri);
}
}

//更新数据
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase database = dbHelper.getWritableDatabase();
int count = 0;
switch (uriMatcher.match(uri)) {
case ALLPERSON:
count = database.update(TABLENAME, values, selection, selectionArgs);
break;
case PERSON:
long personid = ContentUris.parseId(uri);
String where = TextUtils.isEmpty(selection)?"personid=?":selection + " personid=?";
String[] params = new String[]{String.valueOf(personid)};
if(!TextUtils.isEmpty(selection) && selectionArgs!=null){
params = new String[selectionArgs.length+1];
for (int i = 0; i < selectionArgs.length; i++) {
params[i] = selectionArgs[i];
}
params[selectionArgs.length] = String.valueOf(personid);
}
count = database.update(TABLENAME, values, where, params);
break;
default:
throw new IllegalArgumentException("参数错误" + uri);
}
return count;
}

}



2.在AndroidManifest.xml对ContentProvider进行配置,为了能使其它应用能找到该ContentProvider,ContentProvider采用了android:authorities对它进行唯一标识,你可以把ContentProvider看成是一个网站,authorities就是它的域名

<application android:icon="@drawable/icon" android:label="@string/app_name">
<uses-library android:name="android.test.runner" />

<provider android:name=".PersonContentProvider" android:authorities="com.lamp.provider.personprovider"/>
.....


3.由于我操作的数据是针对数据库,新建一个类继承SQLiteOpenHelper

package com.lamp.service;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DataBaseOpenHelper extends SQLiteOpenHelper {
private static final String DBNAME = "android";
private static final int VERSION = 1;

public DataBaseOpenHelper(Context context) {
super(context, DBNAME, null, VERSION);
}

@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
String sql = "create table person (personid integer primary key autoincrement,name varchar(20),age integer)";
sqLiteDatabase.execSQL(sql);
}

@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
String sql = "drop table if exists person";
sqLiteDatabase.execSQL(sql);
onCreate(sqLiteDatabase);
}

}



4.用到的实体bean为Person

package com.lamp.domain;

public class Person {
private Integer personid = null;
private String name = null;
private Integer age = null;
public Person() {
}
public Person(String name,Integer age){
this.name = name;
this.age = age;
}
public Integer getPersonid() {
return personid;
}
public void setPersonid(Integer personid) {
this.personid = personid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "personid:" + this.personid + "name: " + this.name + ", age:" + this.age;
}

}



至此ContentProvider的配置完成,将项目部署到模拟器或者手机中,下面来编写一个新的应用来对上一个应用的数据进行测试

1.新建一个新的项目

package com.lamp.provider;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;

public class PersonProviderTestActivity extends Activity {
private static final String TAG = "PersonProviderTestActivity";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

ContentResolver cr = this.getContentResolver();
//通过唯一的Uri对特定的应用进行数据的操作
Uri uri = Uri.parse("content://com.lamp.provider.personprovider/person");

//插入数据
/*
uri = Uri.parse("content://com.lamp.provider.personprovider/person");
ContentValues values = new ContentValues();
values.put("name", "kang");
values.put("age", 35);
Uri uris = cr.insert(uri, values);
*/

//查询数据,此处是查询personid=13的记录
/* Uri uri = Uri.parse("content://com.lamp.provider.personprovider/person/13");
Cursor cursor = cr.query(uri, new String[]{"personid","name","age"}, null, null, null);
while(cursor.moveToNext()){
Log.i(TAG, cursor.getInt(0) + " name:" + cursor.getString(1));
}
cursor.close();*/


//测试删除,此处是删除personid=10的记录
uri = Uri.parse("content://com.lamp.provider.personprovider/person/10");
int count = cr.delete(uri, null, null);
Log.i(TAG, String.valueOf(count));


//测试更新,此处是更新personid=14的记录
/*
uri = Uri.parse("content://com.lamp.provider.personprovider/person/14");
ContentValues values2 = new ContentValues();
values2.put("name", "aaaaa");
values2.put("age", 35);
int count = cr.update(uri, values2, null, null);
Log.i(TAG, String.valueOf(count));
*/
}
}


记得在AndroidManifest.xml中注册权限

<uses-permission android:name="android.permission.READ_CONTACTS" />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值