美文网首页1103安卓自学成功纪
20170104第一行代码第七章Content Provider

20170104第一行代码第七章Content Provider

作者: 在你左右2018 | 来源:发表于2017-01-04 16:02 被阅读98次

    一、简介

    Content Provider用法有两种:

    1、使用现有的CP来读取和操作相应程序中的数据;比如系统电话本。

    2、创建自己的CP给我们的程序数据提供外部访问的接口。

    二、访问已有的CP

    当一个APP通过CP对其数据提供了外部的访问接口,则其他任何程序都可以通过这个接口对数据进行访问和操作。

    1、ContentResolver用法

    任何程序如果想访问其他程序通过CP共享的数据,都要使用ContentResolver,通过Context的getContentResolver()方法获取。

    CR不接受表名,只接收内容URI。

    URI:给CP中的数据建立了一个唯一的标识符,通过URI就可以访问该数据。

    URI包含两个部分:权限authority+路径path。

    权限authority:为了区分不同的程序,一般用该程序的包名做权限,com.example.app.provider

    路径path:为了区分同一个APP中不同的表名。

    URI标准格式为:content://com.example.app.provider/table1

    其中,com.example.app为提供CP的程序包名;table1为数据所在表名。

    使用方法:

    ContentResolver cr=getContentResolver();

    //查询数据

    Cursor cursor=cr.query(uri, column1, “column1=? and column2=?”, new String[] {“ ”,” ”});

    分别填入URI,查询的列名,查询的约束条件,占位符的值,最后还可以加上排序方式。

    //增加数据

    ContentValues values=new ContentValues();

    values.put(“column1”,”hello”);

    values.put(“column2”,”hujun”);

    cr.insert(uri, values);

    利用ContentValues将数据插入表。

    //修改数据

    ContentValues values=new ContentValues();

    values.put(“column1”,”data_changed”);

    cr.update(uri, values, “column1=? and column2=?”, new String[] {“ ”,” ”});

    分别填入URI,values,以及约束条件和占位符的值。

    //删除数据

    cr.delete(uri, “column1=?” , new String[] {“data”});

    删除列1中值为data的行。

    2、读取系统联系人

    手机联系人URI为:

    ContactsContract.CommonDataKinds.Phone.CONTENT_URI

    该数据中包括联系人姓名、号码,所在列名分别为:

    ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME

    ContactsContract.CommonDataKinds.Phone.NUMBER

    读取联系人信息,还需要获取权限

    android.permission.READ_CONTACTS

    读取代码为:

    public void init()

    {

    ContentResolver cr=getContentResolver();

    Cursor cursor=cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);

    if(cursor!=null)

    {

    while(cursor.moveToNext())

    {

    String name=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));

    String number=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

    contacts.add(name+"\n"+number);

    }}

    if(cursor!=null)cursor.close();

    }

    三、创建自己的ContentProvider

    1、创建CP步骤5部曲

    (1)首先,新建MyContentProvider类去继承ContentProvider,需要重写6个方法:

    onCreate():当存在ContentResolver尝试访问该CP时,自动调用onCreate()方法来初始化CP,通常在此完成数据库创建、升级等操作。

    insert()、query()、update()、delete()就是操作CP提供的数据时使用的方法。

    getType():根据传入的URI来返回相应的MIME类型?

    (2)然后,如何解析URI?

    UIR包括两种格式:

    content://com.example.app.provider/table1

    content://com.example.app.provider/table1/1

    第一种格式,以路径table1结尾,访问表table1中所有数据;

    第二种格式,在最后加上了id,即访问表table1中id为1的数据。

    以通配符形式表示:

    *:代表任意长度任意字符;

    #:代表任意长度任意数字。

    content://com.example.app.provider/*代表任意一个表

    content://com.example.app.provider/table1/#代表表table1中任意一行

    采用UriMatcher解析URI,

    首先,配置UriMatcher,利用addURI()方法,将权限,路径和自定义代码传入;

    然后,解析URI,利用match(uri)方法,如果该uri和之前addURI()写入的权限和路径相同时,返回自定义代码。

    最后,通过这个自定义代码,即可采取不同的操作。

    (3)重写query()等

    public class MyContentProvider extends ContentProvider{

    public static final int TABLE1_DIR=0;

    public static final int TABLE1_ITEM=1;

    public static final int TABLE2_DIR=2;

    public static final int TABLE2_ITEM=3;

    private static UriMatcher uriMatcher;

    static

    {

    uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);

    uriMatcher.addURI("com.example.contentprovider", "Book", TABLE1_DIR);

    uriMatcher.addURI("com.example.contentprovider", "Book/#", TABLE1_ITEM);

    uriMatcher.addURI("com.example.contentprovider", "Category", TABLE2_DIR);

    uriMatcher.addURI("com.example.contentprovider", "Category/#", TABLE2_ITEM);

    }

    public Cursor query(Uri uri, String[] projection, String selection,

    String[] selectionArgs, String sortOrder) {

    switch (uriMatcher.match(uri)) {

    case TABLE1_DIR:

    //查询Book中所有数据

    break;

    case TABLE1_ITEM:

    //查询Book中单条数据,根据id

    break;

    case TABLE2_DIR:

    //查询Category中单条数据

    break;

    case TABLE2_ITEM:

    //查询Book中单条数据,根据id

    break;

    default:

    break;

    }

    return null;

    }

    (4)重写getType()

    获取URI对象所对应的MIME类型。

    一个内容URI对应的MIME字符串包含3个部分:

    1、必须以vnd开头;

    2、如果内容URI以路径结尾,则后接android.cursor.dir/

    如果内容URI以id结尾,则后接android.cursor.item/

    3、最后接vnd..

    例如:

    URI:content://com.example.app.provider/table1

    MIMIE:vnd.android.cursor.dir/vnd.com.example.app.provider.table1

    URI:  content://com.example.app.provider/table1/1

    MIMIE:  vnd.android.cursor.item/vnd.com.example.app.provider.table1

    (5)在AndroidManifest.xml中注册

    android:name="com.example.contentprovider.MyContentProvider"

    android:authorities="com.example.contentprovider.provider"

    android:exported="true" >

    android:exported="true"表示该provider可以被其他程序访问。

    四、跨程序数据共享实践

    数据发送方,需要构建ContentProvider,将数据共享;共享的数据在CP类中onCreate()封装到数据库中。

    数据接收方,利用ContentResolver获取数据。

    附录:

    当URI中包含id,如何获取呢?

    String id=uri.getPathSegments().get(1);

    由此可见,路径获取方式为:String path=uri.getPathSegments().get(0);

    相关文章

      网友评论

        本文标题:20170104第一行代码第七章Content Provider

        本文链接:https://www.haomeiwen.com/subject/cpnovttx.html