學習內容提供者
- 內容提供者
- 1.利用現有的內容提供者,操作相應程式的資料(ContentResolver 類)
- 2.自定義自己的內容提供者,供其他程式使用
內容提供者
內容提供者,一般是用于跨程式之間資料的共享,一種是利用現有的內容提供者,來讀取和操作相應程式的資料,另一種是創建自己的內容提供者為其他程式使用,
1.利用現有的內容提供者,操作相應程式的資料(ContentResolver 類)
想要訪問內容提供者中所共享的資料,就必須要使用到ContentResolver這個類,可以通過Context中的getContentResolver()方法,獲取到該類的實體,然后在這個實體的基礎上進行插入,洗掉,更新,查詢操作,
Cursor curosr = null;
curosr = getContentResolver().query(uri,projection,selection,selectionArgs,sortOrder);
public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
查詢操作,在這里,通過getContentResolver來獲得一個ContentResolver實體,然后利用這個實體,呼叫query方法進行查詢,query方法接收五個引數,第一個是uri,第二個是查詢的列明,是字串陣列型別,第三個是查詢的where子句,第四個是where子句中占位符的匹配值,第五個是排序順序, 該方法回傳一個Cursor物件,利用這個cursor,通過cursor.getString……等,cursor.getColumnIndex等獲取資料,
ContentValues contentValues = new ContentValues();
contentValues.put("title",edt_title.getText().toString());
contentValues.put("content",edt_content.getText().toString());
getContentResolver().insert(uri,contentValues);
public Uri insert(@NonNull Uri uri, ContentValues contentValues)
插入操作,就像對資料庫的插入一樣,把資料放在ContentValues里面,然后呼叫insert方法,Insert方法接收兩個引數,第一個是一個uri,第二個是插入的內容ContentValues,Insert方法,回傳的是一個uri,
public int update(@NonNull Uri uri, ContentValues contentValues, String selection, String[] selectionArgs)
更新操作,接收四個引數,第一個引數是一個uri,第二個引數是更新的內容,第三個引數是where子句,第四個引數是where子句占位符的匹配值,該方法回傳更新的行數,
public int delete(@NonNull Uri uri, String selection, String[] selectionArgs)
洗掉操作,接收三個引數,第一個是uri,第二個是where子句,第三個是where子句占位符的匹配值,該方法回傳被洗掉的行數,
可以看到,不管是增刪改查里面的哪一個方法,都有一個引數是uri,這個uri就像一個門牌號一樣,可以識別出是針對哪一個程式的哪一個表哪一個記錄,
public static final String AUTHORITY = "com.example.asus.beiwanglu.provider";
Uri uri = Uri.parse("content://"+AUTHORITY+"/BEIWANGLU/"+ID);
URI記憶體字串:由兩部分組成,一個是authority部分,一個是path部分
authority為程式的 包名.provider
path是用于對一個應用程式內不同的表進行區分,比如有表table1 那么完整的URI 應該是下面
content:// com.example.asus.beiwanglu.provider /table1
如果還需要精確到哪一行記錄,則可以在表/table1的后面加上/2 這個2就代表是表table1的第二條記錄,如下
content:// com.example.asus.beiwanglu.provider /table1/2
得到內容URI字串以后,需要把它決議成Uri物件,才可以使用,利用Uri.parse(“URI內容字串”);這樣就可以上面的增刪改查中使用了,
在真正使用其他程式的內容提供者的時候,需要去了解其有哪些可以匹配的uri,它提供了哪些資料進行操作等具體的資訊,
2.自定義自己的內容提供者,供其他程式使用
前面只是獲取其他程式的URI,然后通過內容提供者來訪問其他程式的資料,那么那些可供外部訪問的應用程式,又是如何提供這些外部訪問介面的呢?現在通過自定義自己的內容提供者,來進一步的學習,
(1)創建內容提供者:
右擊你的包名—new—Other—ContentProvider(當然也可以新建一個類,繼承與ContentProvider,但是別忘記在組態檔中注冊)

