Android 四大組件--ContentProvider

URI

通用資源標志符(Universal Resource Identifier, 簡稱"URI")。
Uri代表要操作的數(shù)據(jù),Android上可用的每種資源 - 圖像、視頻片段等都可以用Uri來表示。
URI一般由三部分組成:
訪問資源的命名機制。
存放資源的主機名。
資源自身的名稱,由路徑表示。

Android的Uri由以下三部分組成: "content://"、數(shù)據(jù)的路徑、標示ID(可選)
eg:所有聯(lián)系人的Uri: content://contacts/people

UriMatcher

UriMatcher 類主要用于匹配Uri.

使用方法

        //初始化
        UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);

        //注冊需要的Uri:
        matcher.addURI("com.study.hdq.componentdemo", "people", PEOPLE);
        matcher.addURI("com.study.hdq.componentdemo", "person/#", PEOPLE_ID);

        //與已經(jīng)注冊的Uri進行匹配
        Uri uri = Uri.parse("content://" + "com.study.hdq.componentdemo" + "/people");
        int match = matcher.match(uri);

        switch (match)

        {
            case PEOPLE:

                return "vnd.android.cursor.dir/people";

            case PEOPLE_ID:

                return "vnd.android.cursor.item/people";

            default:

                return null;

        }

--常量 UriMatcher.NO_MATCH
表示不匹配任何路徑的返回碼
--# 號為通配符
--* 號為任意字符

ContentProvider

ContentProvider是android四大組件之一的內(nèi)容提供器,它主要的作用就是將程序的內(nèi)部的數(shù)據(jù)和外部進行共享,為數(shù)據(jù)提供外部訪問接口,被訪問的數(shù)據(jù)主要以數(shù)據(jù)庫的形式存在,而且還可以選擇共享哪一部分的數(shù)據(jù)。這樣一來,對于程序當中的隱私數(shù)據(jù)可以不共享,從而更加安全。contentprovider是android中一種跨程序共享數(shù)據(jù)的重要組件。

利用系統(tǒng)的ContentProvider讀取聯(lián)系人信息

  Cursor cursor=cr.query(Uri.parse("content://com.android.contacts/raw_contacts"),null,null,null,null);
        while(cursor.moveToNext()){
            Map<String,Object> map=new HashMap<String,Object>();
            int id=cursor.getInt(cursor.getColumnIndex("_id"));
            String displayName=cursor.getString(cursor.getColumnIndex("display_name"));
            Log.i("test",id+" "+displayName);
            map.put("names",displayName);

            //根據(jù)聯(lián)系人獲取聯(lián)系人數(shù)據(jù)
            Cursor cursor2=cr.query(Uri.parse("content://com.android.contacts/raw_contacts/"+id+"/data"),null,null,null,null);
            while(cursor2.moveToNext()){
                //  int type=cursor2.getInt(cursor2.getColumnIndex("mimetype_id"));
                String type=cursor2.getString(cursor2.getColumnIndex("mimetype"));
                String data1=null;
                if ("vnd.android.cursor.item/phone_v2".equals(type)){
                    data1 = cursor2.getString(cursor2.getColumnIndex("data1"));
                    Log.i("test","   "+type+" "+data1);
                    map.put("phones",data1);
                }
            }
            data.add(map);
        }

        Log.e(TAG,"names:"+data.get(0).get("names").toString()+"  phones:"+data.get(0).get("phones").toString());

輸出

com.study.hdq.componentdemo E/MainActivity: names:華為客服  phones:4008308300

自定義ContentProvider

創(chuàng)建MyContentProvider繼承ContentProvider

public class MyContentProvider extends ContentProvider {

    /**
     * 初始化你的provider。Android系統(tǒng)在創(chuàng)建你的provider之后立即調(diào)用此方法。注意你的Provider直到一個ContentResolver對象要操作它時才會被創(chuàng)建。
     */
    @Override
    public boolean onCreate() {
        return false;
    }

