內容提供者 應用的資料庫是不允許其他應用訪問的 內容提供者的作用就是讓別的應用訪問到你的資料庫 自定義內容提供者,繼承ContentProvider類,重寫增刪改查方法,在方法中寫增刪改查資料庫的代碼,舉例增方法 @Override public Uri insert(Uri uri, Conten
內容提供者
- 應用的資料庫是不允許其他應用訪問的
- 內容提供者的作用就是讓別的應用訪問到你的資料庫
-
自定義內容提供者,繼承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>
-
創建一個其他應用,訪問自定義的內容提供者,實現對資料庫的插入操作
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); }
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); }
-
插入系統簡訊
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);
- 插入查詢系統簡訊需要註冊許可權
聯繫人資料庫
- 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); } }
插入聯繫人
- 先查詢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);
-
內容觀察者
-
當資料庫數據改變時,內容提供者會發出通知,在內容提供者的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) { } }
-
在內容提供者中發通知的代碼
ContentResolver cr = getContext().getContentResolver(); //發出通知,所有註冊在這個uri上的內容觀察者都可以收到通知 cr.notifyChange(uri, null);