采用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. SDL初识

    1.SDL是什么? SDL(Security Development Lifecycle)安全开发生命周期.是微软提出的从安全角度指导软件开发的管理模式,在软件开发的生命周期中尽可能地发现安全隐患,降 ...

  2. 01 . RabbitMQ简介及部署

    RabbitMQ简介 ​ MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它 ...

  3. Redis详解(十二)------ 缓存穿透、缓存击穿、缓存雪崩

    本篇博客我们来介绍Redis使用过程中需要注意的三种问题:缓存穿透.缓存击穿.缓存雪崩. 1.缓存穿透 一.概念 缓存穿透:缓存和数据库中都没有的数据,可用户还是源源不断的发起请求,导致每次请求都会到 ...

  4. 本地安装JDK1.7和1.8,可相互快速切换

    1.JDK官网下载jdk1.7和jdk1.8 https://www.oracle.com/java/technologies/javase-jdk8-downloads.html 2.将jdk1.7 ...

  5. HTML静态页面项目:英雄联盟官网网站 的实现

    效果: 源码与素材:链接: https://pan.baidu.com/s/1OuJd1lfEV7mrnf0I6FXm4A 提取码: 5c6j 复制这段内容后打开百度网盘手机App,操作更方便哦

  6. Java实现 蓝桥杯 算法提高 抽卡游戏

    试题 算法提高 抽卡游戏 某个抽卡游戏卡池抽出限定卡的概率为p,该游戏有一个"井"的机制,抽满k次卡后直接送这张限定卡.试求获得这张限定卡需要的期望抽卡次数.输入为一行,用空格隔开 ...

  7. Java实现 蓝桥杯 算法提高 求arccos值

    算法提高 7-2求arccos值 时间限制:10.0s 内存限制:256.0MB 提交此题 问题描述 利用标准库中的cos(x)和fabs(x)函数实现arccos(x)函数,x取值范围是[-1, 1 ...

  8. Java实现 LeetCode 424 替换后的最长重复字符

    424. 替换后的最长重复字符 给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次.在执行上述操作后,找到包含重复字母的最长子串的长度. 注意: 字 ...

  9. Java实现 蓝桥杯VIP 算法训练 开心的金明

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:"你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NN元钱 ...

  10. Java实现 LeetCode 297 二叉树的序列化与反序列化

    297. 二叉树的序列化与反序列化 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得 ...