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

  1. vnd.android.cursor.dir/ 多条数据
  1. vnd.android.cursor.item/ 单条数据
  1. package com.itheima.mycontentprovider.db;
  2.  
  3. import java.io.Serializable;
  4.  
  5. import android.content.Context;
  6. import android.database.sqlite.SQLiteDatabase;
  7. import android.database.sqlite.SQLiteDatabase.CursorFactory;
  8. import android.database.sqlite.SQLiteOpenHelper;
  9. import android.os.Parcelable;
  10.  
  11. public class MyOpenHelper extends SQLiteOpenHelper {
  12.  
  13. public MyOpenHelper(Context context) {
  14. super(context, "people.db", null, 2);
  15. }
  16.  
  17. @Override
  18. public void onCreate(SQLiteDatabase db) {
  19. db.execSQL("create table person(_id integer primary key autoincrement, name char(10), phone char(20), money integer(10))");
  20.  
  21. }
  22.  
  23. @Override
  24. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  25. db.execSQL("create table handsome(_id integer primary key autoincrement, name char(10), phone char(20))");
  26. }
  27.  
  28. }

定义数据库

  1. package com.itheima.mycontentprovider;
  2.  
  3. import com.itheima.mycontentprovider.db.MyOpenHelper;
  4.  
  5. import android.content.ContentProvider;
  6. import android.content.ContentUris;
  7. import android.content.ContentValues;
  8. import android.content.UriMatcher;
  9. import android.database.Cursor;
  10. import android.database.sqlite.SQLiteDatabase;
  11. import android.net.Uri;
  12.  
  13. public class PersonProvider extends ContentProvider {
  14.  
  15. private SQLiteDatabase db;
  16. //创建uri匹配器
  17. UriMatcher um = new UriMatcher(UriMatcher.NO_MATCH);
  18. {
  19. //添加匹配规则
  20. //arg0:主机名
  21. //arg1:路径
  22. //arg2:匹配码
  23. um.addURI("com.itheima.people", "person", 1);//content://com.itheima.people/person
  24. um.addURI("com.itheima.people", "handsome", 2);//content://com.itheima.people/handsome
  25. um.addURI("com.itheima.people", "person/#", 3);//content://com.itheima.people/person/10
  26. }
  27.  
  28. //内容提供者创建时调用
  29. @Override
  30. public boolean onCreate() {
  31. MyOpenHelper oh = new MyOpenHelper(getContext());
  32. db = oh.getWritableDatabase();
  33. return false;
  34. }
  35.  
  36. //values:其他应用要插的数据
  37. @Override
  38. public Uri insert(Uri uri, ContentValues values) {
  39. if(um.match(uri) == 1){
  40. db.insert("person", null, values);
  41.  
  42. //数据库改变了,内容提供者发出通知
  43. //arg0:通知发到哪个uri上,注册在这个uri上的内容观察者都可以收到通知
  44. getContext().getContentResolver().notifyChange(uri, null);
  45. }
  46. else if(um.match(uri) == 2){
  47. db.insert("handsome", null, values);
  48.  
  49. getContext().getContentResolver().notifyChange(uri, null);
  50. }
  51. else{
  52. throw new IllegalArgumentException("uri传错啦傻逼");
  53. }
  54. return uri;
  55. }
  56.  
  57. @Override
  58. public int delete(Uri uri, String selection, String[] selectionArgs) {
  59. int i = 0;
  60. if(um.match(uri) == 1){
  61. i = db.delete("person", selection, selectionArgs);
  62. }
  63. else if(um.match(uri) == 2){
  64. i = db.delete("handsome", selection, selectionArgs);
  65. }
  66. else{
  67. throw new IllegalArgumentException("uri又传错啦傻逼");
  68. }
  69.  
  70. return i;
  71. }
  72.  
  73. @Override
  74. public int update(Uri uri, ContentValues values, String selection,
  75. String[] selectionArgs) {
  76. int i = db.update("person", values, selection, selectionArgs);
  77. return i;
  78. }
  79.  
  80. @Override
  81. public Cursor query(Uri uri, String[] projection, String selection,
  82. String[] selectionArgs, String sortOrder) {
  83. Cursor cursor = null;
  84. if(um.match(uri) == 1){
  85. cursor = db.query("person", projection, selection, selectionArgs, null, null, sortOrder, null);
  86. }
  87. else if(um.match(uri) == 2){
  88. cursor = db.query("handsome", projection, selection, selectionArgs, null, null, sortOrder, null);
  89. }
  90. else if(um.match(uri) == 3){
  91. //取出uri末尾携带的数字
  92. long id = ContentUris.parseId(uri);
  93. cursor = db.query("person", projection, "_id = ?", new String[]{"" + id}, null, null, sortOrder, null);
  94. }
  95. return cursor;
  96. }
  97.  
  98. //返回通过指定uri获取的数据的mimetype
  99. @Override
  100. public String getType(Uri uri) {
  101. if(um.match(uri) == 1){
  102. return "vnd.android.cursor.dir/person";
  103. }
  104. else if(um.match(uri) == 2){
  105. return "vnd.android.cursor.dir/handsome";
  106. }
  107. else if(um.match(uri) == 3){
  108. return "vnd.android.cursor.item/person";
  109. }
  110. return null;
  111. }
  112.  
  113. }

