您的位置:首页 > 编程语言 > PHP开发

ContentProvider和ContentResolver的混用

2016-07-07 14:49 381 查看
/*

* ContentProvider是Android的四大组件之一,可见它在Android中的作用非同小可。

* 它主要的作用是:实现各个应用程序之间的(跨应用)数据共享,比如联系人应用中就使用了ContentProvider,

* 你在自己的应用中可以读取和修改联系人的数据,不过需要获得相应的权限。

* 其实它也只是一个中间人,真正的数据源是文件或者SQLite等。

* 一个应用实现ContentProvider来提供内容给别的应用来操作,

* 通过ContentResolver来操作别的应用数据,当然在自己的应用中也可以。

* ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,

* 继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),

* 当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为表触发器、行触发器,

* 相应地ContentObserver也分为“表“ContentObserver、“行”ContentObserver,

* 当然这是与它所监听的Uri MIME Type有关的。

*/

通过上篇博文我们知道 我们可以通过ContentResolver借助Uri来访问系统的数据库像通话记录,联系人,短信的数据库,,相应的我们也可以自己构建一个数据库通过某种方式(Uri)把自己的数据端口暴露给其他用用程序使用 借助ContentProvider我们可以实现这样的功能.

//让我们通过一个例子来看

既然要暴露端口当然首先要构建数据库

public class DBHelper extends SQLiteOpenHelper {

private static final String DBNAME = "persons.db";
private static final int DBVERSION = 1;

// 创建数据库
public DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
}

// 创建表
@Override
public void onCreate(SQLiteDatabase db) {

String sql = "CREATE TABLE person (_id INTEGER PRIMARY KEY AUTOINCREMENT,name VARCHAR(20),nickname VARCHAR(20))";
db.execSQL(sql);
}
//数据库更新的时候调用
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}

}


//自定义ContentProvider实现增删改查操作

public class MyCustomProvider extends ContentProvider {
private SQLiteDatabase db;
// 用来在程序一启动的时候初始化内容提供者.只会执行一次.
// 这个方法是在主线程中运行的,不能进行特别耗时的操作,否则程序的启动就会延迟.
// true:表示内容提供者被成功的加载.false:反之.
@Override
public boolean onCreate() {
DBHelper helper = new DBHelper(getContext());
db = helper.getWritableDatabase();
return true;
}
// 必须构建URI:---->创建"口令"的过程
private final static String AUTHORITY = "www.xxx.cn";
private final static int PERSON_CODE = 1;
private final static int PERSON_ID = 2;
private final static int PERSON_TEXT = 3;
// UriMatcher.NO_MATCH:默认的验证码.如果URI没有验证通过,就返回该值,-1.
private static UriMatcher mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
// 用来创建URI对象.
// content://www.xxx.cn/person
mMatcher.addURI(AUTHORITY, "person", PERSON_CODE);
// content://www.xxx.cn/person/1
mMatcher.addURI(AUTHORITY, "person/#", PERSON_ID);
// content://www.xxx.cn/person/filter/sss
mMatcher.addURI(AUTHORITY, "person/filter/*", PERSON_TEXT);
}

// Uri:统一资源标示符:content://www.syc.com/mydb
// URL:统一资源定位符--->http://www.baidu.com/index.html

@Override
public Uri insert(Uri uri, ContentValues values) {
// content://www.xxx.cn/person
// insert into person (name,nickname) values("zhs","ss");
// 验证URI
int match = mMatcher.match(uri);
switch (match) {
case PERSON_CODE:
// id:最近添加的一行的行号.
long id = db.insert("person", null, values);
if (id > 0) {
// 当数据源发生了改变,发出通知--->通过uri,把信息告诉--->MyObserver:
getContext().getContentResolver().notifyChange(uri, null);
}
// content://www.xxx.cn/person/1
// 将id追加到原有的uri后面,形成一个新的uri
return ContentUris.withAppendedId(uri, id);
default:
throw new IllegalArgumentException("口令不对,滚一边去!");
}
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int match = mMatcher.match(uri);
// delete from person
// delete from person where _id=1
// delete from person where name=李逵
switch (match) {
case PERSON_CODE:
break;
case PERSON_ID:// content://www.xxx.cn/person/1
long parseId = ContentUris.parseId(uri);
int delete = db.delete("person", "_id=?",
new String[]{String.valueOf(parseId)});
if (delete > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return delete;
case PERSON_TEXT:// content://www.xxx.cn/person/filter/李逵
String lastPathSegment = uri.getLastPathSegment();
int delete2 = db.delete("person", "name=?",
new String[]{lastPathSegment});
if (delete2 > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return delete2;
default:
throw new IllegalArgumentException("路径错误");
}
return 0;
}

@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// update person set name="ss" where _id=1;
// update person set name="ss" where name=ss;
int match = mMatcher.match(uri);
switch (match) {
case PERSON_CODE:
return db.update("person", values, selection, selectionArgs);
case PERSON_ID:// content://www.xxx.cn/person/1
long parseId = ContentUris.parseId(uri);
return db.update("person", values, "_id=?",
new String[]{String.valueOf(parseId)});
case PERSON_TEXT:// content://www.xxx.cn/person/filter/黑鬼
// 截取最后的部分
String lastPathSegment = uri.getLastPathSegment();
return db.update("person", values, "nickname=?",
new String[]{lastPathSegment});
default:
throw new IllegalArgumentException("路径错了");
}
}

@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {

int match = mMatcher.match(uri);
switch (match) {
case PERSON_CODE:
return db.query("person", projection, selection, selectionArgs,
null, null, sortOrder);
case PERSON_ID:
long parseId = ContentUris.parseId(uri);
return db.query("person", projection, "_id=?",
new String[]{String.valueOf(parseId)}, null, null,
sortOrder);
case PERSON_TEXT:
String lastPathSegment = uri.getLastPathSegment();
return db.query("person", projection, "name=?",
new String[]{lastPathSegment}, null, null, sortOrder);
default:
break;
}
return null;
}
// 根据传递进来的uri参数类型,判定要请求的数据类型.
// vnd.android.cursor.item:代表单条数据;
// vnd.android.cursor.dir:代表多条数据.
@Override
public String getType(Uri uri) {
int match = mMatcher.match(uri);
switch (match) {
case PERSON_CODE:
return "vnd.android.cursor.dir";
case PERSON_ID:
return "vnd.android.cursor.item";
}
return null;
}
}


