一、构造一个自己的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. SDWebImage之SDWebImageDownloaderOperation

    上篇讲了SDWebImageDownloader,从源码分析的过程中,我们知道,实际执行下载任务的是SDWebImageDownloaderOperation,本篇我们来看看SDWebImageDow ...

  2. GitHub 轻松提速教程

    通过修改hosts文件来提速,获取github的IP地址 访问:https://www.ipaddress.com/ 网址 依次获取以下三个网址的IP github.com github.global ...

  3. maya2015卸载/安装失败/如何彻底卸载清除干净maya2015注册表和文件的方法

    maya2015提示安装未完成,某些产品无法安装该怎样解决呢?一些朋友在win7或者win10系统下安装maya2015失败提示maya2015安装未完成,某些产品无法安装,也有时候想重新安装maya ...

  4. oracle中常用的对用户的操作

    创建用户:create user usr1 identified by pwd default tablespace ts1 temporary tablespace tmp; 删除用户:drop u ...

  5. MySQL百万级、千万级数据多表关联SQL语句调优

    本文不涉及复杂的底层数据结构,通过explain解释SQL,并根据可能出现的情况,来做具体的优化,使百万级.千万级数据表关联查询第一页结果能在2秒内完成(真实业务告警系统优化结果).希望读者能够理解S ...

  6. Android应用内实现视频播放--腾讯浏览服务(TBS)

    TBS视频播放 TBS视频播放器可以支持市面上几乎所有的视频格式,包括mp4, flv, avi, 3gp, webm, ts, ogv, m3u8, asf, wmv, rm, rmvb, mov, ...

  7. 全网最详细的一个超级好用的命令行工具【Cmder】是什么?

    不多说,直接上干货! Cmder是什么? 一款Windows环境下非常简洁美观易用的cmd替代者,它支持了大部分的Linux命令.支持ssh连接linux,使用起来非常方便.比起cmd.powersh ...

  8. Struts2学习(五)———— s标签和国际化

    一.s标签 在struts-2.3.15.1/docs/WW/docs/tag-reference.html下,就有着struts2所有标签的参考文献,只能看看其中比较常用的标签.其他的以后遇到了在看 ...

  9. Shell 示例:将指定的文件内容转换为大写

    程序代码如下: #!/bin/bash # 将一个指定的输入文件内容转换为大写 E_FILE_ACCESS=70 E_WRONG_ARGS=71 if [ ! -r "$1" ] ...

  10. 关于EF实体类的一点思考

    在EF中修改一条记录时,一般是先查出该条记录,然后再通过TryUpdateModel或其他方式更新对应的属性.但我很讨厌这种要更新一条记录时,还要先去把记录查询出来的做法.我喜欢像sql语句那样的直接 ...