浅谈Android Content Provider的使用

小小于蓝

小小于蓝

2016-02-19 10:09

今天图老师小编要跟大家分享浅谈Android Content Provider的使用,精心挑选的过程简单易学,喜欢的朋友一起来学习吧!

Content Provider:一个组件,必须放在应用的主包或应用的子包之下;

组件的配置需要在清单文件中进行配置;content provider需要在application节点中进行配置;
内容提供者在应用中的作用是对外共享数据(任意类型的数据)使用的,别的程序可以对数据进行CRUD,如通讯录;
如果采用文件的方式对外共享数据,会因为文件的类型不同而需要使用不同的api访问方式导致访问繁杂,而内容提供者提供了统一的api对数据进行操作;
provider
  android:name=".PersonProvider"!-- 内容提供者类的名称 --
  android:authorities="cn.wordtech.providers.personprovider"

  android:exported="false" !-- 解决 android Permission Denial error!,在监听内容提供者数据发生变化时需要配置此项 --
/provider

另:  
android:authorities:为内容提供者指定一个唯一的标识,这样别的应用才可以唯一获取此provider;

Uri 代表了要操作的数据;
Uri主要包含两部分的信息:1需要操作的ContentProvider,2对ContentProvider中的什么数据进行操作

ContentProvider(内容提供者)的scheme已经由Android所规定,scheme为:content://
主机名(或Authority)用于唯一标识这个ContentProvider,外部调用者可以根据此标识来找到它,
路径(path)可以用来表示我们要操作的数据,路径的构建根据业务而定。
ex:
要操作person表中id为10的记录,可以构建这样的路径:/person/10
要操作person表中id为10的记录的name字段,可以构建这样的路径:/person/10/name
要操作person表中的所有记录,可以构建这样的路径:/person
要操作XXX表中的记录,可以构建这样的路径:/XXX
要操作的数据不一定是数据库中的文件,也可以是文件,xml或网络等其它方式
ex:
要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
代码如下:

public class PersonProvider extends ContentProvider {// Content Provider需要继承自ContentProvider类
 // 删改查中,都有两种情况:
 // person 对整个表进行操作
 // person/id 对表中的与id对应记录进行操作
 private DBOpenHelper dbOpenHelper;
 private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);// new UriMatcher(code);code即为匹配不成功时返回的值;
 private static final int PERSONS = 1;
 private static final int PERSON = 2;
 // 设置匹配项
 static {
  MATCHER.addURI("cn.wordtech.providers.personprovider", "person",PERSONS);
  MATCHER.addURI("cn.wordtech.providers.personprovider", "person/#",PERSON);// #号表示数字
 }
 // content://cn.wordtech.providers.personprovider/person
 @Override
 public boolean onCreate() {
  // 由系统调用,当ContentProvider的实例被创建出来的时候被调用,Android开机后,当第一次有应用访问ContentProvider时才创建ContentProvider;
  dbOpenHelper = new DBOpenHelper(getContext(), 1);
  return false;
 }

 // 可以供外部的应用查询数据,返回查询得到的游标对象
 @Override
 public Cursor query(Uri uri, String[] projection, String selection,
   String[] selectionArgs, String sortOrder) {
  SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
  switch (MATCHER.match(uri)) {
  case 1:
   return db.query("person", projection, selection, selectionArgs,
     null, null, sortOrder);
  case 2:
   long rowid = ContentUris.parseId(uri);// 返回要操作的id
   String where = "personid=" + rowid;
   if (selection != null && !"".equals(selection.trim())) {
    where += "and" + selection;
   }
   return db.query("person", projection, where, selectionArgs, null,
     null, sortOrder);

  default:
   throw new IllegalArgumentException("");
  }
 }

 // 此方法用于返回目前Uri所代表的数据的MIME类型,
 // 如果操作的数据属于集合类型,则MIME字符串就以"vnd.android.cursor.dir"开头
 // 如果操作的数据属于非集合类型,则MIME字符串就以"vnd.android.cursor.item"开头
 @Override
 public String getType(Uri uri) {
  switch (MATCHER.match(uri)) {
  case 1:
   return "vnd.android.cursor.dir/person";
  case 2:
   return "vnd.android.cursor.item/person";
  default:
   throw new IllegalArgumentException("");
  }
 }

 // 此方法需要返回操作记录对应的Uri
 @Override
 public Uri insert(Uri uri, ContentValues values) {
  SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
  switch (MATCHER.match(uri)) {
  case 1:
   long rowid = db.insert("person", "", values);// 返回行号?主键值
   // Uri insertUri = Uri
   // .parse("content://com.sqlite.PersonProvider/person/"
   // + rowid);
   Uri insertUri = ContentUris.withAppendedId(uri, rowid);
   return insertUri;
  default:
   throw new IllegalArgumentException("this is Unknow Uri:" + uri);
  }

 }

 // 返回受影响的行数
 @Override
 public int delete(Uri uri, String selection, String[] selectionArgs) {
  SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
  int num = 0;
  switch (MATCHER.match(uri)) {
  case 1:
   num = db.delete("person", selection, selectionArgs);// 清空整个表
   break;
  case 2:
   long rowid = ContentUris.parseId(uri);// 返回要操作的id
   String where = "personid=" + rowid;
   if (selection != null && !"".equals(selection.trim())) {
    where += "and" + selection;
   }
   num = db.delete("person", where, selectionArgs);
   break;
  default:
   throw new IllegalArgumentException("");
  }
  return num;
 }

 @Override // 返回受影响的行数
 public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {
  SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
  int num = 0;
  switch (MATCHER.match(uri)) {
  case 1:
   num = db.update("person", values, selection, selectionArgs);
   break;
  case 2:
   long rowid = ContentUris.parseId(uri);// 返回要操作的id
   String where = "personid=" + rowid;
   if (selection != null && !"".equals(selection.trim())) {
    where += "and" + selection;
   }
   num = db.update("person", values, where, selectionArgs);
   break;
  default:
   throw new IllegalArgumentException("");
  }
  return num;
 }