注册

<provider
android:name=".MyCustomProvider"
android:authorities="www.xxx.cn"
android:exported="true">
</provider>


//在另外一个app借助ContentResolver对该数据库进行增删改查操作

/****
* ContentProvider内容提供者 ContentResolver内容解析者 ContentObserver内容观察者
* ContentResolver就是来取ContentProvider提供的数据的。
* ContentProvider使你数据库中数据能够被其他程序访问,但能访问不能任意方式都能访问,
* 只能通过规定的方式,这中方式就是通过ContentResolver来实现
*内容观察者,观察内容提供者数据的变化。如果内容提供者数据变化了,那么发送信息给观察者。
*原理:在resolver身上注册一个观察者observer,当数据改变时,调用观察者的onChange方法
*在provider的数据会发生改变的方法中调用resolver的notifyChange方法。
*/
public class MainActivity extends AppCompatActivity {

private ContentResolver resolver;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resolver = getContentResolver();
}

public void insert(View v) {
String str = "content://www.xxx.cn/person";
ContentValues values = new ContentValues();
values.put("name", "宋江");
values.put("nickname", "黑三郎");
Uri result = resolver.insert(Uri.parse(str), values);
// 将一个uri最后的id给截取返回.
long parseId = ContentUris.parseId(result);
if (parseId > 0) {
Toast.makeText(this, "添加成功", Toast.LENGTH_LONG).show();
}
}

public void update(View v) {
//根据id更新
String str = "content://www.xxx.cn/person/1";
ContentValues values=new ContentValues();
values.put("name", "李逵");
values.put("nickname", "黑鬼");
int result = resolver.update(Uri.parse(str), values,"_id=?", new String[]{String.valueOf("1")});

//匹配字符更新
//String str = "content://www.xxx.cn/person/filter/黑三郎";
//ContentValues values = new ContentValues();
//values.put("nickname", "黑旋风");
//values.put("name", "大傻逼");
//int result = resolver.update(Uri.parse(str), values, null, null);
if (result > 0) {
Toast.makeText(this, "修改成功", Toast.LENGTH_LONG).show();
}
}

// 删除
public void delete(View v) {
//根据id删除
String str = "content://www.xxx.cn/person/1";
int result = resolver.delete(Uri.parse(str),"_id=?", new String[]{String.valueOf("1")});
//匹配字符删除
//String str = "content://www.xxx.cn/person/filter/宋江";
//int result = resolver.delete(Uri.parse(str), null, null);
//全部删除
//String str = "content://www.xxx.cn/person";
//int result = resolver.delete(Uri.parse(str), null, null);
if (result > 0) {
Toast.makeText(this, "删除成功", Toast.LENGTH_LONG).show();
}
}

public void query(View v) {
//根据id查询 在6.0的手机上居然禁止关联启动了  shit
String str = "content://www.xxx.cn/person/3";
Cursor cursor = resolver.query(Uri.parse(str), new String[] {"_id","name","nickname"},"_id=?", new String[]{"3"}, null);

//全部查询
//String str = "content://www.xxx.cn/person";
//Cursor cursor = resolver.query(Uri.parse(str), new String[] {"_id","name","nickname"},null, null, null);
while (cursor.moveToNext()) {
Long _id = cursor.getLong(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String nickname = cursor.getString(cursor.getColumnIndex("nickname"));
Log.i("TAG", "_id="+_id+"name=" + name+"--nickname="+nickname);
}
}
}


本来应该加上 ContentObserver的 哎 下次再说吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: