android 学习随笔二十一(内容提供者 )

一、内容提供者
* 应用的数据库是不允许其他应用访问的
* 内容提供者的作用就是让别的应用访问到你的私有数据
* 自定义内容提供者,继承ContentProvider类,重写增删改查方法,在方法中写增删改查数据库的代码,举例增方法

@Override
public Uri insert(Uri uri, ContentValues values) {
db.insert("person", null, values);
return uri;
}
* 在清单文件中定义内容提供者的标签,注意必须要有authorities属性,这是内容提供者的主机名,功能类似地址

<provider android:name="com.itheima.contentprovider.PersonProvider"
android:authorities="com.itheima.person"
android:exported="true"
></provider>

通过UriMatcher um = new UriMatcher(UriMatcher.NO_MATCH)指定表

um.addURI("com.itheima.people", "person/#", 3);//content://com.itheima.people/person/10,#匹配任何数字,通常作为WHERE条件使用

vnd.android.cursor.dir/   多条数据
vnd.android.cursor.item/  单条数据
package com.itheima.mycontentprovider.db;

import java.io.Serializable;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Parcelable;

public class MyOpenHelper extends SQLiteOpenHelper {

    public MyOpenHelper(Context context) {
        super(context, "people.db", null, 2);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table person(_id integer primary key autoincrement, name char(10), phone char(20), money integer(10))");
        
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("create table handsome(_id integer primary key autoincrement, name char(10), phone char(20))");
    }

}
定义数据库
package com.itheima.mycontentprovider;

import com.itheima.mycontentprovider.db.MyOpenHelper;

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;

public class PersonProvider extends ContentProvider {

    private SQLiteDatabase db;
    //创建uri匹配器
    UriMatcher um = new UriMatcher(UriMatcher.NO_MATCH);
    {
        //添加匹配规则
        //arg0:主机名
        //arg1:路径
        //arg2:匹配码
        um.addURI("com.itheima.people", "person", 1);//content://com.itheima.people/person
        um.addURI("com.itheima.people", "handsome", 2);//content://com.itheima.people/handsome
        um.addURI("com.itheima.people", "person/#", 3);//content://com.itheima.people/person/10
    }
    
    //内容提供者创建时调用
    @Override
    public boolean onCreate() {
        MyOpenHelper oh = new MyOpenHelper(getContext());
        db = oh.getWritableDatabase();
        return false;
    }

    //values:其他应用要插的数据
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        if(um.match(uri) == 1){
            db.insert("person", null, values);
            
            //数据库改变了,内容提供者发出通知
            //arg0:通知发到哪个uri上,注册在这个uri上的内容观察者都可以收到通知
            getContext().getContentResolver().notifyChange(uri, null);
        }
        else if(um.match(uri) == 2){
            db.insert("handsome", null, values);
            
            getContext().getContentResolver().notifyChange(uri, null);
        }
        else{
            throw new IllegalArgumentException("uri传错啦傻逼");
        }
        return uri;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int i = 0;
        if(um.match(uri) == 1){
            i = db.delete("person", selection, selectionArgs);
        }
        else if(um.match(uri) == 2){
            i = db.delete("handsome", selection, selectionArgs);
        }
        else{
            throw new IllegalArgumentException("uri又传错啦傻逼");
        }
        
        return i;
    }
    
    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        int i = db.update("person", values, selection, selectionArgs);
        return i;
    }
    
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        Cursor cursor = null;
        if(um.match(uri) == 1){
            cursor = db.query("person", projection, selection, selectionArgs, null, null, sortOrder, null);
        }
        else if(um.match(uri) == 2){
            cursor = db.query("handsome", projection, selection, selectionArgs, null, null, sortOrder, null);
        }
        else if(um.match(uri) == 3){
            //取出uri末尾携带的数字
            long id = ContentUris.parseId(uri);
            cursor = db.query("person", projection, "_id = ?", new String[]{"" + id}, null, null, sortOrder, null);
        }
        return cursor;
    }
    
    //返回通过指定uri获取的数据的mimetype
    @Override
    public String getType(Uri uri) {
        if(um.match(uri) == 1){
            return "vnd.android.cursor.dir/person";
        }
        else if(um.match(uri) == 2){
            return "vnd.android.cursor.dir/handsome";
        }
        else if(um.match(uri) == 3){
            return "vnd.android.cursor.item/person";
        }
        return null;
    }

    

}
内容提供者
package com.itheima.mycontentprovider;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
}
MainActivity
package com.itheima.mycontentprovider;

import com.itheima.mycontentprovider.db.MyOpenHelper;

import android.test.AndroidTestCase;

public class Test extends AndroidTestCase {

