Android学习笔记7:四大组件之ContentProvider

来源:互联网 发布:知乎立升净水器好不好 编辑:程序博客网 时间:2024/06/06 09:46

ContentProvider概览:
      我们自己应用的数据库只能给自己使用,无法提供给其他应用直接操作,于是便有了ContentProvider,但在实际开发中很少有应用需要编写自己的ContentProvider 把自己的数据库暴露给别人,一半都是用ContentProvider来访问紫铜应用的数据库,比如系统的短信和联系人。我们学习怎么写ContentProvider是要去了解它实现的原理,其实就是一个URI的匹配  比如android系统的短信应用源代码  里面写URIMatcher  就有content://sms/这个URI  那么我们就可以通过这个URI的匹配  去访问到系统的短信。


  下面就来看看怎么读取系统的短信, 监听系统的短信  读取系统的联系人  和添加修改系统的联系人:


1. 读取短信:


首先看看系统短信数据库的结构:


_id   address  date  body  type(1表示收件  2表示发件) 这几个列名比较常用


这段代码读到了所有 95555发来的短信:

sb = new StringBuilder();ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://sms/");Cursor cursor = resolver.query(uri, null, "address=?", new String[]{"95555"}, null);while(cursor.moveToNext()){String address = cursor.getString(cursor.getColumnIndexOrThrow("address"));String body = cursor.getString(cursor.getColumnIndexOrThrow("body"));String content = address+"---"+body+"\n";sb.append(content);}



2. 短信窃听器:


 谷歌在写ContentProvider的时候  其实注册了一个监听,当内容提供者的数据发生变化时候  我们通过内容观察者可以监听到:关键代码在第六行,我们为这个ContentResolver注册一个内容观察者ContentObserver:


3个参数的含义:
Uri   我们要监听的数据路径  在本例中我们监听所有的短信  所以与contentResolver的一样
Boolean  true:  我们的Uri只要是以contentResolver的Uri开头就行了  false: 必须和contentResolver的Uri一样
new myObserver: 继承ContentObserver  重写了i免得change方法,我们要做的事情:打印出最新的一条短信(注意是倒序排列  所以是moveToFirst())

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ContentResolver contentResolver = getContentResolver();Uri uri = Uri.parse("content://sms/");contentResolver.registerContentObserver(uri, true, new myObserver(new Handler()));}class myObserver extends ContentObserver{public myObserver(Handler handler) {super(handler);// TODO Auto-generated constructor stub}@Overridepublic void onChange(boolean selfChange) {// TODO Auto-generated method stubsuper.onChange(selfChange);Toast.makeText(MainActivity.this, "已经监听到一条短信", Toast.LENGTH_LONG).show();ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://sms/");Cursor cursor = resolver.query(uri, null, null, null, null);cursor.moveToFirst();String address = cursor.getString(cursor.getColumnIndex("address"));String body = cursor.getString(cursor.getColumnIndex("body"));System.out.println(address+"----"+body);}}}


3.联系人的应用

   系统的联系人与短信有不同的地方就是  数据库的存储不只是一张表,而是3张表:

第一张表是 raw_contacts : 用contact_id保存联系人的ID . Uri是:content://com.android.contacts/raw_contacts


第二张表是data: 用data1来存放数据,  mimetype_id存放数据(实际访问不能这个列名,应该用mimetype),raw_contact_id存放这个data对应的ID 。Uri是:content://com.android.contacts/data  看看这张表的结构:



第三张表是mimetype表: 来表示每种数据的类型:1 : EMAIL   5:phone    7:name


获得所有联系人的思路很简单: 先去查询raw_contacts表得到所有的ID  然后用得到的ID去查询data表格,在遍历循环中用mimetype来判断数据类型   来完成自己的业务!