内容提供者

  1. package com.itheima.mycontentprovider;
  2.  
  3. import android.os.Bundle;
  4. import android.app.Activity;
  5. import android.view.Menu;
  6.  
  7. public class MainActivity extends Activity {
  8.  
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.activity_main);
  13.  
  14. }
  15.  
  16. @Override
  17. public boolean onCreateOptionsMenu(Menu menu) {
  18. // Inflate the menu; this adds items to the action bar if it is present.
  19. getMenuInflater().inflate(R.menu.main, menu);
  20. return true;
  21. }
  22.  
  23. }

MainActivity

  1. package com.itheima.mycontentprovider;
  2.  
  3. import com.itheima.mycontentprovider.db.MyOpenHelper;
  4.  
  5. import android.test.AndroidTestCase;
  6.  
  7. public class Test extends AndroidTestCase {
  8.  
  9. public void test(){
  10. MyOpenHelper oh = new MyOpenHelper(getContext());
  11. oh.getWritableDatabase();
  12. }
  13. }

test

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.itheima.mycontentprovider"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6.  
  7. <uses-sdk
  8. android:minSdkVersion="8"
  9. android:targetSdkVersion="17" />
  10. <instrumentation android:name="android.test.InstrumentationTestRunner"
  11. android:targetPackage="com.itheima.mycontentprovider"></instrumentation>
  12. <application
  13. android:allowBackup="true"
  14. android:icon="@drawable/ic_launcher"
  15. android:label="@string/app_name"
  16. android:theme="@style/AppTheme" >
  17.  
  18. <uses-library android:name="android.test.runner"/>
  19. <activity
  20. android:name="com.itheima.mycontentprovider.MainActivity"
  21. android:label="@string/app_name" >
  22. <intent-filter>
  23. <action android:name="android.intent.action.MAIN" />
  24.  
  25. <category android:name="android.intent.category.LAUNCHER" />
  26. </intent-filter>
  27. </activity>
  28.  
  29. <provider
  30. android:name="com.itheima.mycontentprovider.PersonProvider"
  31. android:authorities="com.itheima.people"
  32.  
  33. android:exported="true"
  34. >
  35. </provider>
  36. </application>
  37.  
  38. </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);
}

  1. package com.itheima.other;
  2.  
  3. import android.net.Uri;
  4. import android.os.Bundle;
  5. import android.app.Activity;
  6. import android.content.ContentResolver;
  7. import android.content.ContentValues;
  8. import android.database.Cursor;
  9. import android.view.Menu;
  10. import android.view.View;
  11.  
  12. public class MainActivity extends Activity {
  13.  
  14. @Override
  15. protected void onCreate(Bundle savedInstanceState) {
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.activity_main);
  18. }
  19.  
  20. public void insert(View v){
  21. //通过内容提供者把数据插入01数据库
  22. //1.获取contentResolver
  23. ContentResolver resolver = getContentResolver();
  24. //2.访问内容提供者,插入数据
  25. ContentValues values = new ContentValues();
  26. values.put("name", "流氓润");
  27. values.put("phone", 138992);
  28. values.put("money", 14000);
  29. //arg0:指定内容提供者的主机名
  30. resolver.insert(Uri.parse("content://com.itheima.people/person"), values);
  31.  
  32. values.clear();
  33. values.put("name", "侃哥");
  34. values.put("phone", 15999);
  35. //arg0:指定内容提供者的主机名
  36. resolver.insert(Uri.parse("content://com.itheima.people/handsome"), values);
  37. }
  38.  
  39. public void delete(View v){
  40. ContentResolver resolver = getContentResolver();
  41. int i = resolver.delete(Uri.parse("content://com.itheima.people"), "name = ?", new String[]{"凤姐"});
  42. System.out.println(i);
  43. }
  44.  
  45. public void update(View v){
  46. ContentResolver resolver = getContentResolver();
  47. ContentValues values = new ContentValues();
  48. values.put("money", 16001);
  49. int i = resolver.update(Uri.parse("content://com.itheima.people"), values, "name = ?", new String[]{"春晓"});
  50. System.out.println(i);
  51. }
  52.  
  53. public void query(View v){
  54. ContentResolver resolver = getContentResolver();
  55. Cursor cursor = resolver.query(Uri.parse("content://com.itheima.people/person"), null, null, null, null);
  56. while(cursor.moveToNext()){
  57. String name = cursor.getString(1);
  58. String phone = cursor.getString(2);
  59. String money = cursor.getString(3);
  60. System.out.println(name + ";" + phone + ";" + money);
  61. }
  62. }
  63. public void queryOne(View v){
  64. ContentResolver resolver = getContentResolver();
  65. Cursor cursor = resolver.query(Uri.parse("content://com.itheima.people/person/4"), null, null, null, null);
  66. if(cursor.moveToNext()){
  67. String name = cursor.getString(1);
  68. String phone = cursor.getString(2);
  69. String money = cursor.getString(3);
  70. System.out.println(name + ";" + phone + ";" + money);
  71. }
  72. }
  73. }

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);
}

  1. package com.itheima.getsms;
  2.  
  3. import android.net.Uri;
  4. import android.os.Bundle;
  5. import android.app.Activity;
  6. import android.content.ContentResolver;
  7. import android.database.Cursor;
  8. import android.view.Menu;
  9. import android.view.View;
  10.  
  11. public class MainActivity extends Activity {
  12.  
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17. }
  18.  
  19. public void click1(View v){
  20. ContentResolver resolver = getContentResolver();
  21. Cursor cursor = resolver.query(Uri.parse("content://sms"), new String[]{"address", "date", "type", "body"}, null, null, null);
  22. while(cursor.moveToNext()){
  23. String address = cursor.getString(0);
  24. long date = cursor.getLong(1);
  25. int type = cursor.getInt(2);
  26. String body = cursor.getString(3);
  27.  
  28. System.out.println(address + ";" + date + ";" + type + ";" + body);
  29. }
  30. }
  31.  
  32. }

