ContentProvider
1: 作用:最重要的作用就是给其他的应用提供,IPC
2: 通过方法统一管理方法,几个方法的返回值的作用,insert,update,delete,getType,
3: uri操作,uri的匹配的问题,可以匹配多个情况,*匹配字符,#匹配数字。不用自己手动的去写过滤。
4: ContentObserver, 构造方法详解,千万要记住要注销掉,不然是内存泄漏
5: Permission,只有申请了权限了的才能够访问到数据,否则不可以,为了数据的安全
1 : 没有ContentProvider 也是可以直接操作数据库的,但是有了ContentProvider 可以更好的方法管理,同时最关键的就是给其他的应用提供数据。
ContentProvider 的优点:
1: 给其他的应用提供方法,对外进行共享
2: 规范database的管理,不用手动操作数据库,统一了数据的访问方式,可以通过提供给的api操作
3: UriMatcher 和ContentUtils 可以帮助uri过滤
4: 可以通知其他应用,数据变化了
2: ContentProvider中各个方法
1:onCreate 方法一般要求返回true
true if the provider was successfully loaded, false otherwise
2:getType() 返回我们操作的内容类型,例如文本文件,mp3文件,html,text文件。plain/text。一般返回null
3:onDelete返回的是删除了几个数据
4:insert() 返回的是心插入的数据的uri
5:update()返回的是也是影响了多少个数据
3: URI 操作
/**
内容提供者的authority 是可以说是主机名或者是
和service的intent filter的action 类似package 类似,就是要可以找到它
com.kodulf.provider.student 这个的格式,这个是唯一标示,相当于是网站的域名。uri的schema 就是content,因为我们就是内容提供者嘛,哈哈哈?,这个就已经被android 系统固定了,只要看到uri的schema 是content 的我们的第一反应就是访问的内容提供者中的数据。1: 如果要操作person表中id 为10的数据 content://authority/person/10
2: 如果要操作person 表中id为10的数据的name 字段 content://authority/person/10/name
3: 如果要操作person 表中所有的数据 content://authority/person
4: 如果要操作xxx表数据 content://authority/xxxURI 的判断UriMatcher:
1: 匹配现有的表或者是单个数据
2: 如果没有匹配到需要抛出异常
*/static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);public static final int STUDENT_CODE = 1;
public static final int STUDENT_NUMBER_CODE = 2;
public static final int TEACHER_CODE = 3;
public static final int TEACHER_NUMBER_CODE = 4;static {mUriMatcher.addURI(AUTHRITY,MySQLiteOpenHelper.TABLE_STUDENT,STUDENT_CODE);mUriMatcher.addURI(AUTHRITY,MySQLiteOpenHelper.TABLE_STUDENT+"/#",STUDENT_NUMBER_CODE);mUriMatcher.addURI(AUTHRITY,MySQLiteOpenHelper.TABLE_TEACHER,TEACHER_CODE);mUriMatcher.addURI(AUTHRITY,MySQLiteOpenHelper.TABLE_TEACHER+"/#",TEACHER_NUMBER_CODE);
}
……
switch (mUriMatcher.match(uri)) {case STUDENT_CODE://第二个参数为字段名称long rowId = mDb.insert(MySQLiteOpenHelper.TABLE_STUDENT, null, values);//content://kodulf.contentprovider/student/10//可以有两种方法:Uri parse = Uri.parse(URI_STUDENT + "/" + rowId);Uri uri1 = ContentUris.withAppendedId(uri, rowId);getContext().getContentResolver().notifyChange(uri,null);return parse;case STUDENT_NUMBER_CODE:break;default:throw new IllegalArgumentException("Wrong parameter");
}
UriMatcher 的匹配的规则1: #代表了所有的数字
2: * 代表任意字符1: 匹配表
mUriMatcher.addURI(AUTHRITY,“student”,TEACHER_CODE);2:匹配表中的某个数据,例如student/12
mUriMatcher.addURI(AUTHRITY,“student/#”,TEACHER_CODE);3:匹配表中的某个列,例如student/name
mUriMatcher.addURI(AUTHRITY,“student/*”,TEACHER_CODE);
4: ContenObserver
ContentObserver
https://blog.csdn.net/qinjuning/article/details/7047607
uri 需要观察的Uri(需要在UriMatcher里注册,否则该Uri也没有意义了)notifyForDescendents 为false 表示精确匹配,即只匹配该Uri为true 表示可以同时匹配其派生的Uri,举例如下:假设UriMatcher 里注册的Uri共有一下类型:1 、content://com.qin.cb/student (学生)2 、content://com.qin.cb/student/# 3、 content://com.qin.cb/student/schoolchild(小学生,派生的Uri)getContentResolver().registerContentObserver(Uri.parse(MyContentProvider.URI_STUDENT), false, new ContentObserver(new Handler()) {@Overridepublic boolean deliverSelfNotifications() {return super.deliverSelfNotifications();}@Overridepublic void onChange(boolean selfChange) {super.onChange(selfChange);Log.d("kodulfdb","onChange selfChange");}@Overridepublic void onChange(boolean selfChange, Uri uri) {super.onChange(selfChange, uri);Log.d("kodulfdb","onChange selfChange, Uri uri");}
});千万要记住要注销掉
5: Permission
Permission
<!-- student provider 访问权限声明 --><permissionandroid:name="com.android.peter.provider.READ_PERMISSION"android:label="Student provider read permission"android:protectionLevel="normal"/><permissionandroid:name="com.android.peter.provider.WRITE_PERMISSION"android:label="Student provider read permission"android:protectionLevel="normal"/><!-- 声明ContentProvider --><application...<providerandroid:name=".StudentContentProvider"android:authorities="com.android.peter.provider"android:readPermission="com.android.peter.provider.READ_PERMISSION"android:writePermission="com.android.peter.provider.WRITE_PERMISSION"android:process=":provider"android:exported="true"/>...</application>为了方便起见,权限声明时protectionLevel设置的是最低风险权限(normal),关于其他等级权限和说明如下:权限等级说明
normal 低风险权限,只要申请了就可以使用,安装时不需要用户确认
dangerous 高风险权限,安装时需要用户确认授权才可使用。
signature 只有当申请权限应用与声明此权限应用的数字签名相同时才能将权限授给它。
signatureOrSystem 签名相同或者申请权限的应用为系统应用才能将权限授给它。使用地方就需要申明权限了:
<uses-permission android:name="bjpkten.contentproviderdemo30min.contentprovider"></uses-permission>