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);
}
}
}
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 学习随笔二十一(内容提供者 )的更多相关文章
- android 学习随笔二十八(应用小知识点小结 )
去掉标题栏的方法 第一种:也一般入门的时候经常使用的一种方法requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏注意这句一定要写在setConte ...
- android 学习随笔二十二(小结)
ADB进程 * adb指令 * adb install xxx.apk * adb uninstall 包名 * adb devices * adb start-server * adb kill-s ...
- android 项目学习随笔二十一(IM、语音识别、机器人、统计、扫描二维码、条形码)
语音识别:科大讯飞语音云 http://www.xfyun.cn/ 语音机器人模拟 public class TalkBean { public String text; public boolean ...
- android 学习随笔二十四(动画:帧动画)
帧动画,一张张图片不断的切换,形成动画效果 * 在drawable目录下定义xml文件,子节点为animation-list,在这里定义要显示的图片和每张图片的显示时长 * FrameAnimatio ...
- android 学习随笔二十三(动画:Fragment )
Fragment * 用途:在一个Activity里切换界面,切换界面时只切换Fragment里面的内容 * 在一个Activity中切换多个界面,每个界面就是一个Fragment* Fragmnen ...
- android 学习随笔二十(多媒体编程 )
1.图片处理 加载大图片 图片大小的计算 图片大小 = 图片的总像素 * 每个像素占用的大小 * 单色图:每个像素占用1/8个字节* 16色图:每个像素占用1/2个字节* 256色图:每个像素占用1个 ...
- Android学习(二十一)OptionsMenu选项菜单
一.OptionsMenu选项菜单 在应用程序中点击功能按钮会弹出选项菜单,点击可以实现具体功能. 二.实现思路: 1.创建选项菜单: onCreateOptionsMenu(); 2.设置菜单项可用 ...
- android 学习随笔二十九(自定义监听 )
package com.itheima.momo.dialog; import com.itheima.momo.R; import android.app.AlertDialog; import a ...
- android 学习随笔二十六(动画:属性动画)
属性动画,属性动画是真正改变对象的某个属性的值 * 补间动画,只是一个动画效果,组件其实还在原来的位置上,xy没有改变1.位移:* 第一个参数target指定要显示动画的组件* 第二个参数proper ...
随机推荐
- c#上传文件(一)使用 .net 控件上传文件
1.html代码: <body> <form id="form1" runat="server"> <div> <as ...
- 二代身份证阅读器(XZX)
问题一 解决方法: 通常我把所有的dll复制到system32文件夹,64位系统复制到sysWOW64文件夹,而且编译选项CPU要选择X86 问题二 解决方法: 图片路径默认是C:\,对C:\没有写的 ...
- 通过SessionID和用户名来保证同一个用户不能同时登录(单点登录)
可以通过SessionID和用户名来保证同一个用户不能同时登录的问题,下面程序模仿了QQ的登录,当登录后判断当前帐号是否已经登录,如果登录.则踢掉以前登录的用户. 1.通过Application全局变 ...
- App Store idfa被拒检查办法
最近应用因为这个问题被拒两次,理由如下: PLA 3.3.12We found your app uses the iOS Advertising Identifier but does not in ...
- CSS:CSS定位和浮动
CSS2.1规定了3种定位方案 1.Normal flow:普通流(相对定位 position relative.静态定位 position static) 普通流(normal flow,国内有人翻 ...
- Apache中压力测试工具ab的操作说明
1.压力测试工具ab(ApacheBench)的简单说明 1) 网站性能压力测试是性能调优过程中必不可少的一环.只有让服务器处在高压情况下才能真正体现出各种设置所暴露的问题.Apache中有个 ...
- python_字典
1. 字典的定义 字典由多个键及其对应的值构成(我们也把键/值对称为项).键是唯一的,值不唯一.键可以是数字.字符串甚至是元组. 2. 字典的创建 (1) phonebook = {"} 名 ...
- [PCL]1 PCL点云库安装
1.安装文件下载:官网,我还是比较喜欢别人编译好的安装包啊,哈哈. http://www.pointclouds.org/downloads/windows.html 2.傻瓜式安装(下面的依赖项都集 ...
- R12.2.0 buildStage 运行结果
# ./buildStage.sh Copyright (c) , Oracle Corporation Redwood Shores, California, USA Oracle E-Busine ...
- JAVA类加载机制详解
“代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是变成语言发展的一大步”,这句话出自<深入理解JAVA虚拟机>一书,后面关于jvm的系列文章主要都是参考这本书. JAV ...