下面是对前一个类进行测试
代码如下:

public class AccessContentProviderTest extends AndroidTestCase {
 public void testinsert() {
  Uri uri = Uri.parse("content://cn.wordtech.providers.personprovider/person");// 根据标识名得到内容提供者
  ContentResolver cr = this.getContext().getContentResolver(); // This class provides applications access to the content model
  ContentValues values = new ContentValues();
  values.put("name", "Livingstone");
  values.put("phone", "110");
  values.put("amount", "1111111111");
  cr.insert(uri, values);// 在cr的内部会调用内容提供者的值;
 }

 public void testdelete() {
  Uri uri = Uri.parse("content://cn.wordtech.providers.personprovider/person/1");// 根据标识名得到内容提供者
  ContentResolver cr = this.getContext().getContentResolver();
  cr.delete(uri, null, null);
 }

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

 public void testupdate() {
  Uri uri = Uri.parse("content://cn.wordtech.providers.personprovider/person/2");// 根据标识名得到内容提供者
  ContentResolver cr = this.getContext().getContentResolver();
  ContentValues values = new ContentValues();
  values.put("name", "Livingstone11");
  cr.update(uri, values, null, null);
 }

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

 public void testquery() {
  Uri uri = Uri.parse("content://cn.wordtech.providers.personprovider/person");// 根据标识名得到内容提供者
  ContentResolver cr = this.getContext().getContentResolver();
  Cursor cursor = cr.query(uri, null, null, null, "personid asc");
  while (cursor.moveToNext()) {
   String name = cursor.getString(cursor.getColumnIndex("name"));
   Log.i("Name", name);
  }
 }
}

展开更多 50%)
分享

猜你喜欢

浅谈Android Content Provider的使用

编程语言 网络编程
浅谈Android Content Provider的使用

Android SharedPreferences的使用分析

编程语言 网络编程
Android SharedPreferences的使用分析

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Content-type 的说明

Web开发
Content-type 的说明

浅谈设计师必看的Android设计指南

平面设计 海报设计 广告设计 画报设计 签名设计 服装设计 名片设计 画册设计 版式设计 商标设计
浅谈设计师必看的Android设计指南

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

android中处理各种触摸事件的方法浅谈

编程语言 网络编程
android中处理各种触摸事件的方法浅谈

基于Android LayoutInflater的使用介绍

编程语言 网络编程
基于Android LayoutInflater的使用介绍

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

Android中关于Notification及NotificationManger的详解

Android中关于Notification及NotificationManger的详解

在win0系统中使用Edge浏览器浏览网页时出现绿屏怎么办?

在win0系统中使用Edge浏览器浏览网页时出现绿屏怎么办?
下拉加载更多内容 ↓