Android-----ContentProvider

ContentProvider是Android四大组件之一,也是一个Android应用与外界交流的媒介之一,通常被称为“数据共享接口”

ContentProvider并没有想象中那么难,原理就和JDBC一样,通过和数据存储媒体建立一个桥,然后通过特定的通讯语句去进行数据的增删改查。

下面是一个对手机图书SQLite的增删改查

第一步:规划数据库,通过写定各种常量去确定SQLite的属性
  public static final String AUTHORITY = "com.androidbook.provider.BookProvider";
    
    public static final String DATABASE_NAME = "book.db";
    public static final int DATABASE_VERSION = 1;
    public static final String BOOKS_TABLE_NAME = "books";
    
    private BookProviderMetaData() {}
    
    //inner class describing columns and their types
    public static final class BookTableMetaData implements BaseColumns 
    {
        private BookTableMetaData() {}
        public static final String TABLE_NAME = "books";

        //uri and mime type definitions
        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/books");
        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.androidbook.book";
        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.androidbook.book";

        public static final String DEFAULT_SORT_ORDER = "modified DESC";
        
        //Additional Columns start here.
        //string type
        public static final String BOOK_NAME = "name";
        //string type
        public static final String BOOK_ISBN = "isbn";
        //string type
        public static final String BOOK_AUTHOR = "author";
        //Integer from System.currentTimeMillis()
        public static final String CREATED_DATE = "created";
        //Integer from System.currentTimeMillis()
        public static final String MODIFIED_DATE = "modified";
    }
