Android提供了一些主要数据类型的Contentprovider,比如音频、视频、图片和私人通讯录等。可在android.provider包下面找到一些android提供的Contentprovider。可以获得这些Contentprovider,查询它们包含的数据.也就是说,一个程序可以通过实现一个Content Provider的抽象接口将自己的数据暴露出去。外界根本看不到,也不用看到这个应用暴露的数据在应用当中是如何存储的,或者是用数据库存储还是用文件存储,还是通过网上获得,这些一切都不重要,重要的是外界可以通过这一套标准及统一的接口和程序里的数据打交道,可以读取程序的数据,也可以删除程序的数据,
ContentProvider提供了一种统一的通过Uri实现数据操作的方式。其步骤为:
1. 在当前应用程序中定义一个ContentProvider。
2. 在当前应用程序的AndroidManifest.xml中注册此ContentProvider
3. 其他应用程序通过ContentResolver和Uri来获取此ContentProvider的数据。
ContentResolver提供了诸如insert(), delete(), query()和update()之类的方法。用于实现对ContentProvider中数据的存取操作。
Uri是一个通用资源标志符,将其分为A,B,C,D 4个部分:
A:无法改变的标准前缀,包括;"content://"、"tel://"等。当前缀是"content://"时,说明通过一个Content Provider控制这些数据
B:URI的标识,它通过authorities属性声明,用于定义了是哪个ContentProvider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的 类名。例如;"content://com.test.data.myprovider"
C:路径,可以近似的理解为需要操作的数据库中表的名字,如:"content://hx.android.text.myprovider/name"中的name
下面是个例子:
public class RuiXin { public static final String DBNAME = "ruixinonlinedb"; public static final String TNAME = "ruixinonline"; public static final int VERSION = 3; public static String TID = "tid"; public static final String EMAIL = "email"; public static final String USERNAME = "username"; public static final String DATE = "date"; public static final String SEX = "sex"; public static final String AUTOHORITY = "com.ruixin.login"; public static final int ITEM = 1; public static final int ITEM_ID = 2; public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.ruixin.login"; public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.ruixin.login"; public static final Uri CONTENT_URI = Uri.parse("content://" + AUTOHORITY + "/ruixinonline"); }
public class MyProvider extends ContentProvider{ DBlite dBlite; SQLiteDatabase db; private static final UriMatcher sMatcher; static{ // 生成一个UriMatcher sMatcher = new UriMatcher(UriMatcher. NO_MATCH); // 生成一个UriMatcher 如果满足 这个要求 就返回值为 RuiXin.ITEM_ID sMatcher.addURI(RuiXin. AUTOHORITY,RuiXin. TNAME, RuiXin.ITEM); sMatcher.addURI(RuiXin. AUTOHORITY, RuiXin.TNAME+"/#" , RuiXin.ITEM_ID); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub db = dBlite.getWritableDatabase(); int count = 0; switch ( sMatcher.match(uri)) { case RuiXin. ITEM: count = db.delete(RuiXin. TNAME,selection, selectionArgs); break; case RuiXin. ITEM_ID: String id = uri.getPathSegments().get(1); count = db.delete(RuiXin. TID, RuiXin.TID+"=" +id+(!TextUtils.isEmpty(RuiXin. TID= "?")? "AND("+selection+ ')': ""), selectionArgs); break; default: throw new IllegalArgumentException( "Unknown URI"+uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub switch ( sMatcher.match(uri)) { case RuiXin. ITEM: return RuiXin. CONTENT_TYPE; case RuiXin. ITEM_ID: return RuiXin. CONTENT_ITEM_TYPE; default: throw new IllegalArgumentException( "Unknown URI"+uri); } } @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub db = dBlite.getWritableDatabase(); long rowId; if( sMatcher.match(uri)!=RuiXin. ITEM){ throw new IllegalArgumentException( "Unknown URI"+uri); } rowId = db.insert(RuiXin. TNAME,RuiXin. TID,values); if(rowId>0){ Uri noteUri=ContentUris.withAppendedId(RuiXin. CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(noteUri, null); return noteUri; } throw new IllegalArgumentException( "Unknown URI"+uri); } @Override public boolean onCreate() { // TODO Auto-generated method stub this. dBlite = new DBlite( this.getContext()); // db = dBlite.getWritableDatabase(); // return ( db == null)?false:true; return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub db = dBlite.getWritableDatabase(); Cursor c; Log. d("-------" , String.valueOf(sMatcher.match(uri))); switch ( sMatcher.match(uri)) { case RuiXin. ITEM: c = db.query(RuiXin. TNAME, projection, selection, selectionArgs, null , null, null); break; case RuiXin. ITEM_ID: String id = uri.getPathSegments().get(1); c = db.query(RuiXin. TNAME, projection, RuiXin.TID+"=" +id+(!TextUtils.isEmpty(selection)? "AND("+selection+ ')': ""),selectionArgs, null, null, sortOrder); break; default: Log. d("!!!!!!" , "Unknown URI" +uri); throw new IllegalArgumentException( "Unknown URI"+uri); } c.setNotificationUri(getContext().getContentResolver(), uri); return c; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } }
在其AndroidManifest.xml中声明此ContentProvider,其中authorities属性定义了此ContentProvider的Uri标识。
<provider android:name=".MyProvider" android:authorities="com.test.MyProvider"/>
访问数据
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //通过contentResolver进行查找 contentResolver = MainActivity.this.getContentResolver(); Cursor cursor = contentResolver.query( RuiXin.CONTENT_URI, new String[] { RuiXin.EMAIL, RuiXin.USERNAME, RuiXin.DATE,RuiXin.SEX }, null, null, null); while (cursor.moveToNext()) { Toast.makeText(MainActivity.this, cursor.getString(cursor.getColumnIndex(RuiXin.EMAIL)) + " " + cursor.getString(cursor.getColumnIndex(RuiXin.USERNAME)) + " " + cursor.getString(cursor.getColumnIndex(RuiXin.DATE)) + " " + cursor.getString(cursor.getColumnIndex(RuiXin.SEX)), Toast.LENGTH_SHORT).show(); } startManagingCursor(cursor); //查找后关闭游标 }