MainActivity

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.itheima.getsms"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6.  
  7. <uses-sdk
  8. android:minSdkVersion="8"
  9. android:targetSdkVersion="17" />
  10. <uses-permission android:name="android.permission.READ_SMS"/>
  11.  
  12. <application
  13. android:allowBackup="true"
  14. android:icon="@drawable/ic_launcher"
  15. android:label="@string/app_name"
  16. android:theme="@style/AppTheme" >
  17. <activity
  18. android:name="com.itheima.getsms.MainActivity"
  19. android:label="@string/app_name" >
  20. <intent-filter>
  21. <action android:name="android.intent.action.MAIN" />
  22.  
  23. <category android:name="android.intent.category.LAUNCHER" />
  24. </intent-filter>
  25. </activity>
  26. </application>
  27.  
  28. </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);
* 插入查询系统短信需要注册权限

  1. package com.itheima.insertsms;
  2.  
  3. import android.net.Uri;
  4. import android.os.Bundle;
  5. import android.app.Activity;
  6. import android.content.ContentResolver;
  7. import android.content.ContentValues;
  8. import android.view.Menu;
  9. import android.view.View;
  10.  
  11. public class MainActivity extends Activity {
  12.  
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17. }
  18.  
  19. public void click(View v){
  20. Thread t = new Thread(){
  21. @Override
  22. public void run() {
  23. try {
  24. sleep(7000);
  25. } catch (InterruptedException e) {
  26. // TODO Auto-generated catch block
  27. e.printStackTrace();
  28. }
  29. ContentResolver resolver = getContentResolver();
  30. ContentValues values = new ContentValues();
  31. values.put("address", 95555);
  32. values.put("date", System.currentTimeMillis());
  33. values.put("type", 1);
  34. values.put("body", "您尾号为XXXX的招行储蓄卡收到转账1,000,000");
  35. resolver.insert(Uri.parse("content://sms"), values);
  36. }
  37. };
  38. t.start();
  39.  
  40. }
  41.  
  42. }

