ContentProvider簡介
ContentProvider(内容提供者)是Android的四大元件之一,可以實作不同程序間的資料共享。在Android 源碼系統中,像設定,聯系人,多媒體等都使用到了ContentProvider。其實ContentProvider最終也是操作Sqlite資料庫,實作資料的增删改查。接下來我們看看怎麼使用。
使用步驟:
一、建立一個UserContentProvider類繼承ContentProvider,并在AndroidManifest.xml中添加授權:
android:authorities="com.psp.user.provider"
<provider
android:name=".UserContentProvider"
android:authorities="com.psp.user.provider"
android:enabled="true"
android:exported="true"/>
- name:ContentProvider的類名
- authorities:唯一辨別了一個ContentProvider,外部應用通過該屬性值來通路ContentProvider。是以該屬性值必須唯一
- exported:表明是否允許其他應用調用ContentProvider,true表示支援,false表示不支援
二、建立資料庫操作類如下:首先聲明資料庫的名稱,表名,以及版本号,并建立一張使用者表。
public class DBOpenHelper extends SQLiteOpenHelper {
//資料庫名
private static final String DB_NAME = "user.db";
//表名
public static final String DB_TABLE_NAME = "user";
//資料可版本号
private static final int DB_VERSION = 1;
public DBOpenHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
//建立一張使用者表
String sql_create_user = "CREATE TABLE IF NOT EXISTS "+DB_TABLE_NAME+"(_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT,age TEXT)";
db.execSQL(sql_create_user);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
三、實作UserContentProvider類,在onCreate()方法中向資料庫中插入一條資料。實作query和insert方法,其他方法不做探究。
public class UserContentProvider extends ContentProvider {
//授權,和AndroidManifest.xml中的保持一緻
public static final String AUTHORITY = "com.psp.user.provider";
//比對Uri的類
private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//設定ContentProvider的唯一辨別,用于比對不同的Uri
private static final int USER_INFO = 1;
private SQLiteDatabase mDb;
//初始化
static {
//若URI資源路徑 = content://com.psp.user.provider/user ,則傳回注冊碼USER_INFO
uriMatcher.addURI(AUTHORITY, "user", USER_INFO);
}
private Context mContext;
public UserContentProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getType(Uri uri) {
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Uri insert(Uri uri, ContentValues values) {
int uri_code = uriMatcher.match(uri);
switch (uri_code) {
case USER_INFO:
mDb.insert(DBOpenHelper.DB_TABLE_NAME, null, values);
break;
default:
throw new RuntimeException("出錯了!!");
// 向該表添加資料
}
// 當該URI的ContentProvider資料發生變化時,通知外界(即通路該ContentProvider資料的通路者)
mContext.getContentResolver().notifyChange(uri, null);
return uri;
}
@Override
public boolean onCreate() {
mContext = getContext();
mDb = new DBOpenHelper(getContext()).getReadableDatabase();
//初始化一條資料
ContentValues initialValues = new ContentValues();
initialValues.put("name","zhang san");
initialValues.put("age",18);
mDb.insert(DBOpenHelper.DB_TABLE_NAME,null,initialValues);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
int result = uriMatcher.match(uri);
//查詢資料
switch (result){
case USER_INFO:
return mDb.query(DBOpenHelper.DB_TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder, null);
default:
throw new RuntimeException("出錯了!!");
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
throw new UnsupportedOperationException("Not yet implemented");
}
}
三、在其他應用中查詢或者插入資料,這邊以在本應用中操作為例。其他應用中方法一樣。
在MainActivity的布局檔案中添加兩個按鈕,一個實作查詢,一個實作插入。布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.psp.contentproviderdemo.MainActivity">
<Button
android:id="@+id/bt_querry_user_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="query user"
android:textAllCaps="false"
/>
<Button
android:id="@+id/bt_insert_user_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="insert user"
android:textAllCaps="false"
/>
</LinearLayout>
MainActivity的代碼實作如下:
public class MainActivity extends AppCompatActivity {
//比對uri和UserContentProvider中的保持一緻
public static final Uri USER_CONTENT_URI = Uri.parse("content://com.psp.user.provider/user");
Button query_user;
Button insert_user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
query_user = findViewById(R.id.bt_querry_user_info);
insert_user = findViewById(R.id.bt_insert_user_info);
query_user.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
queryProviderData(MainActivity.this);
}
});
insert_user.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
insertProviderData(MainActivity.this,"li si",22);
}
});
}
//查詢資料庫
public static String queryProviderData(Context context) {
try {
Cursor cursor = context.getContentResolver().query(USER_CONTENT_URI,
new String[]{"_id", "name","age"}, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
Log.d("psp_log","_id= "+cursor.getInt(0)+"\n"+
"name="+cursor.getString(1)+"\n"+"age="+cursor.getInt(2));
Toast.makeText(context,"name="+cursor.getString(1)+"\n"+"age="+cursor.getInt(2),Toast.LENGTH_SHORT).show();
}
cursor.close();
}else {
Log.d("psp_log","snCursor = null" );
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
//向資料庫中插入資料
public static void insertProviderData(Context context,String name,int age) {
ContentValues userValues = new ContentValues();
userValues.put("name", name);
userValues.put("age", age);
context.getContentResolver().insert(USER_CONTENT_URI, userValues);
}
}
四、結果驗證
啟動應用,點選查詢按鈕,看是否有一條初始化的“zhang san”的使用者,列印結果:
01-05 10:00:45.610 28827-28827/com.psp.contentproviderdemo D/psp_log: _id= 1
name=zhang san
age=18
我們在點選插入按鈕,再點選查詢按鈕,看看“li si”是否插入成功,列印結果:
01-05 10:29:48.343 29993-29993/com.psp.contentproviderdemo D/psp_log: _id= 1
name=zhang san
age=18
01-05 10:29:48.354 29993-29993/com.psp.contentproviderdemo D/psp_log: _id= 2
name=li si
age=22
列印結果說明資料操作是成功的。
源碼位址:
GitHub位址:pshiping2014/ContentProviderDemo