ContentProvider ContentProvider 在android中的作用是對外共用數據,也就是說你可以通過ContentProvider把應用中的數據共用給其他應用訪問,其他應用可以通過ContentProvider 對你應用中的數據進行添刪改查。ContentProvider的就是 ...
ContentProvider
ContentProvider 在android中的作用是對外共用數據,也就是說你可以通過ContentProvider把應用中的數據共用給其他應用訪問,其他應用可以通過ContentProvider 對你應用中的數據進行添刪改查。
ContentProvider的就是自定義增刪改查介面並暴露出去,讓別的應用訪問自己的數據。ContentResolver就是按照一定規則訪問內容提供者的數據。
ContentProvider對外共用數據步驟:
步驟
1. 定義一個類 繼承 ContentProvider
2. 定義匹配規則 uri
3. 通過靜態代碼塊添加匹配規則
4.在manifest.xml中配置contentProvider.
ContentProvider類主要方法的作用:
public boolean onCreate() 該方法在其它應用第一次訪問它時才會被創建。
public Uri insert(Uri uri, ContentValues values)
public int delete(Uri uri, String selection, String[] selectionArgs)
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
public String getType(Uri uri)
Uri介紹
uri代表了要操作的數據
ContentProvider的scheme為:content://
主機名(或叫Authority)用於唯一標識這個ContentProvider,外部調用者可以根據這個標識來找到它。
路徑(path)可以用來表示我們要操作的數據,路徑的構建應根據業務而定,如下:
要操作file表中id為10的記錄,可以構建這樣的路徑:/file/10
要操作file表中id為10的記錄的name欄位, file/10/name
要操作file表中的所有記錄,可以構建這樣的路徑:/file
當然要操作的數據可以是資料庫,也可以是文件、xml或網路等其他存儲方式。
代碼示例
public class FileProvider extends ContentProvider { private Context mContext; private static final int QUEYSUCESS = 0; private static final int INSERTSUCESS = 1;
//UriMatcher.NO_MATCH表示不匹配任何路徑的返回碼
private static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); private SQLiteDatabase mDb; private String mTableName = DbOpenHelper.STUDENT_TABLE_NAME;
static{
//註冊所有要匹配的uri
mUriMatcher.addURI("com.itcast.contentp.FileProvider", "query", QUEYSUCESS);
mUriMatcher.addURI("com.itcast.contentp.FileProvider", "insert", INSERTSUCESS);
}
@Override
public boolean onCreate() {
mContext = getContext();
mDb = new DbOpenHelper(mContext).getWritableDatabase();
return false;
}
@Override
public Cursor query(Uri uri, String[] arg1, String arg2, String[] arg3,String arg4) {
if (mUriMatcher.match(uri)== QUEYSUCESS ) {//uri匹配後進行下麵的操作
Cursor cursor = mDb.query(tableName, arg1, arg2, arg3, null, null, null);
getContext().getContentResolver().notifyChange(uri, null);
return cursor;
}else{
throw new IllegalArgumentException("match fail");
}
}
這裡只給出部分代碼。。。。。。
ContentResolver
使用ContentResolver調用ContentProvider提供的介面,對ContentProvider中的數據進行添加、刪除、修改和查詢操作時。
可以使用Activity提供的getContentResolver()方法來獲取ContentResolver對象。 ContentResolver 類提供了與ContentProvider類相同簽名的四個方法:
- public Uri insert(Uri uri, ContentValues values)
- public int delete(Uri uri, String selection, String[] selectionArgs)。
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
1.對ContentProvider中的數據進行增刪改查
直接看代碼:
//uriQuery必須與要查詢的ContentProvider中的要操作數據的uri保持一致(btw 這裡只給了查詢好插入的例子)
ContentValues values = new ContentValues(); Cursor cursor = getContentResolver().query(uriQuery, null, null, null, null); int count = cursor.getCount(); //獲取到一共有多少行 int contact_id = count + 1; ContentValues nameValues = new ContentValues(); nameValues.put("name", name); nameValues.put("mime_type", "vnd.android.cursor.item/name"); nameValues.put("contact_id", contact_id); getContentResolver().insert(uriInsert, nameValues);
2.監聽ContentProvider中數據的變化
在ContentProvider 發生數據變化時調用getContentResolver().notifyChange(uri, null)來通知註冊在此URI上的訪問者。
當數據放生變化時會調用ContentObserver的onChange()來進行一系列的後續操作~~~
如下:
public class MainActivity extends Activity { private Uri uri; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //註冊 uri = Uri.parse("content://com.itcast.contentp.AccountProvider");
getContentResolver().registerContentObserver(uri, true, new MyObserver(new Handler()))
}
}
//監聽到變化後調用onChange()來執行一系列操作
private class MyObserver extends ContentObserver { Uri uri = Uri.parse("content://com.itcast.contentp.AccountProvider");
public MyObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
Cursor cursor = getContentResolver().query(uri, new String[]{"file","mime_type","date"}, null, null, null);
while(cursor.moveToNext()){
//執行一些操作
}
}
}