Android ContentProvider数据共享
一、构造一个自己的Provider实现App之间数据共享
1、我们先来了解一下 Uri(统一资源定位符)
定义:每一个Content Provider使用一个公开的URI唯一标示其数据集,Android所提供的ContentProvider都存放android.provider包中
结构:分为A、B、C、D四个部分 A:标准前缀,用来说明一个Content Provider控制这些数据,无法改变的;
B:URI 的标识,唯一标识ContentProvider,外部调用者可以根据这个标识来找到它。为了保证URI标识的唯一性,它必须是一个完整的、小写的类名。一般是定义该ContentProvider的包.类的名称
C:路径(path),通俗的讲就是你要操作的数据库中表的名字,或者你也可以自己定义,记得在使用的时候保持一致就可以了;
D:如果URI中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示返回全部; "content://com.gdnf.provider/tablename/#" #表示数据id。 路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
1、要操作person表中id为10的记录,可以构建这样的路径:/person/10
2、要操作person表中id为10的记录的name字段,
person/10/name
3、要操作person表中的所有记录,可以构建这样的路径:/person
4、当然要操作的数据不一定来自数据库,也可以是文件、xml或网络等其他存储方式,如下:要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
5、如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:Uri
uri
= Uri.parse("content://com.bing.provider.personprovider/person")
2、UriMatcher
UriMatcher主要用在ContentProvider中,用来构建URI匹配项和判断Uri的正确性,如在insert之前先判断用户传进来的Uri是否与UriMatcher定义的匹配。
3、ContentUris
Long id=ContentUris.parseId(uri);取出URI中传递的ID
Uri uri=ContentUris.withAppendedId(uri,id);为Uri追加ID
4、案例代码
package com.example.provider; import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.support.annotation.Nullable; import com.example.dao.StuDao; /**
* Created by Administrator on 2017/12/18.
*/ public class StuProvider extends ContentProvider { //定义authorities--这是表示Uri的“B部分”,获取ContentProvider的包名
private static final String authorities="com.example.provider.stuprovider"; //构建UriMatcher对象(用于管理和匹配Uri)
private static UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH); //为每一个Uri定义一个编码
//所有Stu的编码为1
private static final int STUS=1;
//一个Stu的编码为2
private static final int STU=2;
//根据姓名查找Stu的编码为3
private static final int STU_NAME=3;
//根据性别查找Stu的编码为4
private static final int STU_SEX=4;
//应用UriMatcher对象构建Uri匹配项
static{
//A部分默认为:content:。只需带入B、C、D的值
matcher.addURI(authorities,"/stu",STUS);
matcher.addURI(authorities,"/stu/#",STU);
matcher.addURI(authorities,"/stu/#/name",STU_NAME);
matcher.addURI(authorities,"/stu/#/sex",STU_SEX);
} //声明上下文
private Context context;
@Override
public boolean onCreate() {
context=getContext();
return false;
} @Nullable
@Override
public String getType(Uri uri) {
if(matcher.match(uri)==STUS){
return "vnd.android.cursor.dir/stu";
}else if(matcher.match(uri)==STU){
return "vnd.android.cursor.item/stu";
}
return null;
} @Nullable
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
if(matcher.match(uri)==STUS){
long id=new StuDao(context).addStu(contentValues);//添加学生
Uri newUri=ContentUris.withAppendedId(uri,id); //发生了数据变化,给出一个通知信号
getContext().getContentResolver().notifyChange(uri,null);
return newUri;
}
return null;
} @Override
public int delete(Uri uri, String s, String[] strings) {
StuDao dao=new StuDao(context);
switch (matcher.match(uri)){
case STUS:
dao.delete("tb_stu",null,null);
break;
case STU:
long id=ContentUris.parseId(uri);//从Uri里面解析出Id
dao.delete("tb_stu","_id="+id,null);
break;
}
//发生了数据编号,给出一个通知信号
getContext().getContentResolver().notifyChange(uri,null);
return 0;
} @Override
public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
StuDao dao=new StuDao(context);
int i=-1;
switch (matcher.match(uri)){
case STUS:
i=dao.update("tb_stu",contentValues,s,strings);
break;
case STU:
long id=ContentUris.parseId(uri);//从Uri里面解析出Id
i=dao.update("tb_stu",contentValues,"_id="+id,null);
break;
}
//发生了数据编号,给出一个通知信号
getContext().getContentResolver().notifyChange(uri,null);
return 0;
} @Nullable
@Override
public Cursor query(Uri uri, String[] strings, String s, String[] strings1, String s1) {
StuDao dao=new StuDao(context);
Cursor cursor=null;
switch (matcher.match(uri)){
case STUS:
cursor=dao.queryStu(strings,s,strings1,null,null,s1,null);
break;
case STU:
long id=ContentUris.parseId(uri);//从Uri里面解析出Id
cursor=dao.queryStu(strings,"_id="+id,null,null,null,s1,null);
break;
}
return cursor;
}
}
二、在另一个程序中如何使用ContentResolver内容解析器进行数据操作
1、ContentResolver操作ContentProvider中的数据
当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用getContentResolver()方法获取ContentResolver对象
2、监听ContentProvider中数据的变化
如果ContentProvider的访问者需要监听ContentProvider中的数据变化,可以注册一个观察者getContentResolver().registerContentObserver(uri,bool,observer)
3、数据提供者在数据发生改变时发出消息
getContent().getContentResolver().notifyChange(uri,null)
4、案例代码
package com.example.android_contentprover_test; import android.app.Activity;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Toast; public class MainActivity extends Activity { //定义一个ContentResolver内容解析器
private ContentResolver resolver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //获取系统的ContentResolver对象
resolver=getContentResolver();
//为resolver添加一个监听事件,监听数据是否发生变化
Uri uri=Uri.parse("content://com.example.provider.stuprovider/stu");
resolver.registerContentObserver(uri,true,new StuObServer(handler));
} //构建一个handler对象执行数据操作
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==1){
//为所欲为
findStuList(null);//执行查询
}
}
}; //构建一个观察者类
private class StuObServer extends ContentObserver{ private Handler handler;
public StuObServer(Handler handler) {
super(handler);
this.handler=handler;
}
//当发生改变时
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//监听到数据发生改变时,发出一个编号为1的消息
handler.sendEmptyMessage(1);
}
} public void addStu(View view){
//声明数据来源——路径
Uri addUri=Uri.parse("content://com.example.provider.stuprovider/stu");
//创建一个数据对象
ContentValues values=new ContentValues();
values.put("sname","Join");
values.put("sage",21);
values.put("ssex","男");
//使用内容解析器执行添加(参数为:数据的来源,更改的数据)
Uri newUri=resolver.insert(addUri,values);
//通过解析器得到更改数据的ID
long id= ContentUris.parseId(newUri);
Toast.makeText(this, "添加学生成功,ID="+id, Toast.LENGTH_SHORT).show(); //使用内容解析器调用查询方法,查询数据
Cursor cursor=resolver.query(newUri,null,null,null,null);
if(cursor.moveToNext()){
int _id=cursor.getInt(cursor.getColumnIndex("_id"));
String name=cursor.getString(cursor.getColumnIndex("sname"));
Toast.makeText(this, "ID="+_id+",Name="+name, Toast.LENGTH_SHORT).show();
}
cursor.close();
} public void findStuList(View view){
Uri uri=Uri.parse("content://com.example.provider.stuprovider/stu");
Cursor cursor=resolver.query(uri,null,null,null,null);
while(cursor.moveToNext()){
int _id=cursor.getInt(cursor.getColumnIndex("_id"));
String name=cursor.getString(cursor.getColumnIndex("sname"));
Log.i("App1 StuList", "ID="+_id+",Name="+name);
}
cursor.close();
}
}
Android ContentProvider数据共享的更多相关文章
- Android基础 : Android ContentProvider
Android 应用程序通过ContentProvider实现方式统一的数据共享功能. 外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activi ...
- Android--简单开发和使用ContentProvider数据共享
今天学习的时候学到了ContentProvider数据共享这个东东,所以自己写了个小例子: 我们要开发ContentProvider的话,需要创建一个类去继承ContentProvider,里面会让你 ...
- Android ContentProvider基本用法
转自:https://www.jianshu.com/p/601086916c8f 一.基本概念 ContentProvider是Android系统中提供的专门用户不同应用间进行数据共享的组件,提供了 ...
- Android ContentProvider完整案例
ContentData类,提供数据常量: /** * 提供ContentProvider对外的各种常量,当外部数据需要访问的时候,就可以参考这些常量操作数据. * @author HB * */ pu ...
- Android ContentProvider 启动分析
对于 ContentProvider 还不是很熟悉的同学,可以阅读上一篇 Android ContentProvider 基本原理和使用详解.本文主要是对 contentProvider 的源码进行分 ...
- Android ContentProvider和Uri详解 (绝对全面)
ContentProvider的基本概念 : 1.ContentProvider为存储和读取数据提供了统一的接口 2.使用ContentProvider,应用程序可以实现数据共享 3.andr ...
- Android ContentProvider和Uri详解
一.使用ContentProvider(内容提供者)共享数据 ContentProvider在android中的作用是对外共享数据, 也就是说你可以通过ContentProvider把应用中的数据共享 ...
- android ContentProvider 笔记
学习android的contentprovider.笔记记录于此. contentprovider作用是将数据共享给其他的应用. 参考链接 https://www.tutorialspoint.com ...
- Android ContentProvider、ContentResolver和ContentObserver的使用
1.ContentProvider.ContentResolver和ContentObserver ContentProvider是Android的四大组件之中的一个,可见它在Android中的作用非 ...
随机推荐
- Spring 使用javaconfig配置aop
1.在xml中需要配置自动代理 /** * */ package com.junge.demo.spring.dao; import org.springframework.context.annot ...
- Burpsuite常用模块详解以及渗透测试上的运用
0x00前言 哪有什么前言,大家好,我是浅安.QQ:320229344... 0x01 JDK的安装,以及Burpsuite的成功开启. burpsuite基于JAVA环境才能正常运行的.所以要先安装 ...
- JavaScript使用浏览器内置XML解析器解析DOM对象
所有现代浏览器都内建了供读取和操作 XML 的 XML 解析器.解析器把 XML 转换为 XML DOM 对象 (可通过 JavaScript 操作的对象). 一.获取DOM对象 XMLHttpReq ...
- scrapy Data flow
The data flow in Scrapy is controlled by the execution engine, and goes like this:1. The Engine gets ...
- Bootstrap 3的box-sizing样式导致UMeditor控件的图片无法正常缩放
UMeditor组件是百度提供的一套开源的web在线所见即所得富文本编辑器,是UEditor的简化版,UM的主要特点就是容量和加载速度上的改变,主文件的代码量为139k,而且放弃了使用传统的ifram ...
- Django2.1发布,Django2.1新特性
Django 2.1 现已正式发布,官方表示随着 2.1 的发布,对 2.0 系列的主流支持服务将结束,进入安全修复服务周期,直至2019年4月. 2.1新特性:https://docs.django ...
- Rip配置
Rip配置 首先建立如图拓扑图 分别配置两台电脑的ip地址和子网掩码和网关.如图所示. 在router0上配置两个端口的IP以及子网掩码 在路由器router0上配置rip2协议.里面的no auto ...
- DevExpress GridView自动滚动
引言 最新有一个winform项目使用的是DevExpress的控件,所以最近都在摸索使用这套控件,实在是佩服整套控件的强大,同时代码写起来也简洁.客户有一个需求,希望报表结果能在外接的大屏幕上定时滚 ...
- Eclipse创建web项目目录结构
效果图如下: 0 新建Web项目 1.右击项目MyProject进入Java Build Path 2. 点击Add Folder按钮,进入如下界面 3.选择src,点击Add New Folder按 ...
- PHP-CPP开发扩展(五)
PHP-CPP是一个用于开发PHP扩展的C++库.本节讲解如何在C++中实现PHP类. 类和对象 类和对象 怎样在PHP-CPP里写出PHP的类呢?很简单,看下面的例子: main.cpp /** * ...