采用Content Provider(内容提供者)对外共享数据

(1)、内容提供者作为安卓系统中的一个重要组件,需要在清单文件中进行配置。

(2)、作用是对外共享数据使用,可以使用它将你应用中的数据对外进行数据共享,可以进行增删改查。

(3)、可以讲任意类型数据对外共享。

(4)、案例建立在原先数据库应用中,将person表中的数据对外进行共享,并对其进行增删改查。

(5)、如果采用文件操作模式对外进行共享,会因为文件的格式不同导致需要使用不同的API进行操作,例如xml文件需要使用PULL解析器,而使用内容提供者进行共享可以使用统一的访问方式。

(6)、作为组件,应该在应用主包下面新建类,并继承ContentProvider,取名为PersonProvider,并在AndroidMainfest.xml文件中配置组件。结点为provider ,name为.PersonProvider,authorities(为内容提供者提供唯一标识,又叫主机名),名为org.blair.providers.personprovider。

(7)、当类建立好了之后,我们发现这些自动生成的API中都有一个参数是URI格式的。那么需要了解什么是URI

(8)、URI:

Uri代表了要操作的数据,Uri主要包含了两部分信息:1》需要操作的ContentProvider ,2》对ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成:

ContentProvider(内容提供者)的scheme已经由Android所规定,scheme为:content://

主机名(或叫Authority)用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。

路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:

要操作person表中id为10的记录,可以构建这样的路径:/person/10

要操作person表中id为10的记录的name字段, person/10/name

要操作person表中的所有记录,可以构建这样的路径:/person

要操作xxx表中的记录,可以构建这样的路径:/xxx

当然要操作的数据不一定来自数据库,也可以是文件、xml或网络等其他存储方式,如下:

要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name

如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:

Uri uri =Uri.parse("content://cn.itcast.provider.personprovider/person")

(9)、首先允许外部应用添加数据。

(10)、接下来在其他应用中使用单元测试进行测试访问,使用以前的OtherTest项目,写一个测试类AccessContentProviderTest,首先需要启动内容提供者所在的应用,再运行测试方法。

(11)、运行后报错,原因是清单文件中的权限问题,应加入exported=”true”属性。


(12)、接下来完成删除方法、更新。查询

源代码:

public class PersonProvider extendsContentProvider {

    privateDBOpenHelper openHelper;

    privatestatic final UriMatcher MATCHER=new UriMatcher(UriMatcher.NO_MATCH);/*定义一个静态的matcher对象,需要传入一个int code,表示如果不匹配,返回一个默认值-1*/

    privatestatic final int PERSONS=1;//新增匹配码

    privatestatic final int PERSON=2;//删除匹配码

static{  //静态代码块设置

    MATCHER.addURI("org.blair.providers.personprovider","person", PERSONS);//向静态MATCHER中添加数据

    MATCHER.addURI("org.blair.providers.personprovider","person/#",PERSON);//#代表所有数字。*代表所有字符

}

    @Override

    publicboolean onCreate() {//此方法由系统调用,当内容提供者实例被创建时调用,只会调用一次,适合做数据的初始化操作

         openHelper=newDBOpenHelper(getContext());

         returntrue;

    }

 

    @Override

    publicCursor query(Uri uri, String[] projection, String selection,

             String[]selectionArgs, String sortOrder) {//可以供外部应用查询内容提供者中的数据

         SQLiteDatabasedb=openHelper.getWritableDatabase();

         intnum=0;

         switch(MATCHER.match(uri)) {

         case1:

             Cursorcursor1=db.query("person", projection, selection, selectionArgs, null,null, sortOrder);

             returncursor1;

         case2:

             longrowid=ContentUris.parseId(uri);//可以得到uri后面的数字

             StringwhereClause="persionid="+rowid;

             if(selection!=null&&!selection.trim().equals("")){

                  whereClause+="and "+selection;

             }

             Cursorcursor2=db.query("person", projection, whereClause, selectionArgs,null, null, sortOrder);

             returncursor2;

         default:

         thrownew IllegalArgumentException("这是一个未知的Uri:"+uri);

         }

    }

 

 

    @Override

    publicString getType(Uri uri) {//返回你目前要操作的数据的内容类型

         //TODO Auto-generated method stub

         returnnull;

    }

/**

 *ContentValues用于存放字段值

 */

    @Override

