應用和應用之間的數據通常都不是孤立的,每個應用都需要與其他的應用來交換數據,例如,我們安裝在手機上的安全軟件提供了來電防火牆的功能,這個時候安全軟件通常會需要訪問我們手機自帶通信錄中數據。在android中採用了ContentProvider(內容提供者)這一組件實現不用應用之間數據的共享,這種數據的共享包括了不同的數據類型。一個應用程序可以通過ContentProvider來對外提供自己的數據,同時可以通過ContentResolver來操作其他應用內容提供者提供的數據。
作爲android的四大組件之一,ContentProvider也需要在項目清單文件中進行配置
<provider android:name="com.example.database.MyContentProvider" android:authorities="com.example.dbapp"/>
第一個屬性比較好理解,就是我們自己定義的內容提供者實現類,這個實現類需要放在應用所在包或者其子包下面,第二個參數參數指定了其他應用訪問我這個內容提供者的標誌,可以這樣理解,www.sina.com.cn/index.html中的www.sina.com.cn指定我們訪問的地址是新浪一樣,authorities屬性指定了訪問自定義內容提供者的地址。
自己定義的內容提供者需要繼承ContentProvider這個父類,同時需要重寫其中的方法。其中的增刪改查方法都需要我們自己根據具體的業務邏輯來實現,onCreate方法是在自定義的內容提供者被創建的時候由系統自動的調用。
package com.example.database;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
public class MyContentProvider extends ContentProvider {
private DBOpenHelper dbhelper;
private static final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final String URI = "com.example.dbapp";
/*
* 兩個變量分別用來標示uri的匹配模式,一種是匹配所有的數據,一種是標示匹配單個數據。
*對外提供兩種uri形式,滿足不同操作
*/
private static final int PERSONS = 1;
private static final int PERSON = 2 ;
static {
matcher.addURI(URI, "person", PERSONS);
matcher.addURI(URI, "person/#", PERSON);
}
@Override
public boolean onCreate() {
dbhelper = new DBOpenHelper(this.getContext());
return true;
}
/*
*下面的四個方法分別實現了對contacts數據庫中person表的增刪改查
*
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbhelper.getWritableDatabase();
switch(matcher.match(uri)){
case 1:
Cursor cursor = db.query("person", null, null, null, null, null,null);
return cursor;
case 2:
Cursor cursor2 = db.query("person", projection, selection, selectionArgs, null, null, sortOrder);
return cursor2;
}
return null;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
SQLiteDatabase db = dbhelper.getWritableDatabase();
switch(matcher.match(uri)){
case 1 :
db.execSQL("insert into person values(?,?)", new String[]{values.getAsString("name"),values.getAsString("phone")});
break;
default :
throw new IllegalArgumentException(uri+ "無法匹配");
}
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbhelper.getWritableDatabase();
switch(matcher.match(uri)){
case 1:
int count = db.delete("person", selection, selectionArgs);
return count;
case 2:
long id = ContentUris.parseId(uri);
db.delete("person","person="+id + "and"+ selection, selectionArgs);
break;
}
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = dbhelper.getWritableDatabase();
switch(matcher.match(uri)){
case 1:
long count = db.update("person", values, null, null);
return (int)count;
case 2:
long count2 =db.update("person", values, selection, selectionArgs);
return (int)count2;
}
return 0;
}
}
在完成了自定義的內容提供者之後,我們可以在其他的應用中完成對這個應用中數據的操作,下面是在hello應用中,通過單元測試的方法來完成對com.example.dbapp應用數據的增刪改查
package com.example.test;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;
public class MyContentProviderTest extends AndroidTestCase {
public void testInsert(){
Uri uri = Uri.parse("content://com.example.dbapp/person");
for(int i = 0;i<20 ; i++){
ContentValues values = new ContentValues();
values.put("name", "zhangsan"+i);
values.put("phone", "130xxxxxxxx");
this.getContext().getContentResolver().insert(uri, values);
}
}
public void testDelete(){
Uri uri = Uri.parse("content://com.example.dbapp/person");
this.getContext().getContentResolver().delete(uri, null,null);//兩個參數都爲空表示刪除所有的數據
}
public void testQuery(){
Uri uri = Uri.parse("content://com.example.dbapp/person");
Cursor cursor = this.getContext().getContentResolver().query(uri, new String []{"name"}, null, null, "order by name asc");
while(cursor.moveToNext()){
Log.i("PersonName",cursor.getString(cursor.getColumnIndex("name")));
}
}
public void testUpdate(){
Uri uri = Uri.parse("content://com.example.dbapp/person/15");
ContentValues values = new ContentValues();
values.put("phone", "131xxxxxxxx");
this.getContext().getContentResolver().update(uri, values,"name=?", new String[]{"zhangsan0"});
}
}
這樣我們就通過內容提供者完成了一個應用對另一個應用數據的操作。