1. 程式人生 > >android 內容提供器

android 內容提供器

android執行時許可權

在執行程式時動態的對程式的某一項許可權申請做授權,避免了安裝軟體時不一次性授權不能安裝的問題。 不是所有許可權都需要在執行時申請授權,現在的許可權歸為兩類一類是普通許可權一類是危險許可權,還有一類是特殊許可權用的比較少。 對於普通許可權系統為自行幫我們授權,如申請訪問網路狀態,而危險許可權則需要得到使用者的同意才能使用,每一個危險許可權屬於一個許可權組,若許可權組中任意一個許可權被允許那麼這個許可權組的所有許可權都會被允許。 在一個 需要使用者授權的操作中基本流程應該是,在執行要執行的操作前先檢查許可權是否被允許,不被允許則申請使用者的許可,允許則直接進行操作。

訪問其他應用程式的資料

類容提供器的用法主要有兩種一種是建立自己程式的內容提供器供外部訪問,另一種是通過外部的內容提供器來訪問其他程式中的資料。 對於每一個程式想要訪問內容提供器中的資料,則必須藉助ContentResolver類,通過Context類中的getContentResolver方法取得該類的例項,該類提供了一系列的方法對資料進行增刪改查。不同於資料庫的增刪改查操作接受表名,內容提供器使用URI來唯一標識資料,他主要由兩部分組成一部分是authority一部分是path,前者用於對不同應用程式做區分,後者用於對同一應用程式中的不同的表做區分。 authority:com.example.app.provider path:table1 ,table2 uri:content://com.example.app.provider.table1 uri:content://com.example.app.provider.table2 uri可以清楚的表示出我們想要訪問的哪個程式的哪個資料,若不這樣按照資料庫的那種模式我們無法讓程式知道我們要訪問的是哪一個程式中的表 得到uri字串後要解析成uri物件才可以被作為引數傳入

  Uri uri = Uri.parse("content://com.example.databasetest.provider/book");

這時便可以通過這個uri物件來查詢這張表了 常見的增刪改查程式碼

package com.example.providertest;

import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.
os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { private String newId; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button addData = (Button) findViewById(R.id.add_data); addData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 新增資料 Uri uri = Uri.parse("content://com.example.databasetest.provider/book"); ContentValues values = new ContentValues(); values.put("name", "A Clash of Kings"); values.put("author", "George Martin"); values.put("pages", 1040); values.put("price", 55.55); Uri newUri = getContentResolver().insert(uri, values); newId = newUri.getPathSegments().get(1); } }); Button queryData = (Button) findViewById(R.id.query_data); queryData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 查詢資料 Uri uri = Uri.parse("content://com.example.databasetest.provider/book"); Cursor cursor = getContentResolver().query(uri, null, null, null, null); if (cursor != null) { while (cursor.moveToNext()) { String name = cursor.getString(cursor. getColumnIndex("name")); String author = cursor.getString(cursor. getColumnIndex("author")); int pages = cursor.getInt(cursor.getColumnIndex ("pages")); double price = cursor.getDouble(cursor. getColumnIndex("price")); Log.d("MainActivity", "book name is " + name); Log.d("MainActivity", "book author is " + author); Log.d("MainActivity", "book pages is " + pages); Log.d("MainActivity", "book price is " + price); } cursor.close(); } } }); Button updateData = (Button) findViewById(R.id.update_data); updateData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 更新資料 Uri uri = Uri.parse("content://com.example.databasetest.provider/book/" + newId); ContentValues values = new ContentValues(); values.put("name", "A Storm of Swords"); values.put("pages", 1216); values.put("price", 24.05); getContentResolver().update(uri, values, null, null); } }); Button deleteData = (Button) findViewById(R.id.delete_data); deleteData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 刪除資料 Uri uri = Uri.parse("content://com.example.databasetest.provider/book/" + newId); getContentResolver().delete(uri, null, null); } }); } }

建立自己的內容提供器

新建一個類去整合contentProvider的方式來建立一個自己的內容提供器,覆寫其中的 個抽象方法, oncreate(),增刪改查,getType()

