采用ContentProvider除了可以让其他应用访问当前的app的数据之外,还有可以实现当app的数据发送变化的时候,通知注册了数据变化通知的调用者

其他所有的代码都和第20讲的一样,不同的地方看下面的代码:

package test.weiyuan.sqllite1;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log; import dB.DbOpenHelper; /**
* Created by wei.yuan on 2015/6/3.
* 一定要在清单文件中对内容提供者进行注册
*/
public class PersonProvider extends ContentProvider { private DbOpenHelper dbOpenHelper;
//该类用于检测的外部应用输入的URL是否正确,如果正确返回码就是codePerson,不正确返回UriMatcher.NO_MATCH
private static final int codePerson = 1;
private static final int codePerson1 = 2;
//该类用于检测的外部应用输入的URL是否正确,如果不正确返回码就是new UriMatcher(UriMatcher.NO_MATCH)构造函数中的参数,这里是UriMatcher.NO_MATCH
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static
{
//这个url表示对整个person表进行操作
uriMatcher.addURI("test.weiyuan.sqllite1.PersonProvider","person",codePerson);
//这个url表示对person表中的某个记录进行操作,#表示的是数字,就是对应的person表中的某个记录
uriMatcher.addURI("test.weiyuan.sqllite1.PersonProvider","person/#",codePerson1);
}
//onCreate()之后被调用一次,在调用的时候创建数据库,记得返回值为true
@Override
public boolean onCreate() {
dbOpenHelper = new DbOpenHelper(getContext());
return true;
} //查询数据表的数据
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteDatabase database = dbOpenHelper.getWritableDatabase();
switch (uriMatcher.match(uri))
{
//更新整个表
case codePerson: return database.query("person",projection,selection,selectionArgs,null,null,sortOrder); //更新表中的某条记录
case codePerson1:
long row_id = ContentUris.parseId(uri);
String where = " personid="+row_id;
Log.i("weiyuan",""+row_id);
if (selection!=null&&!"".equals(selection.trim()))
{
where += "and "+selection;
}
return database.query("person",null,where,selectionArgs,null,null,sortOrder); default: //如果传人的url不正确,抛出一个异常提示用户
throw new IllegalArgumentException("this is a unkown url-->"+uri); } } //返回要操作数据的内容类型,如txt文本就是plain/text类型
@Override
public String getType(Uri uri) {
return null;
} //可以让外面的应用向内容提供者插入数据
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase database = dbOpenHelper.getWritableDatabase();
switch (uriMatcher.match(uri))
{
case codePerson:
//这里如果values为空,就必须需要第二个参数有值这里为"name",如果values有值,第二个参数默认为空值
long rowid = database.insert("person",null,values);
// Uri insertUri = Uri.parse("context://test.weiyuan.providers.PersonProvider/person/"+rowid);可以使用下面的方法http://blog.csdn.net/feng88724/article/details/6331396
Uri insertUri = ContentUris.withAppendedId(uri,rowid);
//当数据添加之后,发送通知提供给其他内容提供者
getContext().getContentResolver().notifyChange(uri,null);//发出数据变化的通知
if(database!=null)
{
database.close();
} return insertUri; default:
//如果传人的url不正确,抛出一个异常提示用户
if(database!=null)
{
database.close();
}
throw new IllegalArgumentException("this is a unkown url-->"+uri); } } //返回值int表示你删除了多少条记录
@Override
public int delete(Uri uri, String selection, String[] selectionArgs)
{
SQLiteDatabase database = dbOpenHelper.getWritableDatabase();
switch (uriMatcher.match(uri))
{
//删除整个表
case codePerson: database.delete("preson",selection,selectionArgs);
if(database!=null)
{
database.close();
}
break;
//删除表中的某条记录
case codePerson1:
long row_id = ContentUris.parseId(uri);
String where = " personid="+ row_id;
Log.i("weiyuan",""+row_id);
if (selection!=null&&!"".equals(selection.trim()))
{
where += "and "+selection;
}
database.delete("person",where,selectionArgs);
if(database!=null)
{
database.close();
}
break; default:
//如果传人的url不正确,抛出一个异常提示用户
throw new IllegalArgumentException("this is a unkown url-->"+uri); } return 0;
} @Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase database = dbOpenHelper.getWritableDatabase();
switch (uriMatcher.match(uri))
{
//更新整个表
case codePerson: database.update("preson",values,selection,selectionArgs);
if(database!=null)
{
database.close();
}
break;
//更新表中的某条记录
case codePerson1:
long row_id = ContentUris.parseId(uri);
String where = " personid="+row_id;
Log.i("weiyuan",""+row_id);
if (selection!=null&&!"".equals(selection.trim()))
{
where += "and "+selection;
}
database.update("person",values,where,selectionArgs);
if(database!=null)
{
database.close();
}
break; default:
if(database!=null)
{
database.close();
}
//如果传人的url不正确,抛出一个异常提示用户
throw new IllegalArgumentException("this is a unkown url-->"+uri); }
return 0;
}
}

