Android 基础到进阶四大组件之 ContentProvider 详解,安卓开发菜鸟教程
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + PATH_USERS); //返回代码 public static final int USER_INFO = 1; //创建 UriMatcher 对象 private static UriMatcher uriMatcher; //创建静态代码块 static { //实例化 UriMatcher 对象 uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); //参数 1:authority;参数 2:路径;参数 3:自定义代码 uriMatcher.addURI(UserInfoContent.AUTHORITY, UserInfoContent.PATH_USERS, USER_INFO);} 3. 注册 ContentProvider 在 AndroidManif ``` 《Android 学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》 浏览器打开:qq.cn.hn/FTe 免费领取 ``` est.xml 文件中的 application 节点下使用标签注册。样例: <!-- android:name 指定 ContentProvider 实现的类名 android:authorities 指定 ContentProvider 对应 Uri(相当于 ContentProvider 分配一个域名) android:exported 指定 ContentProvider 是否允许其他应用调用。 如果将该属性设置为 true,则允许其他应用调用--> <android:authorities="com.scc.userprovider" android:name=".UserProvider" android:exported="true"/> []( )使用 ContentProvider ----------------------------------------------------------------------------------- 1. 通过 insert()方法添加单条数据 ContentValues cv = new ContentValues(); cv.put(UserInfoContent._ID, bean.get_id()); cv.put(UserInfoContent.USER_NAME, bean.getName()); cv.put(UserInfoContent.USER_AGE, bean.getAge()); cv.put(UserInfoContent.USER_UPDATE_TIME, bean.getUpdate_time()); Uri uri = getContentResolver().insert(UserInfoContent.CONTENT_URI, cv); Log.e(getClass().getName(), "insert:" + uri); * 通过 bulkInsert()方法添加多条数据 ContentValues[] arrayValues = new ContentValues[10]; //实例化每一个 ContentValues... int count = getContentResolver().bulkInsert(UserInfoContent.CONTENT_URI, arrayValues); ![](https://static001.geekbang.org/infoq/30/30a0daab3933b74fc298da5bf68e5789.png) 2. 指定 ID 删除单条数据 int delete = getContentResolver().delete(UserInfoContent.CONTENT_URI, "_id=12", null); Log.e(getClass().getName(), "delete(失败返回-1):" + delete); * 通过 selection 语句删除多条数据 String selection = UserInfoContent._ID + ">12"; int result = getContentResolver().delete(UserInfoContent.CONTENT_URI, selection, null); ![](https://static001.geekbang.org/infoq/6e/6e5b7d7ce001e5b0bb17b66adcbf996e.png) 3. 修改数据 UserInfoBean bean = new UserInfoBean("蚩尤", 32, "12:00"); ContentValues cv = new ContentValues(); cv.put(UserInfoContent.USER_NAME, bean.getName()); cv.put(UserInfoContent.USER_AGE, bean.getAge()); cv.put(UserInfoContent.USER_UPDATE_TIME, bean.getUpdate_time()); getContentResolver().update(UserInfoContent.CONTENT_URI, cv, "_id=18", null); ![](https://static001.geekbang.org/infoq/91/919efd6a25b88106c89d08888fbf191d.png) 4. 查询数据 Cursor cursor = getContentResolver().query(UserInfoContent.CONTENT_URI, null, selection, null, null); //循环取出游标指向的每条用户记录 while (cursor.moveToNext()) { UserInfoBean user = new UserInfoBean(); user.name = cursor.getString(cursor.getColumnIndex(UserInfoContent.USER_NAME)); user.age = cursor.getInt(cursor.getColumnIndex(UserInfoContent.USER_AGE)); user._id = cursor.getString(cursor.getColumnIndex(UserInfoContent._ID)); user.update_time = cursor.getString(cursor.getColumnIndex(UserInfoContent.USER_UPDATE_TIME)); userList.add(user); //添加到用户信息列表 } cursor.close(); //关闭数据库游标 Log.e(getClass().getName(), "Query 用户:" + String.format("当前共找到 %d 个用户", userList.size())); ![](https://static001.geekbang.org/infoq/2e/2e8c46f2940c4e7e49cfd4ea24b3f455.png) []( )跨应用使用 ContentProvider -------------------------------------------------------------------------------------- 跨应用和本应用使用 ContentProvider 一样的方法,这边就不做复制了。 例 5 的 Uri 是拼接字段,但是拼接后的结果 **「content://com.scc.userprovider/user。」** 跨平台使用 getContentResolver().方法 的第一个参数: **「Uri uricontent = Uri.parse(“content://com.scc.userprovider/user”);」** ContentValues cv = new ContentValues(); cv.put(UserInfoContent._ID, bean.get_id()); cv.put(UserInfoContent.USER_NAME, bean.getName()); cv.put(UserInfoContent.USER_AGE, bean.getAge()); cv.put(UserInfoContent.USER_UPDATE_TIME, bean.getUpdate_time()); Uri uri = getContentResolver().insert(uricontent, cv); Log.e(getClass().getName(), "insert:" + uri); 1. 新增数据+查找数据 ![](https://static001.geekbang.org/infoq/79/791aefdb214bd7631f0055835cc3dd59.png) 2. 修改数据+删除数据 ![](https://static001.geekbang.org/infoq/ad/ada13531f7e5956a9cc089ac1290131c.png) **「java.lang.SecurityException: Permission Denial: opening provider com.scc.cp.UserProvider from ProcessRecord」** 解决方案: 在 AndroidManifest.xml 文件中的 application 节点下使用标签注册时 android:exported="false"时,不允许其他应用调用。所以其他和应用使用 ContentProvider 会崩溃报错。将 exported 改为:android:exported="true"即可。 []( )最后 -------------------------------------------------------------------- 小编学习提升时,顺带从网上收集整理了一些 Android 开发相关的学习文档、面试题、Android 核心笔记等等文档,希望能帮助到大家学习提升,如有需要参考的可以直接去我 [**CodeChina 地址:https://codechina.csdn.net/u012165769/Android-T3**]( ) 访问查阅。
评论