    public void test(){
        MyOpenHelper oh = new MyOpenHelper(getContext());
        oh.getWritableDatabase();
    }
}
test
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.itheima.mycontentprovider"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
<instrumentation android:name="android.test.InstrumentationTestRunner"
    android:targetPackage="com.itheima.mycontentprovider"></instrumentation>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        
        <uses-library android:name="android.test.runner"/>
        <activity
            android:name="com.itheima.mycontentprovider.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <provider 
            android:name="com.itheima.mycontentprovider.PersonProvider"        
            android:authorities="com.itheima.people"
            
            android:exported="true"
>
        </provider>
    </application>

</manifest>
AndroidManifest

* 创建一个其他应用,访问自定义的内容提供者,实现对数据库的插入操作

public void click(View v){
//得到内容分解器对象
ContentResolver cr = getContentResolver();
ContentValues cv = new ContentValues();
cv.put("name", "小方");
cv.put("phone", 138856);
cv.put("money", 3000);
//url:内容提供者的主机名
cr.insert(Uri.parse("content://com.itheima.person"), cv);
}

package com.itheima.other;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void insert(View v){
        //通过内容提供者把数据插入01数据库
        //1.获取contentResolver
        ContentResolver resolver = getContentResolver();
        //2.访问内容提供者,插入数据
        ContentValues values = new ContentValues();
        values.put("name", "流氓润");
        values.put("phone", 138992);
        values.put("money", 14000);
        //arg0:指定内容提供者的主机名
        resolver.insert(Uri.parse("content://com.itheima.people/person"), values);
        
        values.clear();
        values.put("name", "侃哥");
        values.put("phone", 15999);
        //arg0:指定内容提供者的主机名
        resolver.insert(Uri.parse("content://com.itheima.people/handsome"), values);
    }
    
    public void delete(View v){
        ContentResolver resolver = getContentResolver();
        int i = resolver.delete(Uri.parse("content://com.itheima.people"), "name = ?", new String[]{"凤姐"});
        System.out.println(i);
    }
    
    public void update(View v){
        ContentResolver resolver = getContentResolver();
        ContentValues values = new ContentValues();
        values.put("money", 16001);
        int i = resolver.update(Uri.parse("content://com.itheima.people"), values, "name = ?", new String[]{"春晓"});
        System.out.println(i);
    }
    
    public void query(View v){
        ContentResolver resolver = getContentResolver();
        Cursor cursor = resolver.query(Uri.parse("content://com.itheima.people/person"), null, null, null, null);
        while(cursor.moveToNext()){
            String name = cursor.getString(1);
            String phone = cursor.getString(2);
            String money = cursor.getString(3);
            System.out.println(name + ";" + phone + ";" + money);
        }
    }
    public void queryOne(View v){
        ContentResolver resolver = getContentResolver();
        Cursor cursor = resolver.query(Uri.parse("content://com.itheima.people/person/4"), null, null, null, null);
        if(cursor.moveToNext()){
            String name = cursor.getString(1);
            String phone = cursor.getString(2);
            String money = cursor.getString(3);
            System.out.println(name + ";" + phone + ";" + money);
        }
    }
}
View Code

UriMatcher
* 用于判断一条uri跟指定的多条uri中的哪条匹配
* 添加匹配规则

//指定多条uri
um.addURI("com.itheima.person", "person", PERSON_CODE);
um.addURI("com.itheima.person", "company", COMPANY_CODE);
//#号可以代表任意数字
um.addURI("com.itheima.person", "person/#", QUERY_ONE_PERSON_CODE);
* 通过Uri匹配器可以实现操作不同的表

@Override
public Uri insert(Uri uri, ContentValues values) {
if(um.match(uri) == PERSON_CODE){
db.insert("person", null, values);
}
else if(um.match(uri) == COMPANY_CODE){
db.insert("company", null, values);
}
else{
throw new IllegalArgumentException();
}
return uri;
}
* 如果路径中带有数字,把数字提取出来的api

int id = (int) ContentUris.parseId(uri);

二、获取系统短信

短信数据库
* 只需要关注sms表
* 只需要关注4个字段
* body:短信内容
* address:短信的发件人或收件人号码(跟你聊天那哥们的号码)
* date:短信时间
* type:1为收到,2为发送
###读取系统短信,首先查询源码获得短信数据库内容提供者的主机名和路径,然后访问内容提供者(掌握)

ContentResolver cr = getContentResolver();
Cursor c = cr.query(Uri.parse("content://sms"), new String[]{"body", "date", "address", "type"}, null, null, null);
while(c.moveToNext()){
String body = c.getString(0);
String date = c.getString(1);
String address = c.getString(2);
String type = c.getString(3);
System.out.println(body+";" + date + ";" + address + ";" + type);
}

