內容提供者 參考:
Android四大組件之內容提供者--ContentProvider - java小兵 - CSDN博客 http://blog.csdn.net/wodewutai17quiet/article/details/46670597
Android四大組件之內容提供者--ContentProvider ?
B程序通過內容提供者來訪問聯系人程序的數據。
?
1,什么是ContentProvider ?
? ? ? ? ContentProvider將應用中的數據對其它應用進行共享, 提供增刪改查的方法 ?
? ? ? ? ContentProvider統一了數據的訪問方式,不必針對不同數據類型采取不同的訪問策略 ?
? ? ? ? ContentProvider將數據封裝,只暴露出我們希望提供給其它程序的數據 ?
? ? ? ? ContentProvider中可以注冊觀察者, 監聽數據的變化 ??
2,怎么創建 ?
? ? ? ? 2.1定義類繼承ContentProvider, 實現抽象方法,抽象方法中對數據庫操作的增刪改查都有。 ?
? ? ? ? 2.2在清單文件中注冊:在清單文件的<application>節點下進行配置<provider>標簽,標簽中需要指定name和authorities屬性 ?
? ? ? ? ? ? name:完整的類名。 可以省略包名(manifest節點的package值),注意:省略后的類名是以"."開頭的。 ?
? ? ? ? ? ? authorities:主機 ,是訪問Provider時的路徑,要唯一 ?
?
B程序需要通過com.baidu這個url來實現訪問修改讀取聯系人程序。
完整類名就是繼承ContentProvider類的那個類的完整類名。
這樣配置也是告訴計算機,我這個類是內容提供者,后面要被別人訪問,并且可以通過com.baidu這個主機訪問我。
我們在B程序中通過內容解析者和主機名訪問聯系人程序。
?
3,在手機上注冊 將應用安裝到手機上即可, 不用運行程序 4,其它應用怎么訪問 外部應用使用ContentResolver 類對ContentProvider中的數據進行訪問(CRUD操作) 獲取解析器ContentResolver ContentResolver resolver = Context.getContentResolver(); 通過resolver.insert(), delete(), update(), query()方法訪問Uri關聯的ContentProvider
?
?
5,Uri的處理 URI代表要操作的數據,由scheme、authorites、path三部分組成 eg: content://com.jxn.provider/person scheme | authorites | path 1,schema:表明要訪問ContentProvider。固定為:"content://" 2,Authority(主機名或授權): 定義了是哪個ContentProvider提供這些數據。 3,path:路徑,可根據業務邏輯自定義 。eg: person、person/insert、person/insert/10等等 4,ID:通常定義URI時使用"#"號占位符代替, 使用時替換成對應的數字 "content://com.jxn.provider/person/#" #表示數據id(#代表任意數字) "content://com.jxn.provider/person/*" *來匹配任意文本 Android系統提供了兩個用于操作Uri的工具類:UriMatcher 和 ContentUris 1,UriMatcher類用于匹配Uri ,用法如下: 第一步:把你需要匹配的Uri路徑全部給注冊上,如下: //常量UriMatcher.NO_MATCH表示不匹配任何路徑的返回碼 UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); //如果match()方法匹配content://com.jxn.provider.personprovider/person路徑,返回匹配碼為1 matcher.addURI("com.jxn.provider.personprovider", "person", 1);//添加需要匹配uri,如果匹配就會返回匹配碼 //如果match()方法匹配content://com.jxn.provider.personprovider/person/230路徑,返回匹配碼為2 matcher.addURI("com.jxn.provider.personprovider", "person/#", 2);//#號為通配符 第二步:使用matcher.match(uri)方法對輸入的Uri進行匹配,如果匹配成功就返回匹配碼 switch (matcher.match(Uri.parse("content://com.jxn.provider.personprovider/person/10"))) { case 1 // 相應的業務操作 break; case 2 // 相應的業務操作 break; default: // 相應的業務操作 break; } 2,ContentUris類用于為路徑加上ID和獲取路徑的ID 給Uri加上id: ContentUris.withAppendedId(uri, id) 獲取id: ContentUris.parseId(uri)
?
?
6,監聽內容提供者數據變化?
?????
??????? 1,如果ContentProvider的訪問者需要知道ContentProvider中的數據發生了變化,可以在ContentProvider 發生數據變化時調用getContentResolver().notifyChange(uri, null)來通知注冊在此URI上的訪問者,例如:?
??????????? public class PersonContentProvider extends ContentProvider {?
??????????????? public Uri insert(Uri uri, ContentValues values) {?
??????????????????? db.insert("person", "personid", values);?
??????????????????? // 注:如果沒有調用notifyChange()方法,即使其它應用注冊了ContentObserver,也不會知道ContentProvider中的數據的變化?
??????????????????? getContext().getContentResolver().notifyChange(uri, null);?
??????????????? }?
??????????? }?
?????????????
??????? 2,如果ContentProvider的訪問者需要得到數據變化通知,必須使用ContentObserver對數據(用uri描述)進行監聽,當監聽到數據變化通知時,系統就會調用ContentObserver的onChange()方法:?
??????????? getContentResolver().registerContentObserver(Uri.parse("content://com.jxn.providers.personprovider/person"),true, new PersonObserver(new Handler()));?
??????????? public class PersonObserver extends ContentObserver{?
??????????????? public PersonObserver(Handler handler) {?
??????????????????? super(handler);?
??????????????? }?
??????????????? public void onChange(boolean selfChange) {?
??????????????????? //此處可以進行相應的業務處理?
??????????????? }?
??????????? }??
?
7,補充?
??????? getType()方法:主要用于匹配數據類型,返回當前Uri所代表數據的MIME類型。?
??????????? 如果返回數據是單條數據:vnd.android.cursor.item??
??????????? 如果返回數據是多條數據:vnd.android.cursor.dir??
?
?
案例:B應用通過A應用提供的ContentProvider訪問A應用中的數據?? ?? ????//?提供ContentProvider的A應用中定義的SQLiteProvider?? ????public?class?SQLiteProvider?extends?ContentProvider?{?? ?? ????????//?Uri匹配器,?用來匹配傳入的Uri?? ????????private?static?final?UriMatcher?matcher?=?new?UriMatcher(UriMatcher.NO_MATCH);?? ?????????? ????????private?static?final?int?PERSON?=?1;?? ?????????? ????????//?DBOpenHelper?extends?SQLiteOpenHelper?? ????????private?DBOpenHelper?helper;?? ?? ????????static?{?? ????????????//?設置一個Uri,?如果匹配到person,?返回1?? ????????????matcher.addURI("com.jxn.sqlite.provider",?"person",?PERSON);?? ????????}?? ?????????? ?? ????????//?其它應用第一次訪問時(此時會創建ContentProvider)執行?? ????????//?第一次啟動時執行,?然后會長期駐留在后臺,?除非被殺死,?否則不會再執行?? ????????@Override?? ????????public?boolean?onCreate()?{?? ????????????helper?=?new?DBOpenHelper(getContext());?? ????????????return?true;?? ????????}?? ?? ????????//?外部應用使用此方法查詢數據?? ????????@Override?? ????????public?Cursor?query(Uri?uri,?String[]?projection,?String?selection,?String[]?selectionArgs,?String?sortOrder)?{?? ????????????SQLiteDatabase?db?=?helper.getReadableDatabase();?? ?????????????? ????????????//?用匹配器匹配傳入的uri?? ????????????switch?(matcher.match(uri))?{?? ????????????????case?PERSON:?? ????????????????????return?db.query("person",?projection,?selection,?selectionArgs,?null,?null,?sortOrder);?????//?執行查詢?? ????????????????default:?? ????????????????????throw?new?RuntimeException("Uri不能識別:?"?+?uri);?? ????????????}?? ????????}?? ?? ????????//?外部應用使用此方法添加數據?? ????????@Override?? ????????public?Uri?insert(Uri?uri,?ContentValues?values)?{?? ????????????SQLiteDatabase?db?=?helper.getWritableDatabase();?? ????????????switch?(matcher.match(uri))?{?? ????????????????case?PERSON:?? ????????????????????long?id?=?db.insert("person",?"id",?values);????//?插入記錄,?得到id?? ????????????????????return?ContentUris.withAppendedId(uri,?id);?????//?把id跟在uri后面返回?? ????????????????default:?? ????????????????????throw?new?RuntimeException("Uri不能識別:?"?+?uri);?? ????????????}?? ????????}?? ?? ????????@Override?? ????????public?int?delete(Uri?uri,?String?selection,?String[]?selectionArgs)?{?? ????????????SQLiteDatabase?db?=?helper.getWritableDatabase();?? ????????????switch?(matcher.match(uri))?{?? ????????????????case?PERSON:?? ????????????????????return?db.delete("person",?selection,?selectionArgs);?? ????????????????default:?? ????????????????????throw?new?RuntimeException("Uri不能識別:?"?+?uri);?? ????????????}?? ????????}?? ?? ????????@Override?? ????????public?int?update(Uri?uri,?ContentValues?values,?String?selection,?String[]?selectionArgs)?{?? ????????????SQLiteDatabase?db?=?helper.getWritableDatabase();?? ????????????switch?(matcher.match(uri))?{?? ????????????????case?PERSON:?? ????????????????????return?db.update("person",?values,?selection,?selectionArgs);?? ????????????????default:?? ????????????????????throw?new?RuntimeException("Uri不能識別:?"?+?uri);?? ????????????}?? ????????}?? ?? ????????@Override?? ????????public?String?getType(Uri?uri)?{?? ????????????switch?(matcher.match(uri))?{?? ????????????????case?PERSON:?? ????????????????????return?"vnd.android.cursor.dir/person";?????//?mimetype?? ????????????????default:?? ????????????????????throw?new?RuntimeException("Uri不能識別:?"?+?uri);?? ????????????}?? ????????}?? ????}?? ?? ?? ????//?B應用中要訪問A應用的數據的測試類?? ????public?class?ProviderTest?extends?AndroidTestCase?{?? ?????????? ????????public?void?test()?{?? ?????????? ????????????//?獲取解析器對象?? ????????????ContentResolver?resolver?=?getContext().getContentResolver();?? ?????????????? ????????????//?訪問內容提供者?? ????????????Uri?uri?=?Uri.parse("content://com.jxn.sqlite.provider");?? ????????????ContentValues?values?=?new?ContentValues();?? ?? ????????}?? ?????????? ????????public?void?testQuery()?{?? ?????????? ????????????//?獲取解析器對象?? ????????????ContentResolver?resolver?=?getContext().getContentResolver();?? ????????????Uri?uri?=?Uri.parse("content://com.jxn.sqlite.provider/person");?? ?????????????? ????????????//?訪問內容提供者?? ????????????Cursor?c?=?resolver.query(uri,?new?String[]{?"id",?"name",?"balance"?},?"balance>?",?new?String[]{?"9000"?},?"balance?DESC");?? ????????????while?(c.moveToNext())?{?? ????????????????Person?p?=?new?Person(c.getInt(0),?c.getString(1),?c.getInt(2));?? ????????????????System.out.println(p);?? ????????????}?? ????????}?? ?????????? ????????public?void?testInsert()?{?? ????????????ContentResolver?resolver?=?getContext().getContentResolver();?? ????????????Uri?uri?=?Uri.parse("content://com.jxn.sqlite.provider/person");?? ?????????????? ????????????ContentValues?values?=?new?ContentValues();?? ????????????values.put("name",?"provider");?? ????????????values.put("balance",?12345);?? ?????????????? ????????????//?插入數據,?并且得到這條數據的uri?? ????????????uri?=?resolver.insert(uri,?values);?? ?????????????? ????????????System.out.println(uri);?? ????????}?? ?????????? ????????public?void?testUpdate()?{?? ????????????ContentResolver?resolver?=?getContext().getContentResolver();?? ????????????Uri?uri?=?Uri.parse("content://com.jxn.sqlite.provider/person");?? ?????????????? ????????????ContentValues?values?=?new?ContentValues();?? ????????????values.put("name",?"update");?? ????????????values.put("balance",?54321);?? ????????????int?count?=?resolver.update(uri,?values,?null,?null);?? ????????????System.out.println(count);?? ????????}?? ?????????? ????????public?void?testDelete()?{?? ????????????ContentResolver?resolver?=?getContext().getContentResolver();?? ????????????Uri?uri?=?Uri.parse("content://com.jxn.sqlite.provider/person");?? ?????????????? ????????????int?count?=?resolver.delete(uri,?null,?null);?? ????????????System.out.println(count);?? ????????}?? ?????????? ????????public?void?testGetType()?{?? ????????????ContentResolver?resolver?=?getContext().getContentResolver();?? ????????????//?獲取uri的類型?? ????????????String?type?=?resolver.getType(Uri.parse("content://com.jxn.sqlite.provider/person"));?? ????????????System.out.println(type);?? ????????}?? ????} ?
轉載于:https://www.cnblogs.com/Renyi-Fan/p/7471659.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生
總結
以上是生活随笔 為你收集整理的内容提供者 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。