Android个人每天总结.doc(day04四大组件之:内容提供者ContentProvider)
2016-08-01 20:41
543 查看
作者:韩亚飞_yue31313_韩梦飞沙 QQ:313134555
作用:
让手机中的应用独有的数据能共享
且能实现私有数据和特定的共享,权限的细化,比如让特定文件的只能读,
也就是外部应用都能访问任意应用的ContentProvider,能访问什么数据,就看里面定义了什么方法.
这样只提供方法让外部访问数据,而并不把文件暴露,提高了安全性
让外部应用能监听数据的修改
public class SqliteProvider
extendsContentProvider {
private DBFactory
helper;
private UriMatcher
matcher;
private static
final int
PERSON = 0;
private static
final int
PERSON_ID = 1;
2.重写6个抽象方法
增删改查方法具本实现自已定义
里面有6个方法
① onCreate()方法:provider对象创建时运行
public boolean onCreate() {
//获得db工具类,获得db对象
helper = new DBFactory(getContext());
② UriMatcher工具类用于解析Uri的参数:
用UriMatcher的match(uri)方法可以解析得到Uri的参数值,返回值是之前定义的int常量:matcher.match(uri)在CURD方法中用Switch去判断match方法得到的结果,进行匹配执行.
matcher = newUriMatcher(UriMatcher.NO_MATCH);
添加解析表名功能:
matcher.addURI("sql.provider.SqliteProvider",
"person", PERSON);
添加解析参数值功能:
matcher.addURI("sql.provider.SqliteProvider",
"person/#", PERSON_ID);
return
true;
}
③ insert方法:
这个返回值是Uri,就是把影响的行id发回去,但要uri拼接
用一个ContentUris工具类的withAppendId(uri,id);实现拼接.
public Uriinsert(Uri uri, ContentValues values) {
SQLiteDatabase db = helper.getWritableDatabase();
getContext().getContentResolver().notifyChange(uri,null);
用UriMatcher的match(uri)方法可以解析得到Uri的参数值
switch (matcher.match(uri)){
case PERSON:
uri = ContentUris.withAppendedId(uri,
db.insert("person",
"id", values));
db.close();
return uri;
default:
throw new IllegalArgumentException("不能识别的uri:" + uri);
}
}
④ delete方法:返回删除的行int
public int delete(Uri uri, Stringselection, String[] selectionArgs) {
SQLiteDatabase db = helper.getWritableDatabase();
getContext().getContentResolver().notifyChange(uri,null);
switch (matcher.match(uri)){
case PERSON_ID:
long id = ContentUris.parseId(uri);
selection = "_id=" + id;
case PERSON:
int i= db.delete("person", selection,selectionArgs);
db.close();
return i;
default:
throw new IllegalArgumentException("不能识别的uri:" + uri);
}
}
⑤ update方法:返回修该的行,int
public int update(Uri uri,ContentValues
values,String selection,
String[]selectionArgs) {
SQLiteDatabase db = helper.getWritableDatabase();
getContext().getContentResolver().notifyChange(uri,null);
switch (matcher.match(uri)) {
case PERSON_ID:
long id = ContentUris.parseId(uri);
selection = "_id=" + id;
case PERSON:
int i= db.update("person",
values, selection,selectionArgs);
db.close();
return i;
default:
throw new IllegalArgumentException("不能识别的uri:" + uri);
}
}
⑥ query方法:返回Cursor
注意:这里返回的是Cursor,不能关闭database,因为要传递,
public Cursorquery(Uri uri, String[] projection, String selection,
String[]selectionArgs, String sortOrder) {
SQLiteDatabase db = helper.getWritableDatabase();
getContext().getContentResolver().notifyChange(uri,null);
switch (matcher.match(uri)){
case PERSON_ID:
⑦ getType:返回值是一个String 用于定义返回的事件类型.
mimetype解释
3.在清单文件里注册
在application里定义<Provider name=文件位置(注意.的应用,代表当前应用包)
authorites=是ContentProvider的唯一标识(名字最好要有意义)>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
>
<provider android:name=".provider.SqliteProvider"android:authorities="sql.provider.SqliteProvider"/>
</application>
用一个ContentUris工具类的withAppendId(uri,id);实现拼接.
用于解析具体参数值返回一个long类型
带id的"user/#"ContentUris.parseId(Uri)
如:content://sql.provider.SqliteProvider/person/15---能得到15
4.ContentUris类用于解析Uri后的id,也可以用于给Uri追加id
ContentUris.parseId(Uri)
long id = ContentUris.parseId(uri);
selection = "_id=" + id;
case PERSON:
return db.query("person",
new String[] { "name",
"phone" },
selection, null,
null, null,
null);
default:
throw new IllegalArgumentException("不能识别的uri:" + uri);
}
}
1.ContentResolver:用于访问内容提供者--用Context当前环境对象获取get...
其是一个ContentProvider的一个管理者类
每个应用程序是可以实现数据共享的,对于每一个应用程序程序都拥有一个contentprovider实例进行存储,而contentresolver则是用于管理所有程序的contentprovider实例,通过contentrescolver可以获得数据,插入数据等……至于getcontentrescolver()就是获取实例。。。
ContentResolvercr=getContentResolver();
2.这个类有四个方法CURD,能访问内容提供者的对应的CURD--只有查不关数据库
可以把helper方法定义在oncreate方法中,这样就不用在每个CURD方法中定义.
四个方法中用到两个比较重要的参数:
Uri参数:表示要访问哪个ContentProvider,需要以Content://开头,后面加上authorities定义的名字
Values参数:是ContentValues--那个map中定义sql要查询的map<String,Object>(列名,列的值).
注意:修改ContentProvider代码后要把那个应用重新发到手机上运行.
cr.insert(uri,values);
cr.delete(uri,where, selectionArgs);
cr.update(uri,values, where, selectionArgs);
cr.query(uri,projection, selection, selectionArgs, sortOrder);
projection:表示要查询列名的数组.null表示查询所有列.
columns:要查询出来的列名。相当于select语句select关键字后面的部分。
selection:查询条件子句,相当于select语句where关键字后面的部分,在条件子句允许使用占位符“?”
selectionArgs:对应于selection语句中占位符的值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常。
groupBy:相当于select语句group by关键字后面的部分
having:相当于select语句having关键字后面的部分
orderBy:相当于select语句order by关键字后面的部分,如:personiddesc(倒序), age asc;
limit:指定偏移量和获取的记录数,相当于select语句limit关键字后面的部分。
1. 通过getContentResolver对象注册一个ContentObserver
有三个参数:
Uri:这个Uri是应用清单文件中定义的Provider的authorites,但在前面要加上content://
boolean:表示是uri是绝对
Observer:自已定一个观察者对象
public class MainActivity
extends Activity {
public
void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 给应用中注册一个观察者ContentObserver:参数为应用的uri
Uri uri = Uri.parse("content://com.itheima.SQLiteProvider");
MyObserver observer =new MyObserver();
getContentResolver().registerContentObserver(uri,
true,observer );
System.out.println("register");
}
2. 创建一个MyObserver对象,让其作参数:具本观察细节在onChange()方法定义.
private class MyObserver
extendsContentObserver {
public MyObserver() {
// 在主线程中创建的Handler, onChange()方法就在主线程中执行
super(new Handler());
}
public void onChange(boolean selfChange) {
System.out.println("收到数据修改的通知!");
}
}
3. 定义ContentProvider类中哪些方法执行时让外部观察.
通过notifyChange(uri,null)方法
那么数据一旦修改,就会执行onChange()方法
public Uriinsert(Uri uri, ContentValues values) {
SQLiteDatabase db = helper.getWritableDatabase();
getContext().getContentResolver().notifyChange(uri,null);
不需要观察时卸载一个Resolver观察者
getContentResolver().unregisterContentObserver(observer);
observer = null;
注册监听,要知道应用的uri,
用git工具,或直接去zip下载应用的源码
短信的uri就是sms
在应用中注册观察者就行了.
在onChange方法中定义查询短信query方法
查结果集注意Cursor可能有别名
Cursor的getCount方法能获得有多少数据
getlumnNames()方法获得所有列名.
_id在desc Limit 1 查数据库中最后一条记录
获得结果集后.得到想要的数据
主要看这数据库的三张表:
raw_contacts:只有id 是data的外键,1对多:比如.1号联系人有三个数据,姓名,电话,邮箱....
data:是详细数据
mimetype:表示数据类型
Authorites:
要读和写联系人的权限:READ_CONTACTWRITE_CONTACT
先查raw_contact的_id
再通过_id查data的 data1raw_contact
双重循环去查找
data2里面的是电话是表示选的哪一种联系方式
data2中的是名字中的名 data3是名字的姓.
写联系人
向raw_contacts表中加一个id
再通过一个id,加三个数据
appilBatch方法实现类似于事务的操作
有两个参数:一个是Uri 一个是List里面放批量各个操作
各个操作是一个对象,用ContentProvider的静态方法创建.
很多应用内部已定义好了,内容提供者,如电话本,短信,其实内部已经实现了内容提供者,我们看到的只是通过内容提供者访问其的数据的界面层
1.应用安装好,就会创建好,手机开机后,第一次被访问时,被创建
2.只要创建了,只要手机没关机,就会一直存在,类似于在注册表里注册一样
3.手机关机,才会消失
4.应用里的数据都可以提供访问.不一定是数据库,在方法里自已定义就可以,但通常通是访问数据库
② getContext与getApplication方法的区别:都是得到当前应用的上下文环境
getApplication:是在Activity中定义的
getContext是由虚拟机setContext创建的进来的.
day04四大组件之:内容提供者ContentProvider
Ø 内容提供者:四大组件之一ContentProvider
一、定义及作用:
内容提供者:四大组件之一ContentProvider作用:
让手机中的应用独有的数据能共享
且能实现私有数据和特定的共享,权限的细化,比如让特定文件的只能读,
也就是外部应用都能访问任意应用的ContentProvider,能访问什么数据,就看里面定义了什么方法.
这样只提供方法让外部访问数据,而并不把文件暴露,提高了安全性
让外部应用能监听数据的修改
二、 怎么用?
(一)给一个应用创建内容提供者类
1.写一个类继承ContentProviderpublic class SqliteProvider
extendsContentProvider {
private DBFactory
helper;
private UriMatcher
matcher;
private static
final int
PERSON = 0;
private static
final int
PERSON_ID = 1;
2.重写6个抽象方法
增删改查方法具本实现自已定义
里面有6个方法
① onCreate()方法:provider对象创建时运行
public boolean onCreate() {
//获得db工具类,获得db对象
helper = new DBFactory(getContext());
② UriMatcher工具类用于解析Uri的参数:
用UriMatcher的match(uri)方法可以解析得到Uri的参数值,返回值是之前定义的int常量:matcher.match(uri)在CURD方法中用Switch去判断match方法得到的结果,进行匹配执行.
matcher = newUriMatcher(UriMatcher.NO_MATCH);
添加解析表名功能:
matcher.addURI("sql.provider.SqliteProvider",
"person", PERSON);
添加解析参数值功能:
matcher.addURI("sql.provider.SqliteProvider",
"person/#", PERSON_ID);
return
true;
}
③ insert方法:
这个返回值是Uri,就是把影响的行id发回去,但要uri拼接
用一个ContentUris工具类的withAppendId(uri,id);实现拼接.
public Uriinsert(Uri uri, ContentValues values) {
SQLiteDatabase db = helper.getWritableDatabase();
getContext().getContentResolver().notifyChange(uri,null);
用UriMatcher的match(uri)方法可以解析得到Uri的参数值
switch (matcher.match(uri)){
case PERSON:
uri = ContentUris.withAppendedId(uri,
db.insert("person",
"id", values));
db.close();
return uri;
default:
throw new IllegalArgumentException("不能识别的uri:" + uri);
}
}
④ delete方法:返回删除的行int
public int delete(Uri uri, Stringselection, String[] selectionArgs) {
SQLiteDatabase db = helper.getWritableDatabase();
getContext().getContentResolver().notifyChange(uri,null);
switch (matcher.match(uri)){
case PERSON_ID:
long id = ContentUris.parseId(uri);
selection = "_id=" + id;
case PERSON:
int i= db.delete("person", selection,selectionArgs);
db.close();
return i;
default:
throw new IllegalArgumentException("不能识别的uri:" + uri);
}
}
⑤ update方法:返回修该的行,int
public int update(Uri uri,ContentValues
values,String selection,
String[]selectionArgs) {
SQLiteDatabase db = helper.getWritableDatabase();
getContext().getContentResolver().notifyChange(uri,null);
switch (matcher.match(uri)) {
case PERSON_ID:
long id = ContentUris.parseId(uri);
selection = "_id=" + id;
case PERSON:
int i= db.update("person",
values, selection,selectionArgs);
db.close();
return i;
default:
throw new IllegalArgumentException("不能识别的uri:" + uri);
}
}
⑥ query方法:返回Cursor
注意:这里返回的是Cursor,不能关闭database,因为要传递,
public Cursorquery(Uri uri, String[] projection, String selection,
String[]selectionArgs, String sortOrder) {
SQLiteDatabase db = helper.getWritableDatabase();
getContext().getContentResolver().notifyChange(uri,null);
switch (matcher.match(uri)){
case PERSON_ID:
⑦ getType:返回值是一个String 用于定义返回的事件类型.
mimetype解释
3.在清单文件里注册
在application里定义<Provider name=文件位置(注意.的应用,代表当前应用包)
authorites=是ContentProvider的唯一标识(名字最好要有意义)>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
>
<provider android:name=".provider.SqliteProvider"android:authorities="sql.provider.SqliteProvider"/>
</application>
(二)ContentUris工具类
用于给Uri拼接一个id用一个ContentUris工具类的withAppendId(uri,id);实现拼接.
用于解析具体参数值返回一个long类型
带id的"user/#"ContentUris.parseId(Uri)
如:content://sql.provider.SqliteProvider/person/15---能得到15
4.ContentUris类用于解析Uri后的id,也可以用于给Uri追加id
ContentUris.parseId(Uri)
long id = ContentUris.parseId(uri);
selection = "_id=" + id;
case PERSON:
return db.query("person",
new String[] { "name",
"phone" },
selection, null,
null, null,
null);
default:
throw new IllegalArgumentException("不能识别的uri:" + uri);
}
}
(三)访问内容提供者用ContentResolver
ContentResolver的CURD方法操作应用.1.ContentResolver:用于访问内容提供者--用Context当前环境对象获取get...
其是一个ContentProvider的一个管理者类
每个应用程序是可以实现数据共享的,对于每一个应用程序程序都拥有一个contentprovider实例进行存储,而contentresolver则是用于管理所有程序的contentprovider实例,通过contentrescolver可以获得数据,插入数据等……至于getcontentrescolver()就是获取实例。。。
ContentResolvercr=getContentResolver();
2.这个类有四个方法CURD,能访问内容提供者的对应的CURD--只有查不关数据库
可以把helper方法定义在oncreate方法中,这样就不用在每个CURD方法中定义.
四个方法中用到两个比较重要的参数:
Uri参数:表示要访问哪个ContentProvider,需要以Content://开头,后面加上authorities定义的名字
Values参数:是ContentValues--那个map中定义sql要查询的map<String,Object>(列名,列的值).
注意:修改ContentProvider代码后要把那个应用重新发到手机上运行.
cr.insert(uri,values);
cr.delete(uri,where, selectionArgs);
cr.update(uri,values, where, selectionArgs);
cr.query(uri,projection, selection, selectionArgs, sortOrder);
(四)查询参数详解
table:表名。相当于select语句from关键字后面的部分。如果是多表联合查询,可以用逗号将两个表名分开。projection:表示要查询列名的数组.null表示查询所有列.
columns:要查询出来的列名。相当于select语句select关键字后面的部分。
selection:查询条件子句,相当于select语句where关键字后面的部分,在条件子句允许使用占位符“?”
selectionArgs:对应于selection语句中占位符的值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常。
groupBy:相当于select语句group by关键字后面的部分
having:相当于select语句having关键字后面的部分
orderBy:相当于select语句order by关键字后面的部分,如:personiddesc(倒序), age asc;
limit:指定偏移量和获取的记录数,相当于select语句limit关键字后面的部分。
(五)观察者:contentObserver
外部应用注册观察者用于监听应用数据的修改:contentObserver类1. 通过getContentResolver对象注册一个ContentObserver
有三个参数:
Uri:这个Uri是应用清单文件中定义的Provider的authorites,但在前面要加上content://
boolean:表示是uri是绝对
Observer:自已定一个观察者对象
public class MainActivity
extends Activity {
public
void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 给应用中注册一个观察者ContentObserver:参数为应用的uri
Uri uri = Uri.parse("content://com.itheima.SQLiteProvider");
MyObserver observer =new MyObserver();
getContentResolver().registerContentObserver(uri,
true,observer );
System.out.println("register");
}
2. 创建一个MyObserver对象,让其作参数:具本观察细节在onChange()方法定义.
private class MyObserver
extendsContentObserver {
public MyObserver() {
// 在主线程中创建的Handler, onChange()方法就在主线程中执行
super(new Handler());
}
public void onChange(boolean selfChange) {
System.out.println("收到数据修改的通知!");
}
}
3. 定义ContentProvider类中哪些方法执行时让外部观察.
通过notifyChange(uri,null)方法
那么数据一旦修改,就会执行onChange()方法
public Uriinsert(Uri uri, ContentValues values) {
SQLiteDatabase db = helper.getWritableDatabase();
getContext().getContentResolver().notifyChange(uri,null);
不需要观察时卸载一个Resolver观察者
getContentResolver().unregisterContentObserver(observer);
observer = null;
(六)短信的监听案例:
短信:mms应用是通过ContentProvider将收到的短信存入Provider.telephty中的数据库.注册监听,要知道应用的uri,
用git工具,或直接去zip下载应用的源码
短信的uri就是sms
在应用中注册观察者就行了.
在onChange方法中定义查询短信query方法
查结果集注意Cursor可能有别名
Cursor的getCount方法能获得有多少数据
getlumnNames()方法获得所有列名.
_id在desc Limit 1 查数据库中最后一条记录
获得结果集后.得到想要的数据
(七)操作联系人案例---不通过事物而通过批处理appilBatch实现
读取联系人主要看这数据库的三张表:
raw_contacts:只有id 是data的外键,1对多:比如.1号联系人有三个数据,姓名,电话,邮箱....
data:是详细数据
mimetype:表示数据类型
Authorites:
要读和写联系人的权限:READ_CONTACTWRITE_CONTACT
先查raw_contact的_id
再通过_id查data的 data1raw_contact
双重循环去查找
data2里面的是电话是表示选的哪一种联系方式
data2中的是名字中的名 data3是名字的姓.
写联系人
向raw_contacts表中加一个id
再通过一个id,加三个数据
appilBatch方法实现类似于事务的操作
有两个参数:一个是Uri 一个是List里面放批量各个操作
各个操作是一个对象,用ContentProvider的静态方法创建.
三、什么时候用?
当一个应用的数据需要给外部使用时,或者外部需要监听应用内部的修改很多应用内部已定义好了,内容提供者,如电话本,短信,其实内部已经实现了内容提供者,我们看到的只是通过内容提供者访问其的数据的界面层
四、内容提供者特点:
① ContentProvider生命周期1.应用安装好,就会创建好,手机开机后,第一次被访问时,被创建
2.只要创建了,只要手机没关机,就会一直存在,类似于在注册表里注册一样
3.手机关机,才会消失
4.应用里的数据都可以提供访问.不一定是数据库,在方法里自已定义就可以,但通常通是访问数据库
② getContext与getApplication方法的区别:都是得到当前应用的上下文环境
getApplication:是在Activity中定义的
getContext是由虚拟机setContext创建的进来的.
相关文章推荐
- Android个人每天总结.doc(day07四大组件之:广播接收者&服务Service)
- Android个人每天总结.doc(day06 多线程&Handler类&四大组件之:Activity)
- Android之四大组件之一-ContentProvider内容提供者的使用(二)
- Android个人每天总结.doc(day03 ListView)
- Android个人每天总结.doc(day08 多媒体)
- Android组件系列----ContentProvider内容提供者
- android四大组件之一内容提供者contentprovider
- Android四大组件之一ContentProvider内容提供者(继SQLite数据存储篇)
- Android组件系列----ContentProvider内容提供者
- Android四大组件之ContentProvider(内容提供者)02
- Android 四大组件之一 :ContentProvider内容提供者从入门到精通
- Android Day09四大组件之内容提供者ContentProvider
- Android之内容提供者ContentProvider的总结
- Android四大组件之一ContentProvider(内容提供者)
- Android四大组件之内容提供者Content Provider总结
- Android组件之ContentProvider(内容提供者)
- Android个人每天总结.doc(day02 文件&数据库)
- Android个人每天总结.doc(day05网络应用)
- Android个人每天总结.doc(1)
- Android内容提供者ContentProvider总结