当有其他应用通过provider想数据库插入数据的时候就会发出   getContext().getContentResolver().notifyChange(uri,null);这个数据变化的广播

其他第三方应该如果注册了这个广播就会收到这个数据库变化的广播

我们来看下面的代码,第三方监听者的代码:

package com.example.weiyuan.myapplication;

import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.provider.Contacts;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView; import java.util.List; public class MainActivity extends ActionBarActivity { private ImageView imageView;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.show); //注册内容提供者变化的监听器
Uri uri = Uri.parse("content://test.weiyuan.sqllite1.PersonProvider/person");
/* //第二个参数很关键true表示只要是以"content://test.weiyuan.sqllite1.PersonProvider/person"开头的url都可以监听
比如"content://test.weiyuan.sqllite1.PersonProvider/person/123",是以"content://test.weiyuan.sqllite1.PersonProvider/person"开头的,也可以监听
但是是false的话,如果要监听"content://test.weiyuan.sqllite1.PersonProvider/person/123"就必须写出
"content://test.weiyuan.sqllite1.PersonProvider/person/123"*/
getContentResolver().registerContentObserver(uri,true,new Observer(new Handler())); } //得到数据变化的通知
public class Observer extends ContentObserver
{ /**
* Creates a content observer.
*
* @param handler The handler to run {@link #onChange} on, or null if none.
*/
public Observer(Handler handler) {
super(handler);
} @Override
public void onChange(boolean selfChange) {
//获得最新的插入数据的内容
Uri uri = Uri.parse("content://test.weiyuan.sqllite1.PersonProvider/person");
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(uri, null, null, null, "personid desc ");
if(cursor.moveToFirst())
{
textView.setText(cursor.getString(cursor.getColumnIndex("name"))+"...."+cursor.getString(cursor.getColumnIndex("phone")));
} super.onChange(selfChange);
} @Override
public boolean deliverSelfNotifications() {
return super.deliverSelfNotifications();
}
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId(); //noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
} return super.onOptionsItemSelected(item);
}
}

上面的代码或者最新插入到数据库中的最新的一条数据。对应系统的通讯录我们也可以监听系统通讯录发送变化的广播,获得最新的通讯录数据。

