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中的作用非 ...
随机推荐
- hadoop2.4.0伪分布式搭建以及分布式关机重启后datanode没起来的解决办法
1.准备Linux环境 1.0点击VMware快捷方式,右键打开文件所在位置 -> 双击vmnetcfg.exe -> VMnet1 host-only ->修改subnet ip ...
- TortoiseSVN与TortoiseGit
TortoiseSVN与TortoiseGit 功能:版本控制+备份处理 差异:SVN二段式,没有中间存储点,直接提交后到达了远程存储点:要想对本地的修改进行记录,必须要与SVN服务器进行通讯,无法只 ...
- samba服务配置(一)
samba是一个实现不同操作系统之间文件共享和打印机共享的一种SMB协议的免费软件. samba软件结构: /etc/samba/smb.conf #samba服务的主要配置文件 /etc/sa ...
- springboot之使用redistemplate优雅地操作redis
概述 本文内容主要 关于spring-redis 关于redis的key设计 redis的基本数据结构 介绍redis与springboot的整合 sringboot中的redistemplate的使 ...
- Thinking in Java from Chapter 11
From Thinking in Java 4th Edition 持有对象 // Simple container example (produces compiler warnings.) // ...
- java visualVM(jconsole)远程监控服务器java进程
1. JMX方式(jconsole也可通过此方式进行连接) jmx方式能监控到CPU信息,但无法使用visualVM的visualVM GC插件 jmx无密码方式 监控普通的java进程 . 设 ...
- Javascript高级编程学习笔记(8)—— 变量
日常更新~~ 变量 所有的编程语言中,变量都是赋予语言灵活性的根本所在. 那么JS中的变量又有那些与众不同的地方呢.? 按照ECMA-262的定义,JS的变量和其他编程语言的变量有很大的区别 其松散类 ...
- 16.IO之其他流
第一 打印流 一.概述: 该流提供了打印方法,可以将各种数据类型的数据都原样打印 原理; x<=3; x++){ al.add(new FileInputStream(x+".txt ...
- Java学习笔记38(字符流)
字符输出流:Writer类:使用时候需要它的子类 局限性:只能写文本文件,无法写其他文件 方法: package demo; import java.io.FileWriter; import jav ...
- Rocketmq日志收集与logback集成Demo
官方文档有简洁的例子,这里就做一个简单补充和实践 直接上logback-boot.xml文件 <?xml version="1.0" encoding="UTF-8 ...