Android 四大组件--ContentProvider

URI

通用资源标志符(Universal Resource Identifier, 简称"URI")。
Uri代表要操作的数据,Android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示。
URI一般由三部分组成:
访问资源的命名机制。
存放资源的主机名。
资源自身的名称,由路径表示。

Android的Uri由以下三部分组成: "content://"、数据的路径、标示ID(可选)
eg:所有联系人的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);

        //与已经注册的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四大组件之一的内容提供器,它主要的作用就是将程序的内部的数据和外部进行共享,为数据提供外部访问接口,被访问的数据主要以数据库的形式存在,而且还可以选择共享哪一部分的数据。这样一来,对于程序当中的隐私数据可以不共享,从而更加安全。contentprovider是android中一种跨程序共享数据的重要组件。

利用系统的ContentProvider读取联系人信息

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

            //根据联系人获取联系人数据
            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

创建MyContentProvider继承ContentProvider

public class MyContentProvider extends ContentProvider {

    /**
     * 初始化你的provider。Android系统在创建你的provider之后立即调用此方法。注意你的Provider直到一个ContentResolver对象要操作它时才会被创建。
     */
    @Override
    public boolean onCreate() {
        return false;
    }

    /**
     * 从你的provider获取数据。使用参数来指定要查询的表,要返回行和列,和结果的排序方式。返回一个 Cursor 对象
     */

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

    /**
     * 返回对应一个content URI的MIME类型。
     */
    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        return null;
    }

    /**
     * 向你的provider插入一个新行。参数们指定了要选择的表和要插入的列的值。返回一个指向新行的content URI。
     *
     */
    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        return null;
    }

    /**
     * 从你的provider中删除行。参数们指定了要选择是表和要删除的行们。返回删除打的行的数量。
     *
     */
    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        return 0;
    }

    /**
     * 更新你的provider中已存在的行。参数中指定了要选择的表和要更新的行以及要更新的列数据。返回更新的行的数量。
     *
     */
    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
        return 0;
    }
}

在清单文件中注册

     
  • name:ContentProvider的全称类名
  • authorities:唯一标识了一个ContentProvider,外部应用通过该属性值来访问我们的ContentProvider。因此该属性值必须是唯一的,建议在命名时以包名为前缀
  • exported:表明是否允许其他应用调用ContentProvider,true表示支持,false表示不支持。默认值根据开发者的属性设置而会有所不同,如果包含 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() 实现类似)

 @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表中的所有数据
                break;

            case STUDENT_URI_CODE_ITEM:
                // 查询student表中的单条数据
                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() 方法。它是所有的内容提供器都必 须提供的一个方法,用于获取 Uri 对象所对应的 MIME 类型。一个内容 URI 所对应的 MIME 字符串主要由三部分组分,Android 对这三个部分做了如下格式规定。
1.必须以 vnd 开头。
2.如果内容 URI 以路径结尾,则后接 android.cursor.dir/,如果内容 URI 以 id 结尾, 则后接 android.cursor.item/。
3.最后接上 vnd..

ContentResolver

对于每一个应用程序来说,如果想要访问内容提供器中的共享数据,就一定要借助ContentResolver类,可以通过Context中的getContentResolver()方法获取到该类的实例,ContentResolver中提供了一系列的方法用于对数据进行CRUD
操作.其中insert()方法用于添加数据,update()方法用于更新数据,delete()方法用于删除数据,query()方法用于查询数据

使用

Cursor cursor = getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder);
//uri from table_name 指定查询某个应用程序下的某一张表
//例如: 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 指定查询结果的排序方式

你可能感兴趣的:(Android 四大组件--ContentProvider)