一、构造一个自己的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数据共享的更多相关文章

  1. Android基础 : Android ContentProvider

    Android 应用程序通过ContentProvider实现方式统一的数据共享功能. 外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activi ...

  2. Android--简单开发和使用ContentProvider数据共享

    今天学习的时候学到了ContentProvider数据共享这个东东,所以自己写了个小例子: 我们要开发ContentProvider的话,需要创建一个类去继承ContentProvider,里面会让你 ...

  3. Android ContentProvider基本用法

    转自:https://www.jianshu.com/p/601086916c8f 一.基本概念 ContentProvider是Android系统中提供的专门用户不同应用间进行数据共享的组件,提供了 ...

  4. Android ContentProvider完整案例

    ContentData类,提供数据常量: /** * 提供ContentProvider对外的各种常量,当外部数据需要访问的时候,就可以参考这些常量操作数据. * @author HB * */ pu ...

  5. Android ContentProvider 启动分析

    对于 ContentProvider 还不是很熟悉的同学,可以阅读上一篇 Android ContentProvider 基本原理和使用详解.本文主要是对 contentProvider 的源码进行分 ...

  6. Android ContentProvider和Uri详解 (绝对全面)

        ContentProvider的基本概念 : 1.ContentProvider为存储和读取数据提供了统一的接口 2.使用ContentProvider,应用程序可以实现数据共享 3.andr ...

  7. Android ContentProvider和Uri详解

    一.使用ContentProvider(内容提供者)共享数据 ContentProvider在android中的作用是对外共享数据, 也就是说你可以通过ContentProvider把应用中的数据共享 ...

  8. android ContentProvider 笔记

    学习android的contentprovider.笔记记录于此. contentprovider作用是将数据共享给其他的应用. 参考链接 https://www.tutorialspoint.com ...

  9. Android ContentProvider、ContentResolver和ContentObserver的使用

    1.ContentProvider.ContentResolver和ContentObserver ContentProvider是Android的四大组件之中的一个,可见它在Android中的作用非 ...

随机推荐

  1. Spring 使用javaconfig配置aop

    1.在xml中需要配置自动代理 /** * */ package com.junge.demo.spring.dao; import org.springframework.context.annot ...

  2. Burpsuite常用模块详解以及渗透测试上的运用

    0x00前言 哪有什么前言,大家好,我是浅安.QQ:320229344... 0x01 JDK的安装,以及Burpsuite的成功开启. burpsuite基于JAVA环境才能正常运行的.所以要先安装 ...

  3. JavaScript使用浏览器内置XML解析器解析DOM对象

    所有现代浏览器都内建了供读取和操作 XML 的 XML 解析器.解析器把 XML 转换为 XML DOM 对象 (可通过 JavaScript 操作的对象). 一.获取DOM对象 XMLHttpReq ...

  4. scrapy Data flow

    The data flow in Scrapy is controlled by the execution engine, and goes like this:1. The Engine gets ...

  5. Bootstrap 3的box-sizing样式导致UMeditor控件的图片无法正常缩放

    UMeditor组件是百度提供的一套开源的web在线所见即所得富文本编辑器,是UEditor的简化版,UM的主要特点就是容量和加载速度上的改变,主文件的代码量为139k,而且放弃了使用传统的ifram ...

  6. Django2.1发布,Django2.1新特性

    Django 2.1 现已正式发布,官方表示随着 2.1 的发布,对 2.0 系列的主流支持服务将结束,进入安全修复服务周期,直至2019年4月. 2.1新特性:https://docs.django ...

  7. Rip配置

    Rip配置 首先建立如图拓扑图 分别配置两台电脑的ip地址和子网掩码和网关.如图所示. 在router0上配置两个端口的IP以及子网掩码 在路由器router0上配置rip2协议.里面的no auto ...

  8. DevExpress GridView自动滚动

    引言 最新有一个winform项目使用的是DevExpress的控件,所以最近都在摸索使用这套控件,实在是佩服整套控件的强大,同时代码写起来也简洁.客户有一个需求,希望报表结果能在外接的大屏幕上定时滚 ...

  9. Eclipse创建web项目目录结构

    效果图如下: 0 新建Web项目 1.右击项目MyProject进入Java Build Path 2. 点击Add Folder按钮,进入如下界面 3.选择src,点击Add New Folder按 ...

  10. PHP-CPP开发扩展(五)

    PHP-CPP是一个用于开发PHP扩展的C++库.本节讲解如何在C++中实现PHP类. 类和对象 类和对象 怎样在PHP-CPP里写出PHP的类呢?很简单,看下面的例子: main.cpp /** * ...