    publicUri insert(Uri uri, ContentValues values) {//供外部应用添加数据

         SQLiteDatabasedb=openHelper.getWritableDatabase();

         switch(MATCHER.match(uri)) {//对输入进来的uri内容进行判断

         case1:

             longrowid=db.insert("person", "name", values);//主键值,行号

             //content://org.blair.providers.personprovider/person/10

             UriinsertUri=Uri.parse("content://org.blair.providers.personprovider/person/"+rowid);

             /*

              * 方法2:Uri insertUri=ContentUris.withAppendedId(uri,rowid);

              */

             returninsertUri;

         default:

             thrownew IllegalArgumentException("这是一个未知的Uri:"+uri);

         }

    }

 

    @Override

    publicint delete(Uri uri, String selection, String[] selectionArgs) {//外部删除

         SQLiteDatabasedb=openHelper.getWritableDatabase();

         intnum=0;

         switch(MATCHER.match(uri)) {

         case1:

             num=db.delete("person",selection, selectionArgs);//删除所有数据

             break;

         case2:

             longrowid=ContentUris.parseId(uri);//可以得到uri后面的数字

             StringwhereClause="persionid="+rowid;

             if(selection!=null&&!selection.trim().equals("")){

                  whereClause+="and "+selection;

             }

             db.delete("person",whereClause, selectionArgs);

             break;

         default:

         thrownew IllegalArgumentException("这是一个未知的Uri:"+uri);

         }

         returnnum;

    }

 

    @Override

    publicint update(Uri uri, ContentValues values, String selection,

             String[]selectionArgs) {//外部更新

         SQLiteDatabasedb=openHelper.getWritableDatabase();

         intnum=0;

         switch(MATCHER.match(uri)) {

         case1:

             num=db.update("person",values, selection, selectionArgs);

             break;

         case2:

             longrowid=ContentUris.parseId(uri);//可以得到uri后面的数字

             StringwhereClause="persionid="+rowid;

             if(selection!=null&&!selection.trim().equals("")){

                  whereClause+="and "+selection;

             }

             db.update("person",values, whereClause, selectionArgs);

             break;

         default:

         thrownew IllegalArgumentException("这是一个未知的Uri:"+uri);

         }

         returnnum;

    }

 

}

 



测试方法:

public class AccessContentProviderextends AndroidTestCase {

    privatestatic final String TAG="AccessContentProvider";

    publicvoid testInsert() throws Exception{

         Uriuri=Uri.parse("content://org.blair.providers.personprovider/person");

         ContentResolverresolver=this.getContext().getContentResolver();//访问内容提供者

         ContentValuesvalues=new ContentValues();

         values.put("name","Nancy");

         values.put("phone","110254556");

         values.put("amount","1000000000");

         resolver.insert(uri,values);//返回值为Uri

    }

    publicvoid testDelete() throws Exception{

         Uriuri=Uri.parse("content://org.blair.providers.personprovider/person/26");

         ContentResolverresolver=this.getContext().getContentResolver();

         resolver.delete(uri,null, null);

    }

   

    publicvoid testUpdate() throws Exception{

         Uriuri=Uri.parse("content://org.blair.providers.personprovider/person/27");

         ContentResolverresolver=this.getContext().getContentResolver();

         ContentValuesvalues=new ContentValues();

         values.put("name","蜜雪薇琪");

         resolver.update(uri,values, null, null);

    }

    publicvoid testQuery() throws Exception{

         Uriuri=Uri.parse("content://org.blair.providers.personprovider/person");

         ContentResolverresolver=this.getContext().getContentResolver();

         Cursorcursor=resolver.query(uri, null, null, null, "persionid asc");

         while(cursor.moveToNext()){

             Stringname=cursor.getString(cursor.getColumnIndex("name"));

             Log.i(TAG,name);

         }

         cursor.close();

    }

 

}

(13)、返回对应内容类型

public StringgetType(Uri uri)

该方法用于返回当前Url所代表数据的MIME类型。如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,例如:要得到所有person记录的Uri为content://cn.itcast.provider.personprovider/person,那么返回的MIME类型字符串应该为:“vnd.android.cursor.dir/person”。如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,例如:得到id为10的person记录,Uri为content://cn.itcast.provider.personprovider/person/10,那么返回的MIME类型字符串应该为:“vnd.android.cursor.item/person”。

源代码:

@Override

    publicString getType(Uri uri) {//返回你目前要操作的数据的内容类型

         switch(MATCHER.match(uri)) {

         case1:

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

         case2:

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

         default:

             throw newIllegalArgumentException("这是一个未知的Uri:"+uri);

         }

    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SunnyyMoon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值