Android四大组件之contentProvider

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"表面外部程序不能访问该数据库。

 

posted on 2015-01-08 11:34  Joyfulmath  阅读(368)  评论(0编辑  收藏  举报

导航