黎活明8天快速掌握android视频教程--21_监听ContentProvider中数据的变化的更多相关文章

  1. 黎活明8天快速掌握android视频教程--22_访问通信录中的联系人和添加联系人

    Android系统中联系人的通讯录的contentProvide是一个单独的apk,显示在界面的contact也是一个独立的apk,联系人apk通过contentProvide访问底层的数据库. 现在 ...

  2. 黎活明8天快速掌握android视频教程--17_创建数据库与完成数据添删改查

    1.我们首先来看下整个项目 项目也是采用mvc的框架 package dB; import android.content.Context; import android.database.sqlit ...

  3. 黎活明8天快速掌握android视频教程--15_采用Pull解析器解析和生成XML内容

    1.该项目主要有下面的两个作用 (1)将xml文件解析成对象的List对象,xml文件可以来自手机本地,也可以来自服务器返回的xml数据 (2)强list对象保存成xml文件,xml保存到手机的内存卡 ...

  4. 黎活明8天快速掌握android视频教程--25_网络通信之资讯客户端

    1 该项目的主要功能是:后台通过xml或者json格式返回后台的视频资讯,然后Android客户端界面显示出来 首先后台新建立一个java web后台 采用mvc的框架 所以的servlet都放在se ...

  5. 黎活明8天快速掌握android视频教程--24_网络通信之网页源码查看器

    1 该项目的主要功能就是从将后台的html网页在Android的界面上显示出来 后台就是建立一个java web工程在工程尚建立一个html或者jsp文件就可以了,这里主要看Android客户端的程序 ...

  6. 黎活明8天快速掌握android视频教程--23_网络通信之网络图片查看器

    1.首先新建立一个java web项目的工程.使用的是myeclipe开发软件 图片的下载路径是http://192.168.1.103:8080/lihuoming_23/3.png 当前手机和电脑 ...

  7. 黎活明8天快速掌握android视频教程--20_采用ContentProvider对外共享数据

    1.内容提供者是让当前的app的数据可以让其他应用访问,其他应该可以通过内容提供者访问当前app的数据库 contentProvider的主要目的是提供一个开发的接口,让其他的应该能够访问当前应用的数 ...

  8. 黎活明8天快速掌握android视频教程--19_采用ListView实现数据列表显示

    1.首先整个程序也是采用mvc的框架 DbOpenHelper 类 package dB; import android.content.Context; import android.databas ...

  9. 黎活明8天快速掌握android视频教程--16_采用SharedPreferences保存用户偏好设置参数

    SharedPreferences保存的数据是xml格式,也是存在数据保存的下面四种权限: 我们来看看 我们来看看具体的业务操作类: /** * 文件名:SharedPrecences.java * ...

随机推荐

  1. 获取元素节点的子节点 & 获取文本节点

    1. 获取元素节点的子节点(**只有元素节点才有子节点):              ①. childNodes 属性获取全部的子节点, 但该方法不实用. 因为如果要获取指定的节点          ...

  2. ForkJoinPool分支合并框架-工作窃取

    Fork/Join 框架 Fork/Join 框架:就是在必要的情况下,将一个大任务,进行拆分(fork)成 若干个小任务(拆到不可再拆时), 再将一个个的小任务运算的结果进行 join 汇总 For ...

  3. windows下grunt的快速入门

    1.认识grunt  grunt是什么:他是一套前端自动化工具,是一个基于nodejs的命令行工具.(Grunt和Grunt插件是通过npm  安装并管理的,所以首先要安装nodejs). grunt ...

  4. ASP.NET实现一个在线音乐统计网站(歌手,音乐,角色……增删改查)

    这里更多的是当作随身笔记使用,记录一下学到的知识,以便淡忘的时候能快速回顾 当前步骤是该项目的完结部分(前面由于没有时间整理了,直接发一个大完结吧) 第一部分 第二部分 源码已上传GitHub:这里有 ...

  5. (Java实现) 美元汇率

    时空限制 1000ms/128MB 题目背景 此处省略maxint+1个数 题目描述 在以后的若干天里戴维将学习美元与德国马克的汇率.编写程序帮助戴维何时应买或卖马克或美元,使他从100美元开始,最后 ...

  6. Java实现 LeetCode 110 平衡二叉树

    110. 平衡二叉树 给定一个二叉树,判断它是否是高度平衡的二叉树. 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1. 示例 1: 给定二叉树 [3,9 ...

  7. Java实现 蓝桥杯 历届试题 连号区间数

    问题描述 小明这些天一直在思考这样一个奇怪而有趣的问题: 在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是: 如果区间[L, R] 里的所有元素(即此排列的第L个到第R个元素)递增 ...

  8. html页面引用video.js播放m3u8格式视频

    //head里面的内容,我是采用cdn引用的方式,因为项目太小 <head> <meta charset="utf-8" /> <title>二 ...

  9. python3 主机实时监控系统

    主机实时监控系统(可在局域网访问) 一.思路: 前端: 1.管理员登录(编写一个管理员登录界面) 技术:html+css 2.资源数据显示(用于显示主机资源数据情况) 插件:echarts+jquer ...

  10. spring Cloud服务注册中心Eureka集群

    spring Cloud服务注册中心Eureka集群配置: 在application.yml文件加以下配置: server: port: 8761 tomcat: uri-encoding: UTF- ...