Activity,Service,broadcast and Contentprovider

android 4 大组件。

ContentProvider:使用

public class ImageSearchProvider extends ContentProvider {

    public final static String TAG = "ImageSearch.Provider";
public final static String DBASE_NAME = "imagesearch.db";
public final static int DBASE_VERSION = 1;
public final static String AUTHORITY = "com.globalsearch.imagesearch";
public final static UriMatcher URI_MATCHER;
public static ImageSearchDatabaseHelper mHelper =null;
private static final int SEARCH_COLLECTION_URI_INDICATER = 1;
private static final int SEARCH_SINGAL_URI_INDICATER = 2;
static{
URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
URI_MATCHER.addURI(AUTHORITY, SearchMetaData.TABLE_NAME, SEARCH_COLLECTION_URI_INDICATER);
URI_MATCHER.addURI(AUTHORITY, SearchMetaData.TABLE_NAME+"/#", SEARCH_SINGAL_URI_INDICATER);
}
public static class SearchMetaData implements BaseColumns
{
private SearchMetaData(){}; public final static String TABLE_NAME = "search";
public static final Uri CONTENT_URI = Uri.parse("content://"
+ ImageSearchProvider.AUTHORITY + "/search");
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.imagesearch.search";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.imagesearch.search";
public static final String DEFAULT_SORT_ORDER = "modified DESC"; public static final int IMAGE_TYPE_PATH = 1;
public static final int IMAGE_TYPE_CONTACT = 2; public static final String PERSIOD_ID = "persion_id";
public static final String BITMAP_PATH = "path";
public static final String TYPE = "type";
public static final String CONTACT_ID = "contact_id";
public static final String BITMAP_SIZE = "bitmap_size";
} @Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count =0;
SQLiteDatabase db = mHelper.getWritableDatabase();
switch(URI_MATCHER.match(uri))
{
case SEARCH_COLLECTION_URI_INDICATER:
count = db.delete(SearchMetaData.TABLE_NAME, selection, selectionArgs);
break;
case SEARCH_SINGAL_URI_INDICATER:
String id = uri.getPathSegments().get(1);
count = db.delete(SearchMetaData.TABLE_NAME,
SearchMetaData._ID+"="+id+(!TextUtils.isEmpty(selection)?"AND("+selection+')':""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown Uri "+uri);
} getContext().getContentResolver().notifyChange(uri, null);
return count;
} @Override
public String getType(Uri uri) {
switch(URI_MATCHER.match(uri))
{
case SEARCH_COLLECTION_URI_INDICATER:
return SearchMetaData.CONTENT_TYPE;
case SEARCH_SINGAL_URI_INDICATER:
return SearchMetaData.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown Uri "+uri);
}
} @Override
public Uri insert(Uri uri, ContentValues values) {
if (URI_MATCHER.match(uri) != SEARCH_COLLECTION_URI_INDICATER) {
throw new IllegalArgumentException("Unknown Uri " + uri);
} ContentValues inValue; if (values != null) {
inValue = new ContentValues(values);
} else {
inValue = new ContentValues();
} if (inValue.containsKey(SearchMetaData.PERSIOD_ID) == false) { throw new IllegalArgumentException(
"fail to insert row because persion_id is need " + uri);
} boolean containsBitmapPath =inValue.containsKey(SearchMetaData.BITMAP_PATH) ;
boolean containsContactId = inValue.containsKey(SearchMetaData.CONTACT_ID) ;
if((containsBitmapPath == false) && (containsContactId == false))
{
throw new IllegalArgumentException(
"fail to insert row because Path or ContactId must need one " + uri);
}
else if(containsBitmapPath && containsContactId)
{
throw new IllegalArgumentException(
"fail to insert row because Path and ContactId need only one " + uri);
}
else if(containsBitmapPath)
{
if(inValue.containsKey(SearchMetaData.TYPE) == false)
{
inValue.put(SearchMetaData.TYPE, SearchMetaData.IMAGE_TYPE_PATH);
}
}
else if(containsContactId)
{
if(inValue.containsKey(SearchMetaData.TYPE) == false)
{
inValue.put(SearchMetaData.TYPE, SearchMetaData.IMAGE_TYPE_CONTACT);
}
} SQLiteDatabase db = mHelper.getWritableDatabase(); long rowId = db.insert(SearchMetaData.TABLE_NAME, SearchMetaData.PERSIOD_ID, inValue); if(rowId>0)
{
Uri inSertAppUri = ContentUris.withAppendedId(SearchMetaData.CONTENT_URI, rowId);
getContext().getContentResolver().notifyChange(uri, null);
return inSertAppUri;
} throw new IllegalArgumentException(
"insert row failed " + uri);
} @Override
public boolean onCreate() {
Log.i(TAG, "[onCreate]");
mHelper = new ImageSearchDatabaseHelper(getContext(), DBASE_NAME, null, DBASE_VERSION);
Intent intent = new Intent(ImageSearchReceiver.BUILD_SEARCH_IMAGE_ACTION);
this.getContext().sendBroadcast(intent);
return false;
} @Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = mHelper.getReadableDatabase();
Cursor dbInnerCursor =null;
switch(URI_MATCHER.match(uri))
{
case SEARCH_COLLECTION_URI_INDICATER:
dbInnerCursor = db.query(SearchMetaData.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
break;
case SEARCH_SINGAL_URI_INDICATER:
// String id = String.valueOf(ContentUris.parseId(uri));
String id = uri.getPathSegments().get(1);
dbInnerCursor = db.query(SearchMetaData.TABLE_NAME, projection,
SearchMetaData._ID+"="+id+(!TextUtils.isEmpty(selection)?"AND("+selection+')':""),
selectionArgs, null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("Unknown Uri " + uri);
} return dbInnerCursor;
} @Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int count =0;
SQLiteDatabase db = mHelper.getWritableDatabase();
int match = URI_MATCHER.match(uri);
Log.i(TAG, "match "+match);
switch(match)
{
case SEARCH_COLLECTION_URI_INDICATER:
count = db.update(SearchMetaData.TABLE_NAME,values, selection, selectionArgs);
break;
case SEARCH_SINGAL_URI_INDICATER:
String id = uri.getPathSegments().get(1);
count = db.update(SearchMetaData.TABLE_NAME,values,
SearchMetaData._ID+"="+id+(!TextUtils.isEmpty(selection)?"AND("+selection+')':""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown Uri "+uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
} }
import com.globalsearch.imagesearch.provider.ImageSearchProvider.SearchMetaData;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper; public class ImageSearchDatabaseHelper extends SQLiteOpenHelper { public ImageSearchDatabaseHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
} @Override
public void onCreate(SQLiteDatabase db) {
//create table search
db.execSQL("CREATE TABLE "+SearchMetaData.TABLE_NAME+"("+
SearchMetaData._ID+" INTEGER PRIMARY KEY,"+
SearchMetaData.PERSIOD_ID+" INTEGER,"+
SearchMetaData.BITMAP_PATH+" TEXT,"+
SearchMetaData.TYPE+" INTEGER,"+
SearchMetaData.CONTACT_ID+" INTEGER,"+
SearchMetaData.BITMAP_SIZE+" INTEGER"+
")"
);
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub } }

1.定义provider extends ContentProvider

2.定义ImageSearchDatabaseHelper extends SQLiteOpenHelper

在onCreate的时候,创建数据库的表

然后在provider的onCreate中new helper。这样就能实现provider中的insert,query,update,delete方法。

上层通过mContentResolver 异步的方式调用,最终会调用到contentprovier。

contentprovier是一种数据库调用的框架,user只需要实现具体的contentprovider,而无需关心contentprovier的具体调用流程。

调用流程如上。

ContentProvider:监听。

数据库的监听使用的都是观察者模式,通过

mContentResolver.registerContentObserver(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, mImageStoreObserver);

来设定监听对象,判断数据库有变化。

自己定义ContentProvider的时候,如果变化,就需要通知getContext().getContentResolver().notifyChange(uri, null);

ContentProvider版本更新

在SQLiteOpenHelper 里面有

      @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db); }

在这里可以通过SQL语句更新数据库内容。

ContentProvider的权限和Uri

Uri:"content://"+ AUTHORITY + "/image_search"

AUTHORITY定义在Androidmanifest.xml,通常通过AUTHORITY可以获取该contentprovider。

<provider
            android:name="com.globalsearch.imagesearch.service.provider.ImageSearchProvider"
            android:authorities="com.globalsearch.imagesearch"
            android:exported="false" >
        </provider>

android:exported="false"表面外部程序不能访问该数据库。

05-11 22:18