MainActivity

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.itheima.insertsms"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6.  
  7. <uses-permission android:name="android.permission.WRITE_SMS"/>
  8. <uses-permission android:name="android.permission.READ_SMS"/>
  9.  
  10. <uses-sdk
  11. android:minSdkVersion="8"
  12. android:targetSdkVersion="17" />
  13. <application
  14. android:allowBackup="true"
  15. android:icon="@drawable/ic_launcher"
  16. android:label="@string/app_name"
  17. android:theme="@style/AppTheme" >
  18. <activity
  19. android:name="com.itheima.insertsms.MainActivity"
  20. android:label="@string/app_name" >
  21. <intent-filter>
  22. <action android:name="android.intent.action.MAIN" />
  23.  
  24. <category android:name="android.intent.category.LAUNCHER" />
  25. </intent-filter>
  26. </activity>
  27. </application>
  28.  
  29. </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);
}
}

  1. package com.itheima.getcontacts.domain;
  2.  
  3. public class Contact {
  4.  
  5. private String name;
  6. private String phone;
  7. private String email;
  8. public String getName() {
  9. return name;
  10. }
  11. public void setName(String name) {
  12. this.name = name;
  13. }
  14. public String getPhone() {
  15. return phone;
  16. }
  17. public void setPhone(String phone) {
  18. this.phone = phone;
  19. }
  20. public String getEmail() {
  21. return email;
  22. }
  23. public void setEmail(String email) {
  24. this.email = email;
  25. }
  26. @Override
  27. public String toString() {
  28. return "Contact [name=" + name + ", phone=" + phone + ", email="
  29. + email + "]";
  30. }
  31.  
  32. }

Contact

  1. package com.itheima.getcontacts;
  2.  
  3. import com.itheima.getcontacts.domain.Contact;
  4.  
  5. import android.net.Uri;
  6. import android.os.Bundle;
  7. import android.app.Activity;
  8. import android.content.ContentResolver;
  9. import android.database.Cursor;
  10. import android.view.Menu;
  11. import android.view.View;
  12.  
  13. public class MainActivity extends Activity {
  14.  
  15. @Override
  16. protected void onCreate(Bundle savedInstanceState) {
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.activity_main);
  19. }
  20.  
  21. public void click(View v){
  22. ContentResolver resolver = getContentResolver();
  23.  
  24. Cursor cursor = resolver.query(Uri.parse("content://com.android.contacts/raw_contacts"), new String[]{"contact_id"},
  25. null, null, null);
  26. while(cursor.moveToNext()){
  27. String contactId = cursor.getString(0);
  28. //使用联系人id作为where条件去查询data表,查询出属于该联系人的信息
  29. Cursor cursorData = resolver.query(Uri.parse("content://com.android.contacts/data"), new String[]{"data1", "mimetype"}, "raw_contact_id = ?",
  30. new String[]{contactId}, null);
  31. // Cursor cursorData = resolver.query(Uri.parse("content://com.android.contacts/data"), null, "raw_contact_id = ?",
  32. // new String[]{contactId}, null);
  33.  
  34. // int count = cursorData.getColumnCount();
  35. // for (int i = 0; i < count; i++) {
  36. // System.out.println(cursorData.getColumnName(i));
  37. // }
  38.  
  39. Contact contact = new Contact();
  40. while(cursorData.moveToNext()){
  41. String data1 = cursorData.getString(0);
  42. String mimetype = cursorData.getString(1);
  43. // System.out.println(data1 + ";" + mimetype);
  44. if("vnd.android.cursor.item/email_v2".equals(mimetype)){
  45. contact.setEmail(data1);
  46. }
  47. else if("vnd.android.cursor.item/phone_v2".equals(mimetype)){
  48. contact.setPhone(data1);
  49. }
  50. else if("vnd.android.cursor.item/name".equals(mimetype)){
  51. contact.setName(data1);
  52. }
  53. }
  54. System.out.println(contact.toString());
  55. }
  56. }
  57.  
  58. }