第二步:创建接口继承ContentProvider,创建数据库,并重写query,insert,update,delete这四个方法
public class BookProvider extends ContentProvider
创建数据库
private
static HashMap<String, String> sBooksProjectionMap; static { sBooksProjectionMap = new HashMap<String, String>(); sBooksProjectionMap.put(BookTableMetaData._ID, BookTableMetaData._ID); //name, isbn, author sBooksProjectionMap.put(BookTableMetaData.BOOK_NAME, BookTableMetaData.BOOK_NAME); sBooksProjectionMap.put(BookTableMetaData.BOOK_ISBN, BookTableMetaData.BOOK_ISBN); sBooksProjectionMap.put(BookTableMetaData.BOOK_AUTHOR, BookTableMetaData.BOOK_AUTHOR); //created date, modified date sBooksProjectionMap.put(BookTableMetaData.CREATED_DATE, BookTableMetaData.CREATED_DATE); sBooksProjectionMap.put(BookTableMetaData.MODIFIED_DATE, BookTableMetaData.MODIFIED_DATE); } //Provide a mechanism to identify //all the incoming uri patterns. private static final UriMatcher sUriMatcher; private static final int INCOMING_BOOK_COLLECTION_URI_INDICATOR = 1; private static final int INCOMING_SINGLE_BOOK_URI_INDICATOR = 2; static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(BookProviderMetaData.AUTHORITY, "books", INCOMING_BOOK_COLLECTION_URI_INDICATOR); sUriMatcher.addURI(BookProviderMetaData.AUTHORITY, "books/#", INCOMING_SINGLE_BOOK_URI_INDICATOR); } /** * This class helps open, create, and upgrade the database file. */ private static class DatabaseHelper extends SQLiteOpenHelper { DatabaseHelper(Context context) { super(context, BookProviderMetaData.DATABASE_NAME, null, BookProviderMetaData.DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { Log.d(TAG,"inner oncreate called"); db.execSQL("CREATE TABLE " + BookTableMetaData.TABLE_NAME + " (" + BookTableMetaData._ID + " INTEGER PRIMARY KEY," + BookTableMetaData.BOOK_NAME + " TEXT," + BookTableMetaData.BOOK_ISBN + " TEXT," + BookTableMetaData.BOOK_AUTHOR + " TEXT," + BookTableMetaData.CREATED_DATE + " INTEGER," + BookTableMetaData.MODIFIED_DATE + " INTEGER" + ");"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.d(TAG,"inner onupgrade called"); Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); db.execSQL("DROP TABLE IF EXISTS " + BookTableMetaData.TABLE_NAME); onCreate(db); } } private DatabaseHelper mOpenHelper; @Override public boolean onCreate() { Log.d(TAG,"main onCreate called"); mOpenHelper = new DatabaseHelper(getContext()); return true; }
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,  String sortOrder) 
    {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        switch (sUriMatcher.match(uri)) {
        case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
            qb.setTables(BookTableMetaData.TABLE_NAME);
            qb.setProjectionMap(sBooksProjectionMap);
            break;

        case INCOMING_SINGLE_BOOK_URI_INDICATOR:
            qb.setTables(BookTableMetaData.TABLE_NAME);
            qb.setProjectionMap(sBooksProjectionMap);
            qb.appendWhere(BookTableMetaData._ID + "=" 
                        + uri.getPathSegments().get(1));
            break;

        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        // If no sort order is specified use the default
        String orderBy;
        if (TextUtils.isEmpty(sortOrder)) {
            orderBy = BookTableMetaData.DEFAULT_SORT_ORDER;
        } else {
            orderBy = sortOrder;
        }

        // Get the database and run the query
        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
        Cursor c = qb.query(db, projection, selection, 
                   selectionArgs, null, null, orderBy);
        
        //example of getting a count
        @SuppressWarnings("unused")
        int i = c.getCount();

        // Tell the cursor what uri to watch, 
        // so it knows when its source data changes
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }
public int delete(Uri uri, String where, String[] whereArgs) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        int count;
        switch (sUriMatcher.match(uri)) {
        case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
            count = db.delete(BookTableMetaData.TABLE_NAME, 
                    where, whereArgs);
            break;

        case INCOMING_SINGLE_BOOK_URI_INDICATOR:
            String rowId = uri.getPathSegments().get(1);
            count = db.delete(BookTableMetaData.TABLE_NAME, 
                    BookTableMetaData._ID + "=" + rowId
                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), 
                    whereArgs);
            break;

        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
public int update(Uri uri, ContentValues values, String where, String[] whereArgs) 
    {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        int count;
        switch (sUriMatcher.match(uri)) {
        case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
            count = db.update(BookTableMetaData.TABLE_NAME, 
                    values, where, whereArgs);
            break;

        case INCOMING_SINGLE_BOOK_URI_INDICATOR:
            String rowId = uri.getPathSegments().get(1);
            count = db.update(BookTableMetaData.TABLE_NAME, 
                    values, BookTableMetaData._ID + "=" + rowId
                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), 
                    whereArgs);
            break;

        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
public Uri insert(Uri uri, ContentValues initialValues) {
        // Validate the requested uri
        if (sUriMatcher.match(uri) 
                != INCOMING_BOOK_COLLECTION_URI_INDICATOR) 
        {
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        ContentValues values;
        if (initialValues != null) {
            values = new ContentValues(initialValues);
        } else {
            values = new ContentValues();
        }

        Long now = Long.valueOf(System.currentTimeMillis());

        // Make sure that the fields are all set
        if (values.containsKey(BookTableMetaData.CREATED_DATE) == false) 
        {
            values.put(BookTableMetaData.CREATED_DATE, now);
        }

        if (values.containsKey(BookTableMetaData.MODIFIED_DATE) == false) 
        {
            values.put(BookTableMetaData.MODIFIED_DATE, now);
        }

        if (values.containsKey(BookTableMetaData.BOOK_NAME) == false) 
        {
            throw new SQLException(
               "Failed to insert row because Book Name is needed " + uri);
        }

        if (values.containsKey(BookTableMetaData.BOOK_ISBN) == false) {
            values.put(BookTableMetaData.BOOK_ISBN, "Unknown ISBN");
        }
        if (values.containsKey(BookTableMetaData.BOOK_AUTHOR) == false) {
            values.put(BookTableMetaData.BOOK_ISBN, "Unknown Author");
        }

        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        long rowId = db.insert(BookTableMetaData.TABLE_NAME, 
                BookTableMetaData.BOOK_NAME, values);
        if (rowId > 0) {
            Uri insertedBookUri = 
                ContentUris.withAppendedId(
                        BookTableMetaData.CONTENT_URI, rowId);
            getContext()
               .getContentResolver()
                    .notifyChange(insertedBookUri, null);
            
            return insertedBookUri;
        }

        throw new SQLException("Failed to insert row into " + uri);
    }
/*
 *验证URI
 */
 public String getType(Uri uri) {
        switch (sUriMatcher.match(uri)) {
        case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
            return BookTableMetaData.CONTENT_TYPE;

        case INCOMING_SINGLE_BOOK_URI_INDICATOR:
            return BookTableMetaData.CONTENT_ITEM_TYPE;

        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }
    }
第三步:注册ContentProvider
<provider android:name=".BookProvider"   android:authorities="com.androidbook.provider.BookProvider"/>
第四步:显性操作
增加图书
public void addBook()
    {
        Log.d(tag,"Adding a book");
        ContentValues cv = new ContentValues();
        cv.put(BookProviderMetaData.BookTableMetaData.BOOK_NAME, "book1");
        cv.put(BookProviderMetaData.BookTableMetaData.BOOK_ISBN, "isbn-1");
        cv.put(BookProviderMetaData.BookTableMetaData.BOOK_AUTHOR, "author-1");
        
        ContentResolver cr = this.mContext.getContentResolver();
        Uri uri = BookProviderMetaData.BookTableMetaData.CONTENT_URI;
        Log.d(tag,"book insert uri:" + uri);
        Uri insertedUri = cr.insert(uri, cv);
        Log.d(tag,"inserted uri:" + insertedUri);
        this.reportString("Inserted Uri:" + insertedUri);
    }
删除图书
public void removeBook()
    {
        int i = getCount();
        ContentResolver cr = this.mContext.getContentResolver();
        Uri uri = BookProviderMetaData.BookTableMetaData.CONTENT_URI;
        Uri delUri = Uri.withAppendedPath(uri, Integer.toString(i));
        reportString("Del Uri:" + delUri);
        cr.delete(delUri, null, null);
        this.reportString("Newcount:" + getCount());
    }
查询图书列表
public void showBooks()
    {
        Uri uri = BookProviderMetaData.BookTableMetaData.CONTENT_URI;
        Activity a = (Activity)this.mContext;
        Cursor c = a.managedQuery(uri, 
                null, //projection
                null, //selection string
                null, //selection args array of strings
                null); //sort order
        int iname = c.getColumnIndex(BookProviderMetaData.BookTableMetaData.BOOK_NAME);
        int iisbn = c.getColumnIndex(BookProviderMetaData.BookTableMetaData.BOOK_ISBN);
        int iauthor = c.getColumnIndex(BookProviderMetaData.BookTableMetaData.BOOK_AUTHOR);
        
        //Report your indexes
        reportString("name,isbn,author:" + iname + iisbn + iauthor);
        
        //walk through the rows based on indexes
        for(c.moveToFirst();!c.isAfterLast();c.moveToNext())
        {
            //Gather values
            String id = c.getString(1);
            String name = c.getString(iname);
            String isbn = c.getString(iisbn);
            String author = c.getString(iauthor);
            
            //Report or log the row
            StringBuffer cbuf = new StringBuffer(id);
            cbuf.append(",").append(name);
            cbuf.append(",").append(isbn);
            cbuf.append(",").append(author);
            reportString(cbuf.toString());
        }
        
        //Report how many rows have been read
        int numberOfRecords = c.getCount();
        reportString("Num of Records:" + numberOfRecords);
        
        //Close the cursor
        //ideally this should be done in 
        //a finally block.
        c.close();
    }
private int getCount()
    {
        Uri uri = BookProviderMetaData.BookTableMetaData.CONTENT_URI;
        Activity a = (Activity)this.mContext;
        Cursor c = a.managedQuery(uri, 
                null, //projection
                null, //selection string
                null, //selection args array of strings
                null); //sort order
        int numberOfRecords = c.getCount();
        c.close();
        return numberOfRecords;
    }
原文地址:https://www.cnblogs.com/vijay/p/3531432.html