Authority指定為包名.provider,每個內容提供者都有一個authority,是唯一的,如果有多個自定義內容提供者類,需要不同用以區分,
Exported 是否允許外部程式訪問該內容提供者,可以在組態檔中進行更改,true/false
Enabled 是否使能這個內容提供者,即要不要啟用它
(2)在組態檔中注冊內容提供者(如果你用的是新建一個類,繼承于ContentProvider的方法的話)
<provider
android:authorities="com.example.asus.beiwanglu.provider"
android:name=".BEIWANGLUProvider"
android:enabled="true"
android:exported="true">
</provider>
上面的四行和(1)中的是一樣的,
(3)重寫內容提供者的6個方法:
自定義內容提供者,繼承于ContentProvider,需要重寫6個基本方法,onCreate(),insert(),update(),delete(),query(),getType(),
其中四個資料的操作方法,在上面大致介紹過,這里直接放上一段代碼片段,是一個備忘錄程式的自定義內容提供者
public class BEIWANGLUProvider extends ContentProvider{
public static final int BEIWANGLU_DIR = 0; //資料庫中備忘錄表
public static final int BEIWANGLU_ITEM = 1; //資料庫中備忘錄表中的某一行
public static final String AUTHORITY = "com.example.asus.beiwanglu.provider"; //URI的authority部分
private static UriMatcher uriMatcher;
private BeiWangLuDatabaseHelper dbHelper;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//addURI接收三個引數為Uri物件的authority部分,path部分,以及一個自定義的int 值,起到標識作用
uriMatcher.addURI(AUTHORITY,"BEIWANGLU",BEIWANGLU_DIR); //資料庫中備忘錄表的Uri
uriMatcher.addURI(AUTHORITY,"BEIWANGLU/#",BEIWANGLU_ITEM); //資料庫中備忘錄表某一行的Uri
}
@Override
public boolean onCreate() {
dbHelper = new BeiWangLuDatabaseHelper(getContext(),"BeiWangLuContent.db",null,2);
return true;
}
@Override
public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = null;
switch (uriMatcher.match(uri)){
case BEIWANGLU_DIR:
cursor = db.query("BEIWANGLU",projection,selection,selectionArgs,null,null,sortOrder);
break;
case BEIWANGLU_ITEM:
String BEIWANGLU_ID = uri.getPathSegments().get(1);
cursor = db.query("BEIWANGLU",projection,"id = ?",new String[]{BEIWANGLU_ID},null,null,sortOrder);
break;
default:
}
return cursor;
}
@Override
public String getType(@NonNull Uri uri) {
switch (uriMatcher.match(uri)){
case BEIWANGLU_DIR:
return "vnd.android.cursor.dir/vnd.com.example.asus.beiwanglu.provider.BEIWANGLU";
case BEIWANGLU_ITEM:
return "vnd.android.cursor.item/vnd.com.example.asus.beiwanglu.provider.BEIWANGLU";
default:
}
return null;
}
@Override
public Uri insert(@NonNull Uri uri, ContentValues contentValues) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
Uri uriReturn = null;
switch (uriMatcher.match(uri)){
case BEIWANGLU_DIR:
case BEIWANGLU_ITEM:
long newBEIWANGLU_ID = db.insert("BEIWANGLU",null,contentValues);
uriReturn = Uri.parse("content://"+AUTHORITY+"/BEIWANGLU/"+newBEIWANGLU_ID);
break;
}
return uriReturn;
}
@Override
public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int deleteRow = 0;
switch (uriMatcher.match(uri)){
case BEIWANGLU_DIR:
case BEIWANGLU_ITEM:
break;
}
return deleteRow;
}
@Override
public int update(@NonNull Uri uri, ContentValues contentValues, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int updateRow = 0;
switch (uriMatcher.match(uri)){
case BEIWANGLU_DIR:
updateRow = db.delete("BEIWANGLU",selection,selectionArgs);
break;
case BEIWANGLU_ITEM:
String update_ID = uri.getPathSegments().get(1);
updateRow = db.update("BEIWANGLU",contentValues,"id = ?",new String[]{update_ID});
break;
}
return updateRow;
}
}
分析:
public static final int BEIWANGLU_DIR = 0; //資料庫中備忘錄表
public static final int BEIWANGLU_ITEM = 1; //資料庫中備忘錄表中的某一行
public static final String AUTHORITY = "com.example.asus.beiwanglu.provider"; //URI的authority部分
private static UriMatcher uriMatcher;
private BeiWangLuDatabaseHelper dbHelper;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//addURI接收三個引數為Uri物件的authority部分,path部分,以及一個自定義的int 值,起到標識作用
uriMatcher.addURI(AUTHORITY,"BEIWANGLU",BEIWANGLU_DIR); //資料庫中備忘錄表的Uri
uriMatcher.addURI(AUTHORITY,"BEIWANGLU/#",BEIWANGLU_ITEM); //資料庫中備忘錄表某一行的Uri
}
這一段代碼,是為了匹配uri而使用的,外部程式訪問該程式的時候,需要對其所傳入的uri進行決議,分析出呼叫方是想要訪問哪一張表的資料,
內容URI字串,主要就兩種格式,一個是以路徑結尾,一個是以id結尾,代表想要訪問表中的哪一條記錄,因此,我們可以借助UriMatcher這個類,把URI的匹配格式加進去,到時候只要通過match方法,傳入uri就可以知道外部程式具體想要訪問的是哪一張表哪一條記錄了
創建一個UriMatch物件,并且默認是無匹配的,然后呼叫addURI方法,第一個引數是authority,第二個引數是表名或者表的某一條記錄,第三個引數是int型別,用于標識
比如上面的代碼,第一行是把URI為 AUTHORITY+”BEIWANGLU”加進去,代表的是想要訪問備忘錄表這個表,如果外部程式使用uri為
content://+AUTHORITY+”/BEIWANGLU” 訪問的時候,這時候呼叫uriMatcher.match(uri),就可以得到BEIWANGLU_DIR這個標簽,這樣就可以判斷出是想要訪問備忘錄表了,
如果外部程式使用的uri為content://+AUTHORITY+”/BEIWANGLU/2” 就可以知道外部程式是想要訪問備忘錄表的第二條資料記錄
@Override
public String getType(@NonNull Uri uri) {
switch (uriMatcher.match(uri)){
case BEIWANGLU_DIR:
return "vnd.android.cursor.dir/vnd.com.example.asus.beiwanglu.provider.BEIWANGLU";
case BEIWANGLU_ITEM:
return "vnd.android.cursor.item/vnd.com.example.asus.beiwanglu.provider.BEIWANGLU";
default:
}
return null;
}
這是另一個十分重要的方法,根據傳入的內容URI來回傳相應的MIME型別,一個內容URI字串所對應的MIME型別,一般由兩個部分組成
第一部分:如果URI以路徑結尾,則為vnd.android.cursor.dir/ 如果是以id結尾,那么就是vnd.android.cursor.item/
第二部分:vnd..
其他幾個方法,相信在看了我上面的代碼之后你一定對自定義內容提供者有了更多的了解,
最后,文中如有不對之處,歡迎指出,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/232486.html
標籤:其他
上一篇:js分享國外app,facebook,whatsapp,facebookMessenger....
下一篇:7.1 系統內強制某個應用橫屏