onCreate()初始化內容提供器的時候呼叫,通常完成對資料庫的建立和升級等操作,返回true成功返回false失敗 getType() 根據傳入內容的URI來返回相應的MIME型別。 URI的格式主要有兩種 URI以/結尾表示訪問此表中的資料,而以id結尾則表示訪問詞表中為此ID值的資料,一般用萬用字元的方式來分別匹配這兩種格式的內容URI *表示任意長度的任意字元,#表示匹配任意長度的數字 再借助UriMatcher這個類就可以輕鬆實現匹配內容URI的功能,它提供了一個addURI的方法接受三個引數,再別分吧authrity path 和一個自定義程式碼傳入,這樣在呼叫urimatcher的match方法時就可以將一個uri物件傳入,返回值是一個能夠匹配此uri物件所對應的自定義程式碼,利用這個diamagnetic判斷呼叫方期望訪問的是哪一張表的哪一個資料。 通過匹配其他程式傳入的url來判斷要訪問的資料,這時再在內容提供器內部呼叫資料庫的操作去操作資料庫,最後將得到的值返回給外部程式。 程式碼:

package com.example.databasetest;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

public class DatabaseProvider extends ContentProvider {

    public static final int BOOK_DIR = 0;

    public static final int BOOK_ITEM = 1;

    public static final int CATEGORY_DIR = 2;

    public static final int CATEGORY_ITEM = 3;

    public static final String AUTHORITY = "com.example.databasetest.provider";

    private static UriMatcher uriMatcher;

    private MyDatabaseHelper dbHelper;

    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);
        uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM);
        uriMatcher.addURI(AUTHORITY, "category", CATEGORY_DIR);
        uriMatcher.addURI(AUTHORITY, "category/#", CATEGORY_ITEM);
    }

    @Override
    public boolean onCreate() {
        dbHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 2);
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        // 查詢資料
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        Cursor cursor = null;
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
                cursor = db.query("Book", projection, selection, selectionArgs, null, null, sortOrder);
                break;
            case BOOK_ITEM:
                String bookId = uri.getPathSegments().get(1);
                cursor = db.query("Book", projection, "id = ?", new String[] { bookId }, null, null, sortOrder);
                break;
            case CATEGORY_DIR:
                cursor = db.query("Category", projection, selection, selectionArgs, null, null, sortOrder);
                break;
            case CATEGORY_ITEM:
                String categoryId = uri.getPathSegments().get(1);
                cursor = db.query("Category", projection, "id = ?", new String[] { categoryId }, null, null, sortOrder);
                break;
            default:
                break;
        }
        return cursor;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // 新增資料
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        Uri uriReturn = null;
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
            case BOOK_ITEM:
                long newBookId = db.insert("Book", null, values);
                uriReturn = Uri.parse("content://" + AUTHORITY + "/book/" + newBookId);
                break;
            case CATEGORY_DIR:
            case CATEGORY_ITEM:
                long newCategoryId = db.insert("Category", null, values);
                uriReturn = Uri.parse("content://" + AUTHORITY + "/category/" + newCategoryId);
                break;
            default:
                break;
        }
        return uriReturn;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        // 更新資料
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int updatedRows = 0;
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
                updatedRows = db.update("Book", values, selection, selectionArgs);
                break;
            case BOOK_ITEM:
                String bookId = uri.getPathSegments().get(1);
                updatedRows = db.update("Book", values, "id = ?", new String[] { bookId });
                break;
            case CATEGORY_DIR:
                updatedRows = db.update("Category", values, selection, selectionArgs);
                break;
            case CATEGORY_ITEM:
                String categoryId = uri.getPathSegments().get(1);
                updatedRows = db.update("Category", values, "id = ?", new String[] { categoryId });
                break;
            default:
                break;
        }
        return updatedRows;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // 刪除資料
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int deletedRows = 0;
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
                deletedRows = db.delete("Book", selection, selectionArgs);
                break;
            case BOOK_ITEM:
                String bookId = uri.getPathSegments().get(1);
                deletedRows = db.delete("Book", "id = ?", new String[] { bookId });
                break;
            case CATEGORY_DIR:
                deletedRows = db.delete("Category", selection, selectionArgs);
                break;
            case CATEGORY_ITEM:
                String categoryId = uri.getPathSegments().get(1);
                deletedRows = db.delete("Category", "id = ?", new String[] { categoryId });
                break;
            default:
                break;
        }
        return deletedRows;
    }

    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
                return "vnd.android.cursor.dir/vnd.com.example.databasetest. provider.book";
            case BOOK_ITEM:
                return "vnd.android.cursor.item/vnd.com.example.databasetest. provider.book";
            case CATEGORY_DIR:
                return "vnd.android.cursor.dir/vnd.com.example.databasetest. provider.category";
            case CATEGORY_ITEM:
                return "vnd.android.cursor.item/vnd.com.example.databasetest. provider.category";
        }
        return null;
    }

}