您的位置:首页 > 数据库

other工程想访问db工程下数据库,需要用到db的contentprovider.来共享数据.

2014-06-27 12:19 399 查看
//在db工程中,操作1.类继承

//contentprovider.暴露给别的应用去调用.

//在other应用中注册了一个内容观察者,如果发现内容提供者里面的额数据发生了改变,内容观察者就可以执行onchange方法.

//第二.在xml文件中声明.

//authorities表示的是主机名.

//content:// com.xxx.provider.myprovider /person/10

//scheme           主机名或authority           路径ID

路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:

要操作person表中id为10的记录,可以构建这样的路径:/person/10

要操作person表中id为10的记录的name字段, person/10/name

要操作person表中的所有记录,可以构建这样的路径:/person

要操作xxx表中的记录,可以构建这样的路径:/xxx

当然要操作的数据不一定来自数据库,也可以是文件等他存储方式,如下:

要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name

定义匹配规则

  根据数据库的表结构 定义匹配规则

content://cn.itcast.db.provider/person

content://cn.itcast.db.provider/person/10

也可以根据业务方法, 指定匹配规则

content://cn.itcast.db.provider/delete/10

<provider
android:authorities="cn.itcast.db.personprovider"
android:name=".provider.PersonProvider" >
</provider>
<pre class="java" name="code">package cn.itcast.db.provider;

import cn.itcast.db.MyDBOpenHelper;
import cn.itcast.db.dao.PersonDBDao;
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.util.Log;

public class PersonProvider extends ContentProvider {

public static final int ALL_PERSONS = 1;
public static final int PERSON = 2;
public static final int HAHA =3;
public static final int INSERT =4;
public static final int DELETE =5;
public static final int UPDATE =6;
private static final String TAG = "PersonProvider";
MyDBOpenHelper openHelper;
// 创建了一个路径的识别器 uriMatcher 默认的返回值,如果没有找到匹配的类型  返回 -1;
//UriMatcher路径适配器.UriMatcher.NO_MATCH若果没有找到匹配就返回-1;
public static final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
//现在暂时不用,一会用.person是表.
Uri baseuri = Uri.parse("content://cn.itcast.db.personprovider");
static {
matcher.addURI("cn.itcast.db.personprovider", "person", ALL_PERSONS);
// 指定一个路径的匹配规则
//如果路径 满足 content://cn.itcast.db.provider/person
//返回值就是( ALL_PERSONS) 1 ,匹配码

matcher.addURI("cn.itcast.db.personprovider", "person/#",PERSON );
//	 #号为通配符, 表示数字.
//如果路径 满足 content://cn.itcast.db.provider/person/10 返回值就是( PERSON) 2

matcher.addURI("cn.itcast.db.personprovider", "haha", HAHA);
//匹配规则二.业务需求
matcher.addURI("cn.itcast.db.personprovider", "insert", INSERT);
matcher.addURI("cn.itcast.db.personprovider", "delete", DELETE);
matcher.addURI("cn.itcast.db.personprovider", "update", UPDATE);

}

/**
* PeronProvder 内容提供者第一次被创建的时候 调用的方法
*/
@Override
public boolean onCreate() {
//在oncreat方法中实例化.
openHelper = new MyDBOpenHelper(getContext());
return false;
}
//参数uri表示查询数据所对应的地址.
//projection表示查询出来的结果的列.
//selection表示选择条件.selectionArgs表示选择条件所对应的参数.
//sortOrder表示查询结果是否排序.
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
//	result是匹配码
int result = matcher.match(uri);
switch (result) {
// 符合 content://cn.itcast.db.provider/persons 代表的返回所有的数据
case ALL_PERSONS:
PersonDBDao dao = new PersonDBDao(getContext());
return  dao.findAllbyCursor();
//content://cn.itcast.db.provider/person/10
case PERSON:
//获取数字10的方法.把路径后面的数字过滤出来
long id = ContentUris.parseId(uri);
//在这里,我们通过直接查询数据库.
SQLiteDatabase db = openHelper.getReadableDatabase();
if(db.isOpen()){
//第二个参数写null表示所有列都显示.第三个参数是查询条件.第四个参数是查询条件的参数,之后是分组条件,查询条件,排序条件
Cursor cursor = db.query("person", null, "personid=?", new String[]{id+""}, null, null, null);
return cursor;
}

case HAHA:
Log.i(TAG,"我是haha对应的路径 ");
break;
default:
//非法参数的异常.
throw new IllegalArgumentException("uri 不能被识别 ");
}
return null;
}

