對ContentProvider的一點認識
1、ContentProvider
是android的四大元件之一,作用是對外共享資料,就是把自已應用程式裡的資料分享給其他應用程式,其他應用可以通過ContentProvider對你應用中的資料進行添刪改查。使用ContentProvider對外共享資料的好處是統一了資料的訪問方式。 ContentProvider(內容提供者)用於提供資料的統一訪問格式,封裝底層的具體實現。對於資料的使用者來說,無需知曉資料的來源是資料庫、檔案,或者網路,只需簡單地使用ContentProvider提供的資料操作介面,也就是增(insert)、刪(delete)、改(update)、查(query)四個過程。 contentprovider是一個抽象類,想要擁有自己的provider就必須繼承自這個類並重寫想要實現的方法,並且在manifest檔案裡進行註冊。如:
//這裡只想實現插入和查詢
@Override
public boolean onCreate() {
smsDbHelper = SmsDbHelper.getInstance(getContext());
return true;
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
int match = mUriMater.match(uri);
switch (match) {
case CODE_URI_SMS_ALL:
break;
case CODE_URI_SMS_ONE:
long id = ContentUris.parseId(uri);
selection = "_id = ?";
selectionArgs = new String[]{String.valueOf(id)};
break ;
}
db = smsDbHelper.getReadableDatabase();
Cursor cr = db.query(SendMsg.TABLE_NAME, projection, selection,
selectionArgs, null, null, sortOrder);
cr.setNotificationUri(getContext().getContentResolver(),URI_SMS_ALL);
return cr;
}
@Nullable
@Override
public String getType(Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
//如果匹配就會返回匹配碼
int match = mUriMater.match(uri);
if (match != CODE_URI_SMS_ALL)
throw new IllegalArgumentException("Wrong Uri" + uri);
db = smsDbHelper.getWritableDatabase();
long rowId = db.insert(SendMsg.TABLE_NAME, null, values);
if (rowId > 0) {
//說明插入成功
notifyDataSetChange();
return ContentUris.withAppendedId(uri, rowId);
}
db.close();
return null;
}
private void notifyDataSetChange() {
getContext().getContentResolver().notifyChange(URI_SMS_ALL, null);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
return 0;
}
//在manifest檔案裡進行註冊
<provider
android:authorities="com.example.lyw.sms.provider"
android:name=".db.SmsProvider"/>
2.ContentReciver
當外部應用需要對ContentProvider中的資料進行新增、刪除、修改和查詢操作時,可以使用ContentResolver 類來完成,要獲取ContentResolver 物件,可以使用Activity提供的getContentResolver()方法。 ContentResolver 類提供了與ContentProvider類相同簽名的四個方法:
public int delete(Uri uri, String selection, String[]
selectionArgs):該方法用於從ContentProvider刪除資料。
public int update(Uri uri, ContentValues values, String
selection, String[] selectionArgs):該方法用於更新ContentProvider中的資料。
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder):該方法用於從
ContentProvider中獲取資料。
3、Uri介紹
Uri代表了要操作的資料,Uri主要包含了兩部分資訊:1>需要操作的ContentProvider ,2>對ContentProvider中的什麼資料進行操作,會在程式中定義一下幾個欄位:
public static final String AUTHORITY ="com.example.lyw.sms.provider";
//對外查詢通過這個常量獲取
public static final Uri URI_SMS_ALL = Uri.parse("content://" + AUTHORITY
+ "/sms");
+
private static final int CODE_URI_SMS_ALL = 0;
private static final int CODE_URI_SMS_ONE = 1;
4、UriMatcher類使用介紹
因為Uri代表了要操作的資料,所以我們經常需要解析Uri,並從Uri中獲取資料。Android系統提供了兩個用於操作Uri的工具類,分別為UriMatcher和ContentUris 。UriMatcher類用於匹配Uri。
static {
mUriMater = new UriMatcher(UriMatcher.NO_MATCH);
//註冊路徑
mUriMater.addURI(AUTHORITY, "sms", CODE_URI_SMS_ONE);
mUriMater.addURI(AUTHORITY, "sms/#", CODE_URI_SMS_ALL);
}
//匹配操作,如果匹配就會返回匹配碼
int match = mUriMater.match(uri);
switch (match) {
case CODE_URI_SMS_ALL:
break;
case CODE_URI_SMS_ONE:
long id = ContentUris.parseId(uri);
selection = "_id = ?";
selectionArgs = new String[]{String.valueOf(id)};
break;
}
5.ContentUris類使用介紹
ContentUris類用於操作Uri路徑後面的ID部分( CODE_URI_SMS_ALL)。
withAppendedId(uri, id)用於為路徑加上ID部分:
Uri uri =ContentUris.withAppendedId(uri, rowId);
//生成的URI為:com.example.lyw.sms.provider/sms/rowId;
parseId(uri)方法用於從路徑中獲取ID部分:
Uri uri = Uri.parse("content://com.example.lyw.sms.provider/sms/10")
long personid = ContentUris.parseId(uri);//personid為10
PS:當修改過provider裡的資料需要呼叫,
getContext().getContentResolver().notifyChange(URI_SMS_ALL, null)
具體應用等我整理號程式碼再上傳。