Android核心基础-5.Android 数据存储与访问-4.ContentProvider 内容提供者
来源:互联网 发布:混沌骑士 知乎 编辑:程序博客网 时间:2024/05/16 03:04
续上一博文(Android核心基础-5.Android 数据存储与访问-3.使用Sqlite进行数据存储)
四、ContentProvider 内容提供者
4.1 什么是ContentProvider
- ContentProvider是安卓四大组件之一, 用来共享应用程序内的数据
- 该组件对外提供了其他应用可以直接访问的增删改查方法
- 在数据被修改的时候, 可以使用ContentObserver监听
4.2 创建ContentProvider***
- 定义类继承ContentProvider
- 在清单文件中声明< provider>标签
4.3 访问ContentProvider***
- 获取ContentResolver对象
- 使用ContentResolver指定Uri即可对指定的ContentProvider增删改查
4.4 增删改查方法*
- ContentProvider的insert(), delete(), update(), query(): 对外提供的4个操作数据的方法
- ContentResolver的insert(), delete(), update(), query(): 调用ContentProvider的方法
- SQLiteDabase的insert(), delete(), update(), query(): 在ContentProvider中适合用这4个方法操作数据库, 其内部就是拼接SQL语句, 调用execSQL()和rawQuery()
4.5 UriMatcher*
- UriMatcher可以用来匹配Uri, 识别出子级路径
- addUri()方法可以指定路径和结果码
- match()方法可以匹配一个Uri, 得到结果码
4.6 带id的Uri*
- 可以使用UriMatcher添加一个带”#”的路径, 用来匹配带id的Uri
- 使用ContentUris.parseId()可以从Uri中解析出id
4.7 ContentObserver监听数据修改**
- 可以使用ContentResolver, 调用registerContentObserver()注册一个ContentObserver
- 在数据修改时使用ContentResolver调用notifyChange()发一个通知
- ContentObserver会收到这个通知, 执行内部的onChange()方法
发送通知:
// 当数据改变时, 发送通知, 这时ContentObserver就会接收到getContext().getContentResolver().notifyChange(uri, null);
监听通知:
// 注册一个ContentObserver(类似一个监听器), 其中需要实现onChange()方法, 在数据修改的时候, 会自动执行onChange()方法Uri uri = Uri.parse("content://net.dxs.provider");//参数二:是否接收后代通知,如content://net.dxs.provider/accountgetContentResolver().registerContentObserver(uri, true, new MyObserver());private class MyObserver extends ContentObserver { public MyObserver() { super(new Handler()); } @Override public void onChange(boolean selfChange) { list = dao.queryPage(20, pageNum); // 重新查询数据 adapter.notifyDataSetChanged(); // 刷新ListView(把数据和ListView显示的内容同步) }}
4.8 监听短信
- 从github上下载telephonyprovider, 从清单文件中获取Uri
- 在程序中对指定Uri注册ContentObserver, 当收发短信时就会执行onChange()
- 查询到最后一条数据就是短信记录
4.9 ContentProvider匹配说明
1. schema,用来说明一个ContentProvider控制这些数据。 “content://”
2. 主机名或授权(Authority),它定义了是哪个ContentProvider提供这些数据。
3. path路径,URI下的某一个Item。
4. ID, 通常定义Uri时使用”#”号占位符代替, 使用时替换成对应的数字
“content://net.dxs.provider/person/#” #表示数据id(#代表任意数字)”content://net.dxs.provider/person/* ” *来匹配任意文本
要给第三方提供数据访问的ContentProvider类
DxsProvider.java
package net.dxs.sqlite.provider;import net.dxs.sqlite.dao.MyHelper;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;public class DxsProvider extends ContentProvider { private MyHelper helper; private UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); // 创建匹配器对象, 当Uri无法匹配的时候, 得到-1 private static final int ACCOUNT_ID = 0; private static final int ACCOUNT = 1; private static final int ORDER = 2; @Override public boolean onCreate() { // 创建之后执行 System.out.println("DxsProvider--->onCreate"); helper = new MyHelper(getContext()); matcher.addURI("net.dxs.provider", "account/#", ACCOUNT_ID); matcher.addURI("net.dxs.provider", "account", ACCOUNT); // 向匹配器中添加可以识别的Uri, 指定结果码 matcher.addURI("net.dxs.provider", "order", ORDER); return false; } @Override public Uri insert(Uri uri, ContentValues values) { System.out.println("DxsProvider--->insert"); switch (matcher.match(uri)) { // 使用匹配器识别Uri, 得到预先指定的结果码 case ACCOUNT: SQLiteDatabase db = helper.getWritableDatabase(); long id = db.insert("account", "_id", values); // 通过values拼接SQL语句 getContext().getContentResolver().notifyChange(uri, null); db.close(); return ContentUris.withAppendedId(uri, id); // 把新记录的id拼在Uri最后, 返回 case ORDER: System.out.println("暂时没有order表"); return null; default: throw new IllegalArgumentException("Uri无法识别: " + uri); } } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { System.out.println("DxsProvider--->delete"); switch (matcher.match(uri)) { case ACCOUNT_ID: long id = ContentUris.parseId(uri); selection = "_id=?"; selectionArgs = new String[] { id + "" }; case ACCOUNT: SQLiteDatabase db = helper.getWritableDatabase(); int count = db.delete("account", selection, selectionArgs); getContext().getContentResolver().notifyChange(uri, null); db.close(); return count; default: throw new IllegalArgumentException("Uri无法识别: " + uri); } } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { System.out.println("DxsProvider--->update"); switch (matcher.match(uri)) { case ACCOUNT_ID: long id = ContentUris.parseId(uri); selection = "_id=?"; selectionArgs = new String[] { id + "" }; case ACCOUNT: SQLiteDatabase db = helper.getWritableDatabase(); int count = db.update("account", values, selection, selectionArgs); getContext().getContentResolver().notifyChange(uri, null); // 当数据改变时, 发送通知, 这时ContentObserver就会接收到 db.close(); return count; default: throw new IllegalArgumentException("Uri无法识别: " + uri); } } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { System.out.println("DxsProvider--->query"); switch (matcher.match(uri)) { case ACCOUNT_ID: long id = ContentUris.parseId(uri); // 截取最后一个"/"后面的数字, 转为long selection = "_id=?"; selectionArgs = new String[] { id + "" }; case ACCOUNT: SQLiteDatabase db = helper.getReadableDatabase(); Cursor c = db.query("account", projection, selection, selectionArgs, null, null, sortOrder); return c; default: throw new IllegalArgumentException("Uri无法识别: " + uri); } } @Override public String getType(Uri uri) { // 获取Uri的MimeType, text/html text/css image/jpg audio/mp3 System.out.println("DxsProvider--->getType"); switch (matcher.match(uri)) { case ACCOUNT_ID: return "vnd.android.cursor.item/account"; case ACCOUNT: return "vnd.android.cursor.dir/account"; default: throw new IllegalArgumentException("Uri无法识别: " + uri); } }}
注意清单文件要注册声明provider
<provider android:name="net.dxs.sqlite.provider.DxsProvider" android:authorities="net.dxs.provider" android:exported="true" />
第三方APP开始调用提供的ContentProvider
package net.dxs.other;import android.content.ContentResolver;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.test.AndroidTestCase;public class ProviderTest extends AndroidTestCase { public void test1() { ContentResolver resolver = getContext().getContentResolver(); // 获取ContentResolver Uri uri = Uri.parse("content://net.dxs.provider"); // 指定ContentProvider的Uri // resolver.delete(uri, null, null); // 对指定Uri调用删除方法 resolver.query(uri, null, null, null, null); } public void testInsert() { ContentResolver resolver = getContext().getContentResolver(); Uri uri = Uri.parse("content://net.dxs.provider/account"); ContentValues values = new ContentValues(); values.put("name", "insert"); values.put("balance", 23456); System.out.println(resolver.insert(uri, values)); // 得到刚刚插入的Uri } public void testDelete() { ContentResolver resolver = getContext().getContentResolver(); Uri uri = Uri.parse("content://net.dxs.provider/account/20"); resolver.delete(uri, null, null); } public void testUpdate() { ContentResolver resolver = getContext().getContentResolver(); Uri uri = Uri.parse("content://net.dxs.provider/account/1"); ContentValues values = new ContentValues(); values.put("name", "深情小建"); values.put("balance", 20000); resolver.update(uri, values, null, null); } public void testQuery() { ContentResolver resolver = getContext().getContentResolver(); Uri uri = Uri.parse("content://net.dxs.provider/account/100"); Cursor c = resolver.query(uri, null, null, null, null); while (c.moveToNext()) { System.out.println(c.getString(c.getColumnIndex("name")) + ": " + c.getInt(c.getColumnIndex("balance"))); } c.close(); } public void testGetType() { ContentResolver resolver = getContext().getContentResolver(); System.out.println(resolver.getType(Uri.parse("content://net.dxs.provider/account/100"))); // 单条记录, 返回item System.out.println(resolver.getType(Uri.parse("content://net.dxs.provider/account"))); // 多条记录, 返回dir }}
生成的数据库表如图
实例源代码->百度网盘
1 0
- Android核心基础-5.Android 数据存储与访问-4.ContentProvider 内容提供者
- Android核心基础-5.Android 数据存储与访问-4.ContentProvider 内容提供者-示例(监听短信)
- Android核心基础-5.Android 数据存储与访问-4.ContentProvider 内容提供者-示例(操作联系人)
- android ContentProvider(内容提供者)基础
- android 数据存储和访问方式四:ContentProvider(内容提供者、数据共享)详解
- android 数据存储和访问方式四:ContentProvider(内容提供者、数据共享)详解
- android基础笔记:内容提供者及访问(ContentProvider、ContentResolver)
- Android核心基础-5.Android 数据存储与访问-2.使用SharedPreferences进行数据存储
- Android核心基础-5.Android 数据存储与访问-3.使用Sqlite进行数据存储
- Android ContentProvider(内容提供者)
- android内容提供者ContentProvider
- Android--- ContentProvider(内容提供者)
- Android 内容提供者ContentProvider
- Android内容提供者ContentProvider
- android内容提供者contentProvider
- android ContentProvider内容提供者
- Android-ContentProvider内容提供者
- Android ContentProvider 内容提供者
- Linux下Tomcat使用80端口
- 学生信息管理系统之总结篇
- android Spinner(列表选择框)
- static的用法
- Oracle 单行函数
- Android核心基础-5.Android 数据存储与访问-4.ContentProvider 内容提供者
- 推荐!国外程序员整理的机器学习资源大全
- VF控制和矢量控制的一些区别
- android 下改变默认的checkbox的 选中 和被选中 图片
- Oracle检查与安装操作内容
- JDK中Applet的安全性策略探究
- TCP与UDP的区别
- Android 屏幕适配方案
- C++全局对象的初始化和析构