/**
* 有的时候 我们需要知道内容提供者返回的数据类型
* 知道返回的数据 是一个集合呀 还是一个单独的条目
*
* 用于返回当前Url所代表数据的MIME类型
* 。如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,
* 例如:要得到所有person记录的Uri为content://cn.itcast.provider.personprovider/person,
* 那么返回的MIME类型字符串应该为:“vnd.android.cursor.dir/person”。
*如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,
* 例如:得到id为10的person记录,Uri为content://cn.itcast.provider.personprovider/person/10,
*那么返回的MIME类型字符串应该为:“vnd.android.cursor.item/person”。
* 有的时候 告诉调用者 返回的数据是什么样的类型  例如.mp3
* mime的数据类型
*/
@Override
public String getType(Uri uri) {
int result = matcher.match(uri);
switch (result) {
// 符合 content://cn.itcast.db.provider/persons 代表的返回所有的数据
case ALL_PERSONS:
return "vnd.android.cursor.dir/people";
//content://cn.itcast.db.provider/person/10
case PERSON:
return "vnd.android.cursor.item/people";
default :
return null;
}
}

@Override
public Uri insert(Uri uri, ContentValues values) {
// content://cn.itcast.db.provider/insert
int result = matcher.match(uri);

switch (result) {
case INSERT:
SQLiteDatabase db = openHelper.getWritableDatabase();
db.insert("person", "personid", values);
// 当数据发生改变的时候 ,因为执行了inset方法操作数据库添加.
//给某个uri发出数据发生改变的通知.观察者.
//第二个参数是contentobserver.内容观察者,我们可以显示的指定是哪个内容观察者.
//只要我们数据发成了改变,我们就通知根域名baseuri.
//作用是通知内容观察者数据发生了改变.
getContext().getContentResolver().notifyChange(baseuri, null);
return uri;
default:
throw new IllegalArgumentException("uri 不能被识别 ");
}
}
//返回被删除的数据库哪一行.
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int result = matcher.match(uri);

switch (result) {
case DELETE:
SQLiteDatabase db = openHelper.getWritableDatabase();

getContext().getContentResolver().notifyChange(baseuri, null);
return db.delete("person", selection, selectionArgs);
default:
throw new IllegalArgumentException("uri 不能被识别 ");
}
}

@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int result = matcher.match(uri);

switch (result) {
case UPDATE:
SQLiteDatabase db = openHelper.getWritableDatabase();

getContext().getContentResolver().notifyChange(baseuri, null);
return db.update("person", values, selection, selectionArgs);

default:
throw new IllegalArgumentException("uri 不能被识别 ");
}
}

}
package cn.itcast.other;

import android.app.Activity;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;

public class OtherActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//在我们的应用中想要解析数据,首先得手内容的解析者.
//解析者把要查询的消息告诉contentprovider.contentprovider操作查询.
ContentResolver  resolver =  getContentResolver();
Uri uri = Uri.parse("content://cn.itcast.db.personprovider/");

//        Cursor cursor = resolver.query(uri, null, null, null, null);
//        while (cursor!=null&& cursor.moveToNext()){
//        	String name = cursor.getString( cursor.getColumnIndex("name"));
//        	int age = cursor.getInt(cursor.getColumnIndex("age"));
//        	System.out.println("姓名 "+ name +" 年龄 "+ age);
//        }

//  content://cn.itcast.db.personprovider
// 注册了一个内容观察者
//给uri注册观察者. true表示只要根节点发生改变,这个事件就会发生.
getContentResolver().registerContentObserver(uri, true , new MyObserver(new Handler()));
}

//内容观察者
public class MyObserver extends ContentObserver{

public MyObserver(Handler handler) {
super(handler);

}

/**
* 当内容观察者发现了数据发生改变的时候 调用的方法
*/
@Override
public void onChange(boolean selfChange) {
System.out.println("数据发生改变了 ");
super.onChange(selfChange);
}

}
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