Content Provider:內(nèi)容提供者
- 應(yīng)用程序間共享數(shù)據(jù)的一種方式
- 為存儲和獲取數(shù)據(jù)提供了統(tǒng)一的接口
- Android為常見的一些數(shù)據(jù)提供了默認(rèn)的 Content Provider
- 四大組件之一
定義
- 內(nèi)容提供者將一些特定的應(yīng)用程序數(shù)據(jù)供給其他應(yīng)用程序使用
- 數(shù)據(jù)可以存儲于文件系統(tǒng)雕拼、SQLite數(shù)據(jù)庫或其他方式
- 內(nèi)容提供者繼承于ContentProvider基類,為其他應(yīng)用程序取用和存儲它管理的數(shù)據(jù)實(shí)現(xiàn)了一套標(biāo)準(zhǔn)方法
- 應(yīng)用程序并不是直接調(diào)用這些方法擂送,而是使用ContentResolver對象小腊,調(diào)用它的方法作為替代
- ContentResolver 可以與任意內(nèi)容提供者進(jìn)行會話也颤,與其合作來對所有相關(guān)交互通訊進(jìn)行管理
ContentProvider實(shí)現(xiàn)過程
Database --> Uri --> UriMatcher --> ContentProvider -- > query/insert/update/delete --> AndroidManifest.xml
系統(tǒng)提供的Provider
系統(tǒng)提供的Provider
獲取系統(tǒng)的通訊錄信息
public class PhoneBookInfo extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_phone_book_info);
ListView lvInfo = (ListView) findViewById(R.id.phoneBookInfo_lvInfo);
List<String> stringList = new ArrayList<>();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, stringList);
lvInfo.setAdapter(arrayAdapter);
//查詢通訊錄數(shù)據(jù)
//由于要讀取通訊錄,所以要在manifest中加上"android.permission.READ_CONTACTS"的權(quán)限
Cursor cursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,null,null,null);
if (cursor!=null && cursor.moveToFirst()){
for (int i = 0; i < cursor.getCount(); i++) {
String disPlayName = cursor.getString(
cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)
);
String number = cursor.getString(
cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER)
);
arrayAdapter.add(disPlayName + "\n" + number);
cursor.moveToNext();
}
}
}
}
自定義Content Provider
URI后面還以加上 *** 或 #分別表示:
- *:表示匹配任意長度的任意字符
- <code>#</code>:表示匹配任意長度的數(shù)字
-
DataBase:創(chuàng)建一個(gè)繼承SQLiteOpenHelper的類,并創(chuàng)建<code>user</code>黍翎、<code>book</code>兩個(gè)表凉驻。
public class DataBaseHelper extends SQLiteOpenHelper { public static final String DATABASE = "test.db"; public static final int VERSION = 1; public static final String TABLENAME_USER = "user"; public static final String USER_NAME = TABLENAME_USER + "_name"; public static final String USER_AGE = TABLENAME_USER + "_age"; public static final String TABLENAME_BOOK = "book"; public static final String BOOK_NAME = TABLENAME_BOOK + "_name"; public static final String BOOK_WRITER = TABLENAME_BOOK + "_writer"; public DataBaseHelper(Context context) { super(context, DATABASE, null, VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table " + TABLENAME_USER + " (" + USER_NAME + " TEXT not null, " + USER_AGE + " TEXT not null )" ); db.execSQL("create table " + TABLENAME_BOOK + " (" + BOOK_NAME + " TEXT not null, " + BOOK_WRITER + " TEXT not null ) " ); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
-
Uri:創(chuàng)建UriList.java
UriList.Java -
創(chuàng)建一個(gè)繼承ContentProvider的類腻要,然后設(shè)置UriMatcher和完善重構(gòu)方法:
public class TestContentProvider extends ContentProvider { //初始UriMatcher private static UriMatcher sUriMatcher; public static final int UriMatcher_CODE_USER = 1; public static final int UriMatcher_CODE_BOOK = 2; static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(UriList.AUTHORITY, DataBaseHelper.TABLENAME_USER, UriMatcher_CODE_USER); sUriMatcher.addURI(UriList.AUTHORITY, DataBaseHelper.TABLENAME_BOOK, UriMatcher_CODE_BOOK); } private DataBaseHelper mDataBaseHelper; @Override public boolean onCreate() { //獲取數(shù)據(jù)庫 mDataBaseHelper = new DataBaseHelper(getContext()); return true; } @Nullable @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { //從數(shù)據(jù)庫中query Cursor cursor = mDataBaseHelper.getReadableDatabase().query(getTableName(uri), projection, selection, selectionArgs, null, null, sortOrder); return cursor; } @Nullable @Override public String getType(Uri uri) { return null; } @Nullable @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase sqLiteDatabase = mDataBaseHelper.getWritableDatabase(); Long id; id = sqLiteDatabase.insert(getTableName(uri), null, values); //“withAppendedId”:將uri和id連接起來(即uri/id) //“parseId(Uri contentUri)”:這個(gè)方法負(fù)責(zé)把contentURI 后邊的id解析出來,即返回值是“id” return ContentUris.withAppendedId(uri, id); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { if(TextUtils.isEmpty(getTableName(uri))){ return -1; } int count = mDataBaseHelper.getWritableDatabase().delete(getTableName(uri), selection, selectionArgs); return count; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return mDataBaseHelper.getWritableDatabase().update(getTableName(uri), values, selection, selectionArgs); } //獲取表名 private String getTableName(Uri uri) { int code = sUriMatcher.match(uri); String tableName = ""; switch (code) { case UriMatcher_CODE_USER: tableName = DataBaseHelper.TABLENAME_USER; break; case UriMatcher_CODE_BOOK: tableName = DataBaseHelper.TABLENAME_BOOK; break; } return tableName; } }
-
設(shè)置完ContentProvider之后就可以在相應(yīng)功能里進(jìn)行query/insert/update/delete方法涝登,如:
@Override public void onClick(View v) { ContentResolver contentResolver = getContentResolver(); switch (v.getId()){ //查詢 case R.id.provider_btnQuery: mStringList.clear(); Cursor cursor = contentResolver.query(UriList.Book_Uri,null,null,null,null); if (cursor!= null && cursor.moveToFirst()){ String KeyValue1 = cursor.getString(cursor.getColumnIndexOrThrow(DataBaseHelper.BOOK_NAME)); String KeyValue2 = cursor.getString(cursor.getColumnIndexOrThrow(DataBaseHelper.BOOK_WRITER)); mStringList.add(KeyValue1+"\n"+KeyValue2); cursor.moveToNext(); } mAdapter.notifyDataSetChanged(); break; //刪除 case R.id.provider_btnDelet: contentResolver.delete(UriList.Book_Uri, null, null); break; //插入 case R.id.provider_btnInsert: ContentValues contentValues = new ContentValues(); contentValues.put(DataBaseHelper.BOOK_NAME, mEdtKeyValue1.getText().toString()); contentValues.put(DataBaseHelper.BOOK_WRITER, mEdtKeyValue2.getText().toString()); contentResolver.insert(UriList.Book_Uri, contentValues); break; //修改 case R.id.provider_btnUpdate: ContentValues values = new ContentValues(); values.put(DataBaseHelper.BOOK_NAME, mEdtKeyValue1.getText().toString()); values.put(DataBaseHelper.BOOK_WRITER, mEdtKeyValue2.getText().toString()); contentResolver.update(UriList.Book_Uri, values, null, null); break; } }
-
最后記得在manifest.xml中聲明ContentProvider:
要注意的是<code>authorities</code>的值是與上面的<code>AUTHORITY</code>的值一樣雄家;
<code>exported</code>設(shè)置為<code>true</code>可以跨應(yīng)用使用這個(gè)ContentProvider。
聲明ContentProvider