package com.itheima.getsms;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    public void click1(View v){
        ContentResolver resolver = getContentResolver();
        Cursor cursor = resolver.query(Uri.parse("content://sms"), new String[]{"address", "date", "type", "body"}, null, null, null);
        while(cursor.moveToNext()){
            String address = cursor.getString(0);
            long date = cursor.getLong(1);
            int type = cursor.getInt(2);
            String body = cursor.getString(3);
            
            System.out.println(address + ";" + date + ";" + type + ";" + body);
        }
    }
    
}
MainActivity
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.itheima.getsms"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.READ_SMS"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.itheima.getsms.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
AndroidManifest

 三、插入系统短信

插入系统短信

ContentResolver cr = getContentResolver();
ContentValues cv = new ContentValues();
cv.put("body", "您尾号为XXXX的招行储蓄卡收到转账1,000,000人民币");
cv.put("address", 95555);
cv.put("type", 1);
cv.put("date", System.currentTimeMillis());
cr.insert(Uri.parse("content://sms"), cv);
* 插入查询系统短信需要注册权限

package com.itheima.insertsms;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    public void click(View v){
        Thread t = new Thread(){
            @Override
            public void run() {
                try {
                    sleep(7000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                ContentResolver resolver = getContentResolver();
                ContentValues values = new ContentValues();
                values.put("address", 95555);
                values.put("date", System.currentTimeMillis());
                values.put("type", 1);
                values.put("body", "您尾号为XXXX的招行储蓄卡收到转账1,000,000");
                resolver.insert(Uri.parse("content://sms"), values);
            }
        };
        t.start();
        
    }
    
}
MainActivity
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.itheima.insertsms"
    android:versionCode="1"
    android:versionName="1.0" >
    
    <uses-permission android:name="android.permission.WRITE_SMS"/>
    <uses-permission android:name="android.permission.READ_SMS"/>

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.itheima.insertsms.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
AndroidManifest

 四、联系人数据库

* raw\_contacts表:
* contact_id:联系人id
* data表:联系人的具体信息,一个信息占一行
* data1:信息的具体内容
* raw\_contact_id:联系人id,描述信息属于哪个联系人
* mimetype_id:描述信息是属于什么类型
* mimetypes表:通过mimetype_id到该表查看具体类型

、读取联系人
* 先查询raw\_contacts表拿到联系人id

Cursor cursor = cr.query(Uri.parse("content://com.android.contacts/raw_contacts"), new String[]{"contact_id"}, null, null, null);
* 然后拿着联系人id去data表查询属于该联系人的信息

Cursor c = cr.query(Uri.parse("content://com.android.contacts/data"), new String[]{"data1", "mimetype"}, "raw_contact_id = ?", new String[]{contactId}, null);
* 得到data1字段的值,就是联系人的信息,通过mimetype判断是什么类型的信息

while(c.moveToNext()){
String data1 = c.getString(0);
String mimetype = c.getString(1);
if("vnd.android.cursor.item/email_v2".equals(mimetype)){
contact.setEmail(data1);
}
else if("vnd.android.cursor.item/name".equals(mimetype)){
contact.setName(data1);
}
else if("vnd.android.cursor.item/phone_v2".equals(mimetype)){
contact.setPhone(data1);
}
}

package com.itheima.getcontacts.domain;

public class Contact {

    private String name;
    private String phone;
    private String email;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Override
    public String toString() {
        return "Contact [name=" + name + ", phone=" + phone + ", email="
                + email + "]";
    }
    
    
}
Contact
package com.itheima.getcontacts;

import com.itheima.getcontacts.domain.Contact;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void click(View v){
        ContentResolver resolver = getContentResolver();
        
        Cursor cursor = resolver.query(Uri.parse("content://com.android.contacts/raw_contacts"), new String[]{"contact_id"}, 
                null, null, null);
        while(cursor.moveToNext()){
            String contactId = cursor.getString(0);
            //使用联系人id作为where条件去查询data表,查询出属于该联系人的信息
            Cursor cursorData = resolver.query(Uri.parse("content://com.android.contacts/data"), new String[]{"data1", "mimetype"}, "raw_contact_id = ?", 
                    new String[]{contactId}, null);
//            Cursor cursorData = resolver.query(Uri.parse("content://com.android.contacts/data"), null, "raw_contact_id = ?", 
//                    new String[]{contactId}, null);
            
//            int count = cursorData.getColumnCount();
//            for (int i = 0; i < count; i++) {
//                System.out.println(cursorData.getColumnName(i));
//            }
            
            Contact contact = new Contact();
            while(cursorData.moveToNext()){
                String data1 = cursorData.getString(0);
                String mimetype = cursorData.getString(1);
//                System.out.println(data1 + ";" + mimetype);
                if("vnd.android.cursor.item/email_v2".equals(mimetype)){
                    contact.setEmail(data1);
                }
                else if("vnd.android.cursor.item/phone_v2".equals(mimetype)){
                    contact.setPhone(data1);
                }
                else if("vnd.android.cursor.item/name".equals(mimetype)){
                    contact.setName(data1);
                }
            }
            System.out.println(contact.toString());
        }
    }
    
}
MainActivity
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.itheima.getcontacts"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.READ_CONTACTS"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.itheima.getcontacts.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
View Code