MainActivity

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.itheima.getcontacts"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6.  
  7. <uses-sdk
  8. android:minSdkVersion="8"
  9. android:targetSdkVersion="17" />
  10. <uses-permission android:name="android.permission.READ_CONTACTS"/>
  11.  
  12. <application
  13. android:allowBackup="true"
  14. android:icon="@drawable/ic_launcher"
  15. android:label="@string/app_name"
  16. android:theme="@style/AppTheme" >
  17. <activity
  18. android:name="com.itheima.getcontacts.MainActivity"
  19. android:label="@string/app_name" >
  20. <intent-filter>
  21. <action android:name="android.intent.action.MAIN" />
  22.  
  23. <category android:name="android.intent.category.LAUNCHER" />
  24. </intent-filter>
  25. </activity>
  26. </application>
  27.  
  28. </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);

  1. package com.itheima.insertcontact;
  2.  
  3. import android.net.Uri;
  4. import android.os.Bundle;
  5. import android.app.Activity;
  6. import android.content.ContentResolver;
  7. import android.content.ContentValues;
  8. import android.database.Cursor;
  9. import android.view.Menu;
  10. import android.view.View;
  11.  
  12. public class MainActivity extends Activity {
  13.  
  14. @Override
  15. protected void onCreate(Bundle savedInstanceState) {
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.activity_main);
  18. }
  19.  
  20. public void click(View v){
  21. ContentResolver resolver = getContentResolver();
  22. //先查询最新的联系人的主键,主键+1,就是要插入的联系人id
  23. Cursor cursor = resolver.query(Uri.parse("content://com.android.contacts/raw_contacts"), new String[]{"_id"}, null, null, null);
  24. int _id = 0;
  25. if(cursor.moveToLast()){
  26. _id = cursor.getInt(0);
  27. }
  28. _id++;
  29.  
  30. //插入联系人id
  31. ContentValues values = new ContentValues();
  32. values.put("contact_id", _id);
  33. resolver.insert(Uri.parse("content://com.android.contacts/raw_contacts"), values);
  34.  
  35. //把具体联系人信息插入data表
  36. values.clear();
  37. values.put("data1", "剪刀手坤哥");
  38. values.put("mimetype", "vnd.android.cursor.item/name");
  39. values.put("raw_contact_id", _id);
  40. resolver.insert(Uri.parse("content://com.android.contacts/data"), values);
  41.  
  42. values.clear();
  43. values.put("data1", "8899667");
  44. values.put("mimetype", "vnd.android.cursor.item/phone_v2");
  45. values.put("raw_contact_id", _id);
  46. resolver.insert(Uri.parse("content://com.android.contacts/data"), values);
  47. }
  48.  
  49. }

