一、内容提供者
* 应用的数据库是不允许其他应用访问的
* 内容提供者的作用就是让别的应用访问到你的私有数据
* 自定义内容提供者,继承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);
}
}
}

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>

、插入联系人
* 先查询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("短信数据库改变");
}
} }
<?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>

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

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数据库改变");
}
});
} }
<?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>

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

android 学习随笔二十一(内容提供者 )的更多相关文章

  1. android 学习随笔二十八(应用小知识点小结 )

    去掉标题栏的方法 第一种:也一般入门的时候经常使用的一种方法requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏注意这句一定要写在setConte ...

  2. android 学习随笔二十二(小结)

    ADB进程 * adb指令 * adb install xxx.apk * adb uninstall 包名 * adb devices * adb start-server * adb kill-s ...

  3. android 项目学习随笔二十一(IM、语音识别、机器人、统计、扫描二维码、条形码)

    语音识别:科大讯飞语音云 http://www.xfyun.cn/ 语音机器人模拟 public class TalkBean { public String text; public boolean ...

  4. android 学习随笔二十四(动画:帧动画)

    帧动画,一张张图片不断的切换,形成动画效果 * 在drawable目录下定义xml文件,子节点为animation-list,在这里定义要显示的图片和每张图片的显示时长 * FrameAnimatio ...

  5. android 学习随笔二十三(动画:Fragment )

    Fragment * 用途:在一个Activity里切换界面,切换界面时只切换Fragment里面的内容 * 在一个Activity中切换多个界面,每个界面就是一个Fragment* Fragmnen ...

  6. android 学习随笔二十(多媒体编程 )

    1.图片处理 加载大图片 图片大小的计算 图片大小 = 图片的总像素 * 每个像素占用的大小 * 单色图:每个像素占用1/8个字节* 16色图:每个像素占用1/2个字节* 256色图:每个像素占用1个 ...

  7. Android学习(二十一)OptionsMenu选项菜单

    一.OptionsMenu选项菜单 在应用程序中点击功能按钮会弹出选项菜单,点击可以实现具体功能. 二.实现思路: 1.创建选项菜单: onCreateOptionsMenu(); 2.设置菜单项可用 ...

  8. android 学习随笔二十九(自定义监听 )

    package com.itheima.momo.dialog; import com.itheima.momo.R; import android.app.AlertDialog; import a ...

  9. android 学习随笔二十六(动画:属性动画)

    属性动画,属性动画是真正改变对象的某个属性的值 * 补间动画,只是一个动画效果,组件其实还在原来的位置上,xy没有改变1.位移:* 第一个参数target指定要显示动画的组件* 第二个参数proper ...

随机推荐

  1. JS-004-判断元素显示状态

    在日常的 web 编程或 UI自动化脚本编写过程中,经常会遇到判断页面元素的显示状态,以对应的执行相应的操作.此文主要以 js 判断页面元素的存在状态为例,简单叙述一下 js 是如何判断元素的显示状态 ...

  2. iOS使用NSMutableAttributedString 实现富文本(不同颜色字体、下划线等)

    在iOS开发中,常常会有一段文字显示不同的颜色和字体,或者给某几个文字加删除线或下划线的需求.之前在网上找了一些资料,有的是重绘UILabel的textLayer,有的是用html5实现的,都比较麻烦 ...

  3. D3D9 浮点精度的问题

    最近在对我们的渲染引擎进行优化的时候,发现一个奇怪的现象,因为我们做了Pre-Z(把比较大的物体先绘制一遍,这个时候关闭颜色写,只开启深度测试和写入,目的是为了减少后面一些不可见像素的计算.),面在绘 ...

  4. The Struts dispatcher cannot be found. This is usually caused by using Strut

    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the assoc ...

  5. scp noneed passwd

    经常在不同linux机器之间互相scp拷文件,每次总是要输入密码才可行. 通过ssh-keygen生成公钥,在两台机器之间互相建立信任通道即可. 假设本地机器client,远程机器为server. 1 ...

  6. C++ note

    主要是为了学习c++的类和对象   内容摘自 c++概述 http://see.xidian.edu.cn/cpp/biancheng/cpp/rumen_1/   1,变量  ,C++中,我们可以在 ...

  7. Java基础之线程——使用执行器(UsingExecutors)

    控制台程序. 在这个版本的银行示例中,把借款和贷款事务创建为在不同线程中执行的任务,它们把事务提交给职员.创建事务的任务是Callable<>任务,因为它们需要返回已为每个账户创建的借款或 ...

  8. HTML_css样式表 样式属性 格式布局

    CSS(Cascading Style Sheet,叠层样式表),作用是美化HTML网页. /*注释区域*/此为注释语法 一.样式表 (一)样式表的分类 1.内联样式表 和HTML联合显示,控制精确, ...

  9. powershell 参数 [String]Service

    此种情况,去掉前面的[String] 在里面操作的时候就会认为是string,并可以自动操作了,否则限定为String类型时,就无法将输入的a,b当作String了, 或者需要添加'a,b'单引号来变 ...

  10. 关于VOID *在cl与gcc的不同(无意中发现)

    在windows中,void *是不确定类型,CL编译器无法确定其步长 但在linux中,void *默认步长是1