、插入联系人
* 先查询raw\_contacts表,确定新的联系人的id应该是多少
* 把确定的联系人id插入raw\_contacts表

cv.put("contact_id", _id);
cr.insert(Uri.parse("content://com.android.contacts/raw_contacts"), cv);
* 在data表插入数据
* 插3个字段:data1、mimetype、raw\_contact_id

cv = new ContentValues();
cv.put("data1", "赵六");
cv.put("mimetype", "vnd.android.cursor.item/name");
cv.put("raw_contact_id", _id);
cr.insert(Uri.parse("content://com.android.contacts/data"), cv);

cv = new ContentValues();
cv.put("data1", "1596874");
cv.put("mimetype", "vnd.android.cursor.item/phone_v2");
cv.put("raw_contact_id", _id);
cr.insert(Uri.parse("content://com.android.contacts/data"), cv);

package com.itheima.insertcontact;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    public void click(View v){
        ContentResolver resolver = getContentResolver();
        //先查询最新的联系人的主键,主键+1,就是要插入的联系人id
        Cursor cursor = resolver.query(Uri.parse("content://com.android.contacts/raw_contacts"), new String[]{"_id"}, null, null, null);
        int _id = 0;
        if(cursor.moveToLast()){
            _id = cursor.getInt(0);
        }
        _id++;
        
        //插入联系人id
        ContentValues values = new ContentValues();
        values.put("contact_id", _id);
        resolver.insert(Uri.parse("content://com.android.contacts/raw_contacts"), values);
        
        //把具体联系人信息插入data表
        values.clear();
        values.put("data1", "剪刀手坤哥");
        values.put("mimetype", "vnd.android.cursor.item/name");
        values.put("raw_contact_id", _id);
        resolver.insert(Uri.parse("content://com.android.contacts/data"), values);
        
        values.clear();
        values.put("data1", "8899667");
        values.put("mimetype", "vnd.android.cursor.item/phone_v2");
        values.put("raw_contact_id", _id);
        resolver.insert(Uri.parse("content://com.android.contacts/data"), values);
    }
    
}
MainActivity
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.itheima.insertcontact"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.itheima.insertcontact.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
AndroidManifest

、内容观察者

* 当数据库数据改变时,内容提供者会发出通知,在内容提供者的uri上注册一个内容观察者,就可以收到数据改变的通知

cr.registerContentObserver(Uri.parse("content://sms"), true, new MyObserver(new Handler()));

class MyObserver extends ContentObserver{

public MyObserver(Handler handler) {
super(handler);
// TODO Auto-generated constructor stub
}

//内容观察者收到数据库发生改变的通知时,会调用此方法
@Override
public void onChange(boolean selfChange) {

}

}

package com.itheima.contentobserver;

import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //注册内容观察者,观察者就生效了,可以接受内容提供者发出的通知
        ContentResolver resolver = getContentResolver();
        //arg0:指定接收哪个内容提供者发出的通知
        resolver.registerContentObserver(Uri.parse("content://sms"), 
                true, //如果为true,以这个uri作为开头的uri上的数据改变了,该内容观察者都会收到通知
                new MyObserver(new Handler()));
    }
    
    class MyObserver extends ContentObserver{

        public MyObserver(Handler handler) {
            super(handler);
            // TODO Auto-generated constructor stub
        }
        
        @Override
        public void onChange(boolean selfChange) {
            // TODO Auto-generated method stub
            super.onChange(selfChange);
            System.out.println("短信数据库改变");
        }
    }

}
View Code
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.itheima.contentobserver"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.itheima.contentobserver.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
View Code

  在内容提供者中发通知的代码

ContentResolver cr = getContext().getContentResolver();
//发出通知,所有注册在这个uri上的内容观察者都可以收到通知
cr.notifyChange(uri, null);

 接收内容提供者发送的通知

package com.itheima.receivenotify;

import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.database.ContentObserver;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //注册内容观察者接收01发送的通知
        getContentResolver().registerContentObserver(Uri.parse("content://com.itheima.people"), 
                true, new ContentObserver(new Handler()) {
                    @Override
                    public void onChange(boolean selfChange) {
                        // TODO Auto-generated method stub
                        super.onChange(selfChange);
                        System.out.println("01数据库改变");
                    }
                });
    }


    
}
View Code
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.itheima.receivenotify"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.itheima.receivenotify.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
View Code

------------------------------------------

原文地址:https://www.cnblogs.com/ecollab/p/5951430.html