MainActivity

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.itheima.insertcontact"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6.  
  7. <uses-sdk
  8. android:minSdkVersion="8"
  9. android:targetSdkVersion="17" />
  10. <uses-permission android:name="android.permission.READ_CONTACTS"/>
  11. <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
  12.  
  13. <application
  14. android:allowBackup="true"
  15. android:icon="@drawable/ic_launcher"
  16. android:label="@string/app_name"
  17. android:theme="@style/AppTheme" >
  18. <activity
  19. android:name="com.itheima.insertcontact.MainActivity"
  20. android:label="@string/app_name" >
  21. <intent-filter>
  22. <action android:name="android.intent.action.MAIN" />
  23.  
  24. <category android:name="android.intent.category.LAUNCHER" />
  25. </intent-filter>
  26. </activity>
  27. </application>
  28.  
  29. </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) {

}

}

  1. package com.itheima.contentobserver;
  2.  
  3. import android.net.Uri;
  4. import android.os.Bundle;
  5. import android.os.Handler;
  6. import android.app.Activity;
  7. import android.content.ContentResolver;
  8. import android.database.ContentObserver;
  9. import android.view.Menu;
  10.  
  11. public class MainActivity extends Activity {
  12.  
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17.  
  18. //注册内容观察者,观察者就生效了,可以接受内容提供者发出的通知
  19. ContentResolver resolver = getContentResolver();
  20. //arg0:指定接收哪个内容提供者发出的通知
  21. resolver.registerContentObserver(Uri.parse("content://sms"),
  22. true, //如果为true,以这个uri作为开头的uri上的数据改变了,该内容观察者都会收到通知
  23. new MyObserver(new Handler()));
  24. }
  25.  
  26. class MyObserver extends ContentObserver{
  27.  
  28. public MyObserver(Handler handler) {
  29. super(handler);
  30. // TODO Auto-generated constructor stub
  31. }
  32.  
  33. @Override
  34. public void onChange(boolean selfChange) {
  35. // TODO Auto-generated method stub
  36. super.onChange(selfChange);
  37. System.out.println("短信数据库改变");
  38. }
  39. }
  40.  
  41. }
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.itheima.contentobserver"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6.  
  7. <uses-sdk
  8. android:minSdkVersion="8"
  9. android:targetSdkVersion="17" />
  10.  
  11. <application
  12. android:allowBackup="true"
  13. android:icon="@drawable/ic_launcher"
  14. android:label="@string/app_name"
  15. android:theme="@style/AppTheme" >
  16. <activity
  17. android:name="com.itheima.contentobserver.MainActivity"
  18. android:label="@string/app_name" >
  19. <intent-filter>
  20. <action android:name="android.intent.action.MAIN" />
  21.  
  22. <category android:name="android.intent.category.LAUNCHER" />
  23. </intent-filter>
  24. </activity>
  25. </application>
  26.  
  27. </manifest>

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

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

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

  1. package com.itheima.receivenotify;
  2.  
  3. import android.net.Uri;
  4. import android.os.Bundle;
  5. import android.os.Handler;
  6. import android.app.Activity;
  7. import android.database.ContentObserver;
  8. import android.view.Menu;
  9.  
  10. public class MainActivity extends Activity {
  11.  
  12. @Override
  13. protected void onCreate(Bundle savedInstanceState) {
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.activity_main);
  16.  
  17. //注册内容观察者接收01发送的通知
  18. getContentResolver().registerContentObserver(Uri.parse("content://com.itheima.people"),
  19. true, new ContentObserver(new Handler()) {
  20. @Override
  21. public void onChange(boolean selfChange) {
  22. // TODO Auto-generated method stub
  23. super.onChange(selfChange);
  24. System.out.println("01数据库改变");
  25. }
  26. });
  27. }
  28.  
  29. }
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.itheima.receivenotify"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6.  
  7. <uses-sdk
  8. android:minSdkVersion="8"
  9. android:targetSdkVersion="17" />
  10.  
  11. <application
  12. android:allowBackup="true"
  13. android:icon="@drawable/ic_launcher"
  14. android:label="@string/app_name"
  15. android:theme="@style/AppTheme" >
  16. <activity
  17. android:name="com.itheima.receivenotify.MainActivity"
  18. android:label="@string/app_name" >
  19. <intent-filter>
  20. <action android:name="android.intent.action.MAIN" />
  21.  
  22. <category android:name="android.intent.category.LAUNCHER" />
  23. </intent-filter>
  24. </activity>
  25. </application>
  26.  
  27. </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. 《Maven实战》阅读笔记

    java -versionmvn -vmvn help:system m2eclipse maven->install MAVEN_OPTS: -Xms128m -Xmx512mmvn clea ...

  2. 《JAVA NIO》第二章缓冲区

    1.缓冲区的构成 2.缓冲区的类图 3.ByteBuffer ByteBuffer是直接和Channel打交道的,准确的是直接字节缓冲. 问题:直接字节缓冲区和内存映射的关系 4.ByteOrder ...

  3. 详解Spring事件驱动模型

    转载自:http://jinnianshilongnian.iteye.com/blog/1902886#comments 事件驱动模型简介 事件驱动模型也就是我们常说的观察者,或者发布-订阅模型:理 ...

  4. 当标签上写了runat="server" 后,<%%>就会无效

    当标签上写了runat="server" 后,<%%>就会无效 //这是错误的写法 <input type="hidden" runat=&q ...

  5. [ROS] slam_gmapping

    slam_gmapping节点 1)slam_gmapping 节点在sensor_msgs/LaserScan消息内获取数据并建立地图 map(nav_msgs/OccupancyGrid).该地图 ...

  6. iOS支付后默认关注公众号

    1.这个是微信内部的功能,不对外公开,需要商务洽谈.跟技术无关. 2.同时金额少于1块的也不会有提示关注显示. 3.关注过的不会默认再次关注,但是仍然有选项可以选择.

  7. checkbox判断选中

    $("input[type='checkbox']").is(':checked')

  8. linux文件编码

    linux下新建一个文件,或采用fopen新建,那么文件的编码是什么? 怎么查看文件编码格式: 查看文件编码file命令file ip.txt ip.txt: UTF-8 Unicode text, ...

  9. C++Primer 第三章

    //1.位于头文件中的代码一般不应该使用using声明.这是因为头文件的内容会拷贝到所有引用它的文件中,可能会产生始料未及的命名空间冲突. // 三种使用命名空间中的名字的方法 using names ...

  10. For循环输出九九乘法表

    题:使用For循环输出九九乘法表 解析: 1*1=1 1*2=2  2*2=4 1*3=3  2*3=6  3*3=9 .... 1*9=9  ........ .....9*9=81 可以看做j*i ...