ContentProvider和ContentResolver的混用
来源:互联网 发布:matlab数组倒序 编辑:程序博客网 时间:2024/05/18 15:06
/*
* 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的 哎 下次再说吧
- ContentProvider和ContentResolver的混用
- ContentResolver和ContentProvider的关系
- ContentProvider和ContentResolver的使用
- ContentProvider和ContentResolver的学习
- 简单的Contentprovider和contentResolver
- ContentProvider的创建和ContentResolver的使用
- Android ContentProvider、ContentResolver和ContentObserver的使用
- 关于contentProvider和ContentResolver的个人理解
- ContentProvider和ContentResolver
- ContentProvider和ContentResolver
- ContentProvider ,ContentObserver 和ContentResolver
- Andorid ContentProvider和ContentResolver
- contentProvider和contentResolver
- ContentResolver和ContentProvider
- ContentResolver和ContentProvider
- ContentProvider和ContentResolver
- android之ContentResolver和ContentProvider
- ContentProvider/ContentResolver和Uri详解
- php模拟post提交提交json数据
- 关于Android的.so文件你所需要知道的-转载记录
- 关于直播,所有的技术细节都在这里了
- 如何在Android Studio中搜索并添加jar包
- ActivityManager: Warning: Activity not started, its current task has been brought to the front
- ContentProvider和ContentResolver的混用
- Android 三大图片缓存原理、特性对比
- CSS3 自动换行
- android developer tiny share-20160629
- 常见Tomcat无法启动故障
- Mysql中的Btree与Hash索引比较
- sql中的 inner join 和 out join
- Robert 的军队 题解+代码
- Apache Shiro 简介