1. 什麼是content provider?
一個應用程序將自己的數據分享給其他程序。進程間的程序通信。Provider-resolver:服務器-客服端。Provider封裝對相關數據的增刪改查,resolver解析這些操作,訪問provider。
2. Cursor:遊標;CursorAdapter:遊標適配器
(1) 需要在DBHelper(繼承SqliteOpenHelper)中注意:
A.構造函數中需要調用父類的構造函數:super(context,name,null,version);
B.需要在onCreate函數中添加數據庫創建語句:String sql ="create table person(_idinteger primary key autoincrement, name varchar(64),address varchar(64),ageinteger)";
(2) 在DBManager中利用DBHelper獲取sqlitedatabase,利用sqlitedatabase的insert()、update()、delete()和query()函數進行增刪查改。
(3) Adapter : SimpleCursorAdapter
adapter =newSimpleCursorAdapter(this,
R.layout.activity_main,service.listPersonCursor(),newString[] {
"name","address","age" },newint[]
{ R.id.textView1, R.id.textView2, R.id.textView3
});
from:和Cursor中字段相對應。To:和layout中相關text相對應。
3. LoaderManager:加載器管理器
(1) 需要用到2中(1)、(2)中相關數據,同時需要用到service的實現
(2) Activity需要實現LoaderCallBack<Cursor>接口,在該接口中,需要實現的函數:
A. public Loader<Cursor>onCreateLoader(intarg0, Bundle arg1);
B. publicvoidonLoadFinished(Loader<Cursor> arg0, Cursor arg1);
C. publicvoidonLoaderReset(Loader<Cursor> arg0);
(3) 在activity中的onCreate()函數中獲取LoaderManager,並用LoaderManager創建加載器。代碼:
manager = getLoaderManager();//獲取加載器管理器
manager.initLoader(1001,null,this);//創建加載器:3個參數:id;bundle;loadercallback<cursor>;
(4) 調用了initLoader後,程序會自動調用第三個參數中的public Loader<Cursor>onCreateLoader(intarg0, Bundle arg1)方法,在該方法中可以創建一個異步任務去加載數據。
(5) 在繼承的AsyncTaskLoader的異步加載器中public CursorloadInBackground()函數中進行數據獲取。
(6) 在獲取到數據後,會調用publicvoid onLoadFinished(Loader<Cursor> arg0,Cursor arg1)這個方法,可以將獲取的Cursor賦值給adapter,同時將adapter傳遞給listView。
4. 創建一個content provider:
(1) 需要建立一個像2中(1)中的DBHelper來建立一個共享數據庫表。(或者其他數據結構)
(2) 創建一個類繼承ContentProvider,在該ContentProvider中會出現:
A. publicboolean onCreate();
B. public String getType(Uriarg0);
C. public Uri insert(Uri arg0,ContentValues arg1)
D. publicint update(Uri arg0,ContentValues arg1, String arg2, String[] arg3);
E. publicint delete(Uri arg0, Stringarg1, String[] arg2);
F. public Cursor query(Uri arg0,String[] arg1, String arg2, String[] arg3,String arg4);
(3) 在清單文件中聲明:provider:
<providerandroid:name="com.example.one_contentprovider.PersonContentProvider"
android:authorities="com.example.android.PersonContentProvider">
</provider>
(Android:name):指向具體的ContentProvider;(android:authorities):爲該ContentProvider指定權限,即訪問路徑。
(4) 在provider中創建一個UriMatcher,用於添加Uri的匹配規則:
privatestaticfinalUriMatcherURI_MATCHER=newUriMatcher(UriMatcher.NO_MATCH);
static{ URI_MATCHER.addURI("com.example.android.PersonContentProvider","person",PERSONS);URI_MATCHER.addURI("com.example.android.PersonContentProvider","person/#",PERSON);
}
(5) 在onCreate中創建可以獲取sqlitedatabase的DBHelper。
(6) 重寫provider中的函數
A. publicboolean onCreate():
dbHelper = new DBHelper(getContext());
return false;
B. public String getType(Uriarg0):
int flag = URI_MATCHER.match(arg0);//匹配URI規則,返回匹配的值
switch(flag){
case PERSONS:
return “vnd.android.cursor.dir/person”;
case PERSON:
return “vnd.android.cursor.item/person”;
}
Return null;
C. public Uri insert(Uri arg0,ContentValues arg1)
Uri uri = null;
Int flag = URI_MARCHER.match(arg0);//匹配URI規則
Swtich(flag){
Case PERSONS://插入不會提供具體的id,所以只用匹配persons
SQlitedatabase database =dbHelper.getWriteDatabase();
Long _id =database.insert(“person”,null,arg1);
Uri = ContentUris.withAppendedId(arg0,_id);
Break;
}
Return uri;
D. publicint update(Uri arg0,ContentValues arg1, String arg2, String[] arg3)
int flag = URI_MATCHER.match(arg0);
SQliteDatabase database = dbHelper.getWriteDatabase();
Int count=0;
Switch(flag){
Case PERSON:
Long _id = ContentUris.parseId(arg0);
String where_values = “ _id = ”+_id;
If(arg2!=null&&!arg2.equals(“”)){
Where_values+=arg2;
}
Count=Database.update(“person”,arg1,where_values,arg3);
Break;
}
Return count;
E. publicint delete(Uri arg0, Stringarg1, String[] arg2)
int flag = URI_MATCHER.match(arg0);
SQliteDatabase database = dbHelper.getWriteDatabase();
Int count = 0;
Switch(flag){
Case PERSON:
Long _id = ContentUris.parseId(arg0);
String where_values = “ _id = ”+_id;
If(arg1!=null&&!arg1.equals(“”)){
Where_values+=arg1;
}
Count=Database.delete(“person”,where_values,arg2);
Break;
}
Return count;
F. public Cursor query(Uri arg0,String[] arg1, String arg2, String[] arg3,String arg4)
int flag = URI_MATCHER.match(arg0);
SQliteDatabase database = dbHelper.getReadDatabase();
Cursor cursor = null;
Switch(flag){
Case PERSON:
Long _id = ContentUris.parseId(arg0);
String where_values = “ _id = ”+_id;
If(arg2!=null&&!arg2.equals(“”)){
Where_values+=arg2;
}
Cursor=Database.query(“person”,arg1,where_values,arg3,null,null,arg4);
Break;
Case PERSONS:
Cursor = database.query(“person”,arg1,arg2,arg3,null,null,arg4);
Break;
}
Return cursor;
5. ContentProvider和LoaderManager結合使用
(1) 利用4中創建的ContentProvider作爲數據源
(2) Activity實現LoaderCallBack<Cursor>,同時,需要重寫幾個方法
A. public Loader<Cursor>onCreateLoader(intarg0, Bundle arg1);
B. publicvoidonLoadFinished(Loader<Cursor> arg0, Cursor arg1);
C. publicvoidonLoaderReset(Loader<Cursor> arg0);
(3) 在activity中的onCreate()函數中獲取LoaderManager,並用LoaderManager創建加載器。代碼:
manager = getLoaderManager();//獲取加載器管理器
manager.initLoader(1001,null,this);//創建加載器:3個參數:id;bundle;loadercallback<cursor>;
(4) 在public Loader<Cursor>onCreateLoader(intarg0, Bundle arg1)中創建一個加載器:
CursorLoader cursorLoader = new CursorLoader(this);
Uri uri = Uri.parse("content://com.example.android.PersonContentProvider/person");
cursorLoader.setProjection(new String[]{"name"});
cursorLoader.setUri(uri);
return cursorLoader;
(5) 在加載完成後,將Cursor傳遞給adapter,並傳給listView
List<String> list = new ArrayList<String>();
while(arg1.moveToNext()) {
String nameString= arg1.getString(arg1.getColumnIndex("name"));
list.add(nameString);
}
adapter =new Myadapter(list);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
6. 使用ContentProvider管理聯繫人:
(1) Uri:
A. 聯繫人Uri:ContactsContract.Contacts.CONTENT_URI
B. 電話和e-mail的Uri
C.
(2) 具體操作查看具體API