Android自定義Content Provider及使用

先看看官網API的介紹: java

Content providers are one of the primary building blocks of Android applications, providing content to applications.  android

Content providers是Android app的基石之一。
git

They encapsulate data and provide it to applications through the single ContentResolver interface. github

它們封裝了數據,提供了惟一一個ContentResolver接口。 數據庫

 A content provider is only required if you need to share data between multiple applications. For example, the contacts data is used by multiple applications and must be stored in a content provider. app

只有當你須要在不一樣的APP之間分享數據,你纔有必要建立一個的 content provider。好比,系統的聯繫人數據常常被許多APP所使用,因此必須存放在 content provider裏。
ide

 If you don't need to share data amongst multiple applications you can use a database directly via SQLiteDatabase.
若是你不須要在不一樣的APP之間分享數據,你能夠直接使用SQLite數據庫。

When a request is made via a ContentResolver the system inspects the authority of the given URI and passes the request to the content provider registered with the authority. 
ui

當APP經過ContentResolver發起一個對content provider的數據請求時,系統會根據請求裏的URI的身份標識將請求遞交給對應的content provider this

The content provider can interpret the rest of the URI however it wants. The UriMatcher class is helpful for parsing URIs.
收到請求的content provider能夠自行翻譯URI的剩餘內容,UriMatcher類對此大有幫助。

The primary methods that need to be implemented are:
若是繼承了ContentProvider類,須要實現如下方法。

onCreate() which is called to initialize the provider 初始化
query(Uri, String[], String, String[], String) which returns data to the caller 返回請求的數據
insert(Uri, ContentValues) which inserts new data into the content provider 插入新數據
update(Uri, ContentValues, String, String[]) which updates existing data in the content provider 修改數據
delete(Uri, String, String[]) which deletes data from the content provider 刪除數據
getType(Uri) which returns the MIME type of data in the content provider 返回數據類型

spa



自定義一個java類並繼承自ContentProvider類:

public class BookProvider extends ContentProvider {

    public static final String PROVIDER_NAME = "com.hong.app.contentproviderexample.Books";

    public static final String PROVIDER_CONTENT_STRING = "content://" + PROVIDER_NAME + "/books";
    public static final Uri CONTENT_URI = Uri.parse(PROVIDER_CONTENT_STRING);
    static final String _ID = "_id";
    static final String TITLE = "title";
    static final String ISBN = "isbn";

    static final int BOOKS = 1;
    static final int BOOK_ID = 2;

    private static final UriMatcher uriMatcher;

    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(PROVIDER_NAME, "books", BOOKS);
        uriMatcher.addURI(PROVIDER_NAME, "book/#", BOOK_ID);
    }

    //--FOR DATABASE USE
    SQLiteDatabase booksDB;
    static final String DATABASE_NAME = "Books";
    static final String DATABASE_TABLE = "titles";
    static final int DATABASE_VERSION = 1;
    static final String DATABASE_CREATE = "create table " + DATABASE_TABLE + "(_id integer primary key autoincrement, title text not null,isbn text not null);";

    private static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(DATABASE_CREATE);
        }

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

    @Override
    public boolean onCreate() {
        Context context = getContext();
        DatabaseHelper databaseHelper = new DatabaseHelper(context);
        booksDB = databaseHelper.getWritableDatabase();
        return (booksDB == null) ? false : true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
        queryBuilder.setTables(DATABASE_TABLE);

        if (uriMatcher.match(uri) == BOOK_ID) {
            queryBuilder.appendWhere(_ID + " = " + uri.getPathSegments().get(1));
        }

        if (sortOrder == null || sortOrder == "") {
            sortOrder = TITLE;
        }

        Cursor cursor = queryBuilder.query(
                booksDB,
                projection,
                selection,
                selectionArgs,
                null,
                null,
                sortOrder
        );

        cursor.setNotificationUri(getContext().getContentResolver(), uri);

        return cursor;
    }

    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
            case BOOKS:
                return "vnd.android.cursor.dir/vnd.example.administrator.books";

            case BOOK_ID:
                return "vnd.android.cursor.item/vnd.example.administrator.books";

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

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        long rowID = booksDB.insert(DATABASE_TABLE, "", values);

        if (rowID > 0) {
            Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
            getContext().getContentResolver().notifyChange(_uri, null);
            return _uri;
        } else {
            // throw new SQLException("Failed to insert row into " + uri);
            return null;
        }

    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case BOOKS:
                count = booksDB.delete(DATABASE_TABLE, selection, selectionArgs);
                break;

            case BOOK_ID:
                String id = uri.getPathSegments().get(1);
                count = booksDB.delete(DATABASE_TABLE, _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 int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        int count = 0;
        switch (uriMatcher.match(uri)) {
            case BOOKS:
                count = booksDB.update(DATABASE_TABLE, values, selection, selectionArgs);
                break;
            case BOOK_ID:
                count = booksDB.update(DATABASE_TABLE, values, _ID + "=" + uri.getPathSegments().get(1) + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("UnKnown URI : " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
}


主要用到的類:  UriMatcher SQLiteDatabase SQLiteOpenHelper
主要用到的方法:重寫了ContentProvider類的6個方法—— update,delete,onCreate,query,getType,insert; uriMatcher . match ( uri ) getContext () getContentResolver () notifyChange ( uri , null ) getPathSegments ()
關鍵:以上自定義的content provider 用SQLite的方式保存數據,用    UriMatcher 類來覈對傳入的uri進而進行對應的操做。



使用自定義的content provider:

private void addContent() {
        ContentValues values = new ContentValues();
        values.put(
                BookProvider.TITLE,
                titleEditText.getText().toString()
        );
        values.put(
                BookProvider.ISBN,
                ISBNEditText.getText().toString()
        );
        Uri uri = getContentResolver().insert(BookProvider.CONTENT_URI, values);
        Toast.makeText(getBaseContext(), "Add book: \n" + uri.toString(), Toast.LENGTH_LONG).show();
    }


    private void retrieveAll() {

        Uri allTitles = Uri.parse(BookProvider.PROVIDER_CONTENT_STRING);
        Cursor cursor;

        CursorLoader cursorLoader = new CursorLoader(
                getBaseContext(),
                allTitles,
                null,
                null,
                null,
                "title desc"
        );
        cursor = cursorLoader.loadInBackground();

        StringBuilder builder = new StringBuilder();
        if (cursor!=null) {
            if (cursor.moveToFirst()) {
                do {
                    builder.append(cursor.getString(BookProvider.BOOK_ID) + ","
                            + cursor.getString(cursor.getColumnIndex(BookProvider.TITLE)) + ","
                            + cursor.getString(cursor.getColumnIndex(BookProvider.ISBN)) + "\n");
                } while (cursor.moveToNext());

                String content = builder.toString();

                new AlertDialog.Builder(this)
                        .setTitle("Books")
                        .setMessage("All books:\n" + content)
                        .show();

            }
        }
    }





注意事項:


  1. 記得在 AndroidManifest.xml中聲明provider。而且android:exported值設爲true


<provider
        android:exported="true"
        android:name=".BookProvider"
        android:authorities="com.hong.app.contentproviderexample.Books">
    </provider>




    2.聲明權限


<uses-permission android:name="com.hong.app.contentproviderexample.Books" />






源碼:https://github.com/freewheel70/ContentProviderExample
相關文章
相關標籤/搜索