    /**
     * 從你的provider獲取數(shù)據(jù)。使用參數(shù)來指定要查詢的表,要返回行和列,和結(jié)果的排序方式。返回一個 Cursor 對象
     */

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        return null;
    }

    /**
     * 返回對應(yīng)一個content URI的MIME類型。
     */
    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        return null;
    }

    /**
     * 向你的provider插入一個新行。參數(shù)們指定了要選擇的表和要插入的列的值。返回一個指向新行的content URI。
     *
     */
    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        return null;
    }

    /**
     * 從你的provider中刪除行。參數(shù)們指定了要選擇是表和要刪除的行們。返回刪除打的行的數(shù)量。
     *
     */
    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        return 0;
    }

    /**
     * 更新你的provider中已存在的行。參數(shù)中指定了要選擇的表和要更新的行以及要更新的列數(shù)據(jù)。返回更新的行的數(shù)量。
     *
     */
    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
        return 0;
    }
}

在清單文件中注冊

     <provider
            android:name=".MyContentProvider"
            android:authorities="com.study.hdq.componentdemo.MyContentProvider"
            android:exported="true" />
  • name:ContentProvider的全稱類名
  • authorities:唯一標識了一個ContentProvider,外部應(yīng)用通過該屬性值來訪問我們的ContentProvider。因此該屬性值必須是唯一的,建議在命名時以包名為前綴
  • exported:表明是否允許其他應(yīng)用調(diào)用ContentProvider,true表示支持,false表示不支持。默認值根據(jù)開發(fā)者的屬性設(shè)置而會有所不同,如果包含 Intent-Filter 則默認值為true,否則為false
    使用 UriMatcher
 public static final String AUTHORITY = "om.study.hdq.componentdemo.MyContentProvider";

    public static final int STUDENT_URI_CODE = 0;

    public static final int STUDENT_URI_CODE_ITEM = 1;

    private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    static {
        uriMatcher.addURI(AUTHORITY, "student", STUDENT_URI_CODE);
        uriMatcher.addURI(AUTHORITY, "student/#", STUDENT_URI_CODE_ITEM);
    }

以 query( ) 方法為例示范(insert()、update()、delete() 實現(xiàn)類似)

 @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        switch (uriMatcher.match(uri)) {
            case STUDENT_URI_CODE:
                // 查詢student表中的所有數(shù)據(jù)
                break;

            case STUDENT_URI_CODE_ITEM:
                // 查詢student表中的單條數(shù)據(jù)
                break;


            default:
                break;
        }
        return null;
    }

getType()

 @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        switch (uriMatcher.match(uri)) {
            case STUDENT_URI_CODE:
                return "vnd.android.cursor.dir/vnd."+AUTHORITY+".student";
            case STUDENT_URI_CODE_ITEM:
                return "vnd.android.cursor.item/vnd."+AUTHORITY+".student";
            default:
                break;
        }

        return null;
    }

除此之外,還有一個方法你會比較陌生,即 getType() 方法。它是所有的內(nèi)容提供器都必 須提供的一個方法,用于獲取 Uri 對象所對應(yīng)的 MIME 類型。一個內(nèi)容 URI 所對應(yīng)的 MIME 字符串主要由三部分組分,Android 對這三個部分做了如下格式規(guī)定。
1.必須以 vnd 開頭。
2.如果內(nèi)容 URI 以路徑結(jié)尾,則后接 android.cursor.dir/,如果內(nèi)容 URI 以 id 結(jié)尾, 則后接 android.cursor.item/。
3.最后接上 vnd.<authority>.<path>。

ContentResolver

對于每一個應(yīng)用程序來說,如果想要訪問內(nèi)容提供器中的共享數(shù)據(jù),就一定要借助ContentResolver類,可以通過Context中的getContentResolver()方法獲取到該類的實例,ContentResolver中提供了一系列的方法用于對數(shù)據(jù)進行CRUD
操作.其中insert()方法用于添加數(shù)據(jù),update()方法用于更新數(shù)據(jù),delete()方法用于刪除數(shù)據(jù),query()方法用于查詢數(shù)據(jù)

使用

Cursor cursor = getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder);
//uri from table_name 指定查詢某個應(yīng)用程序下的某一張表
//例如: Uri uri = Uri.parse("content://om.study.hdq.componentdemo.MyContentProvider/student");
//projection select column1,column2 指定查詢的列名
//selection where column = value 指定where的約束條件
//selectionArgs - 為where中的占位符提供具體的值
//orderBy order by column1,column2 指定查詢結(jié)果的排序方式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容