基础学习总结(六)--getContentRolver()的应用、内容监听者ContentObserver
ContentResolver / getContentResolver()
外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activity当中通过getContentResolver()可以得到当前应用的 ContentResolver实例。ContentResolver提供的接口和ContentProvider中需要实现的接口对应,具体可以查看API Doc,不过可以发现ContentResolver里面的方法很多都是final或者static的。在实际应用中,我们很少实现ContentResolver抽象类,更多时候通过getContentResolver()从一个Activity或其它应用程序组件的实现里获取一个ContentResolver:
短信的uri地址:"content:\\sms\"
1 public class MainActivity extends Activity { 2 3 @Override 4 protected void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 setContentView(R.layout.activity_main); 7 8 } 9 10 /* 11 * 备份短信点击事件*/ 12 public void backupSms(View v){ 13 //1.查出所有短信 14 Uri uri = Uri.parse("content://sms/"); 15 //通过上下对象的getContentRolver方法获得ContentResolver实例 16 ContentResolver resolver = getContentResolver(); 17 //获得游标Cursor对象 18 Cursor cor= resolver.query(uri, new String[]{"_id","address","date","type","body"}, null, null, null); 19 if(cor!=null&&cor.getCount()>0){ 20 List<SmsInfo> list=new ArrayList<SmsInfo>(); 21 SmsInfo sms; 22 while(cor.moveToNext()){ 23 sms=new SmsInfo(); 24 sms.setsId(cor.getInt(0)); 25 sms.setAddress(cor.getString(1)); 26 sms.setDate(cor.getLong(2)); 27 sms.setType(cor.getInt(3)); 28 sms.setBody(cor.getString(4)); 29 list.add(sms); 30 } 31 cor.close(); 32 Log.w("MainActivity", "list中条数:"+String.valueOf(list.size())); 33 //2.存到本地 34 writeToLocal(list); 35 } 36 37 38 } 39 40 private void writeToLocal(List<SmsInfo> smslist){ 41 42 try { 43 XmlSerializer srlz= Xml.newSerializer();//得到序列化对象 44 /*动态获取sd卡地址 45 * String state=Environment.getExternalStorageState(); 46 if(Environment.MEDIA_MOUNTED.equals(state)){ 47 return; 48 } 49 File sdcardFile=Environment.getExternalStorageDirectory(); 50 File f=new File(sdcardFile,"sms.xml");*/ 51 FileOutputStream fos=new FileOutputStream("/mnt/sdcard/sms.xml"); 52 //将数据写入xml文本 53 srlz.setOutput(fos, "utf-8"); 54 55 srlz.startDocument("utf-8", true); 56 57 srlz.startTag(null, "SmsInfo"); 58 for (SmsInfo s : smslist) { 59 srlz.startTag(null, "sms"); 60 srlz.attribute(null, "id", String.valueOf(s.getsId())); 61 62 srlz.startTag(null, "address"); 63 srlz.text(s.getAddress()); 64 srlz.endTag(null, "address"); 65 66 srlz.startTag(null, "date"); 67 srlz.text(String.valueOf(s.getDate())); 68 srlz.endTag(null, "date"); 69 70 srlz.startTag(null, "type"); 71 srlz.text(String.valueOf(s.getType())); 72 srlz.endTag(null, "type"); 73 74 srlz.startTag(null, "body"); 75 srlz.text(s.getBody()); 76 srlz.endTag(null, "body"); 77 78 79 srlz.endTag(null, "sms"); 80 } 81 82 srlz.endTag(null, "SmsInfo"); 83 84 srlz.endDocument(); 85 86 Toast.makeText(this, "保存成功", 0).show(); 87 88 } catch (Exception e) { 89 Toast.makeText(this, "保存失败", 0).show(); 90 e.printStackTrace(); 91 92 } 93 } 94 }
添加外部读写权限与本地读取权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_SMS"/>
联系人的uri地址:
content://com.android.contacts/raw_contacts
content://com.android.contacts/data
1 public class MainActivity extends Activity { 2 3 private static final String TAG = "MainActivity"; 4 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 setContentView(R.layout.activity_main); 9 } 10 11 private void printCursor(Cursor cursor) { 12 if(cursor != null && cursor.getCount() > 0) { 13 14 while(cursor.moveToNext()) { 15 16 int columnCount = cursor.getColumnCount(); // 列的总数 17 18 for (int i = 0; i < columnCount; i++) { 19 String columnName = cursor.getColumnName(i); // 取对应i位置的列的名称 20 String columnValue = cursor.getString(i); // 取出对应i位置的列的值 21 22 Log.i(TAG, "当前是第" + cursor.getPosition() + "行: " + columnName + " = " + columnValue); 23 } 24 } 25 cursor.close(); 26 } 27 } 28 29 /** 30 * 查询联系人 31 * @param v 32 */ 33 public void queryContacts(View v) { 34 // 1. 去raw_contacts表中取所有联系人的_id 35 Uri uri = Uri.parse("content://com.android.contacts/raw_contacts"); 36 Uri dataUri = Uri.parse("content://com.android.contacts/data"); 37 38 Cursor cursor = getContentResolver().query(uri, new String[]{"_id"}, null, null, null); 39 // printCursor(cursor); 40 if(cursor != null && cursor.getCount() > 0) { 41 42 while(cursor.moveToNext()) { 43 int id = cursor.getInt(0); 44 // 2. 去data表中根据上面取到的_id查询对应id的数据. 45 46 //where语句 47 String selection = "raw_contact_id = ?"; 48 //where语句需要的值 49 String[] selectionArgs = {String.valueOf(id)}; 50 // 需要的字段 51 Cursor c = getContentResolver().query(dataUri, new String[]{"data1", "mimetype"}, 52 selection, selectionArgs, null); 53 if(c != null && c.getCount() > 0) { 54 55 while(c.moveToNext()) { 56 String mimetype = c.getString(1); // 当前取的是mimetype的值 57 String data1 = c.getString(0); // 当前取的是data1数据 58 59 if("vnd.android.cursor.item/phone_v2".equals(mimetype)) { 60 Log.i(TAG, "号码: " + data1); 61 } else if("vnd.android.cursor.item/name".equals(mimetype)) { 62 Log.i(TAG, "姓名: " + data1); 63 } else if("vnd.android.cursor.item/email_v2".equals(mimetype)) { 64 Log.i(TAG, "邮箱: " + data1); 65 } 66 } 67 c.close(); 68 } 69 } 70 cursor.close(); 71 } 72 73 } 74 75 public void addContacts(View v) { 76 Uri uri = Uri.parse("content://com.android.contacts/raw_contacts"); 77 Uri dataUri = Uri.parse("content://com.android.contacts/data"); 78 // 1. 在raw_contacts表中添加一个记录 79 80 // 取raw_contacts表中contact_id的值 81 Cursor cursor = getContentResolver().query(uri, new String[]{"contact_id"}, null, null, "contact_id desc limit 1"); 82 if(cursor != null && cursor.moveToFirst()) { 83 int contact_id = cursor.getInt(0); 84 contact_id ++; 85 cursor.close(); 86 87 ContentValues values = new ContentValues(); 88 values.put("contact_id", contact_id); 89 getContentResolver().insert(uri, values); 90 91 // 2. 根据上面添加记录的id, 取data表中添加三条数据 92 93 // 存号码 94 values = new ContentValues(); 95 values.put("mimetype", "vnd.android.cursor.item/phone_v2"); 96 values.put("data1", "10086"); 97 values.put("raw_contact_id", contact_id); 98 getContentResolver().insert(dataUri, values); 99 100 // 存姓名 101 values = new ContentValues(); 102 values.put("mimetype", "vnd.android.cursor.item/name"); 103 values.put("data1", "中国移动"); 104 values.put("raw_contact_id", contact_id); 105 getContentResolver().insert(dataUri, values); 106 107 // 存姓名 108 values = new ContentValues(); 109 values.put("mimetype", "vnd.android.cursor.item/email_v2"); 110 values.put("data1", "10086@kengni.com"); 111 values.put("raw_contact_id", contact_id); 112 getContentResolver().insert(dataUri, values); 113 } 114 115 } 116 }
添加联系人的读写sd卡权限
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
ContentObServer应用:
1 首先创建一个ContentObserver的子类,然后实现里面的onChange方法,监听的Uri中的数据发生变化的时候,会调用onchange方法。
2 注册ContentObserver。
1 public class MainActivity extends Activity { 2 3 @Override 4 protected void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 setContentView(R.layout.activity_main); 7 8 // 监听系统短信 9 10 ContentResolver resolver = getContentResolver(); 11 12 // 注册一个内容观察者观察短信数据库 13 resolver.registerContentObserver(Uri.parse("content://sms/"), true, new MyContentObserver(new Handler())); 14 } 15 16 /** 17 * 内容观察者 18 */ 19 class MyContentObserver extends ContentObserver { 20 21 private static final String TAG = "MyContentObserver"; 22 23 public MyContentObserver(Handler handler) { 24 super(handler); 25 } 26 27 /** 28 * 当被监听的内容发生改变时回调 29 */ 30 @Override 31 public void onChange(boolean selfChange) { 32 Log.i(TAG, "短信改变了"); 33 Uri uri = Uri.parse("content://sms/outbox"); // 发件箱的uri 34 35 // 查询发件箱的内容 36 Cursor cursor = getContentResolver().query(uri, new String[]{"address", "date", "body"}, null, null, null); 37 if(cursor != null && cursor.getCount() > 0) { 38 39 String address; 40 long date; 41 String body; 42 while(cursor.moveToNext()) { 43 address = cursor.getString(0); 44 date = cursor.getLong(1); 45 body = cursor.getString(2); 46 47 Log.i(TAG, "号码: " + address + ", 日期: " + date + ", 内容: " + body); 48 } 49 cursor.close(); 50 } 51 } 52 } 53 }
作者:大胖儿在努力
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。