Android 四大组件之ContentProvider

 在Android官方指出的Android的数据存储方式总共有五种,分别是:Shared Preferences、网络存储、文件存储、外储存储、SQLite。接下来,我们讲解一下如何使用ContentProvider

 

一 URI

  由于ContentProvider的使用,是以URI为标识的,所以,我们先学习一下URI的概念。

  Uri代表了要操作的数据,Uri主要包含了两部分信息:1.需要操作的ContentProvider ,2.对ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成:
       1.scheme:ContentProvider(内容提供者)的scheme已经由Android所规定为:content://。
       2.主机名(或Authority):用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
       3.路径(path):可以用来表示我们要操作的数据,路径的构建应根据业务而定。

 

   如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://cn.tyssen.provider.contactprovider/contact")

 

   因为Uri代表了要操作的数据,所以我们很经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。掌握它们的使用,会便于我们的开发工作。

 

 (1).UriMatcher

UriMatcher用于匹配Uri,它的用法如下:
   1.首先把你需要匹配Uri路径全部给注册上,如下:
  //常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码(-1)。
   UriMatcher  uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
   //如果match()方法匹配content://cn.tyssen.sqlite.provider.contactprovider/contact路径,返回匹配码为1.
    uriMatcher.addURI(“cn.tyssen.sqlite.provider.contactprovider”, “contact”, 1);//添加需要匹配uri,如果匹配就会返回匹配码1.

 

   注册完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数,假设匹配content://cn.tyssen.sqlite.provider.contactprovider/contact路径,返回的匹配码为1.

 

•要操作contact表中id为10的记录,可以构建这样的路径:/contact/10
•要操作contact表中id为10的记录的name字段, contact/10/name
•要操作contact表中的所有记录,可以构建这样的路径:/contact

 

     (2).ContentUris

ContentUris用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
•  withAppendedId(uri, id)用于为路径加上ID部分
•  parseId(uri)方法用于从路径中获取ID部分

 

     (3).ContentResolver

ContentResolver当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver使用insert、delete、update、query方法,来操作数据。

二 ContentProvider实例

创建一个Myprovider.java对数据库的接口进行包装:

public class MyProvider extends ContentProvider{

 

        DBlite dBlite;

        SQLiteDatabase db;

         

        private static final UriMatcher sMatcher;

        static{

                sMatcher = new UriMatcher(UriMatcher.NO_MATCH);

                sMatcher.addURI(RuiXin.AUTOHORITY,RuiXin.TNAME, RuiXin.ITEM);

                sMatcher.addURI(RuiXin.AUTOHORITY, RuiXin.TNAME+"/#", RuiXin.ITEM_ID);

 

        }

        @Override

        public int delete(Uri uri, String selection, String[] selectionArgs) {

                // TODO Auto-generated method stub

                db = dBlite.getWritableDatabase();

                int count = 0;

                switch (sMatcher.match(uri)) {

                case RuiXin.ITEM:

                        count = db.delete(RuiXin.TNAME,selection, selectionArgs);

                        break;

                case RuiXin.ITEM_ID:

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

                        count = db.delete(RuiXin.TID, RuiXin.TID+"="+id+(!TextUtils.isEmpty(RuiXin.TID="?")?"AND("+selection+')':""), selectionArgs);

                    break;

                default:

                        throw new IllegalArgumentException("Unknown URI"+uri);

                }

                getContext().getContentResolver().notifyChange(uri, null);

                return count;

        }

 

        @Override

        public String getType(Uri uri) {

                // TODO Auto-generated method stub

                switch (sMatcher.match(uri)) {

                case RuiXin.ITEM:

                        return RuiXin.CONTENT_TYPE;

                case RuiXin.ITEM_ID:

                    return RuiXin.CONTENT_ITEM_TYPE;

                default:

                        throw new IllegalArgumentException("Unknown URI"+uri);

                }

        }

 

        @Override

        public Uri insert(Uri uri, ContentValues values) {

                // TODO Auto-generated method stub

                 

                db = dBlite.getWritableDatabase();

                long rowId;

                if(sMatcher.match(uri)!=RuiXin.ITEM){

                        throw new IllegalArgumentException("Unknown URI"+uri);

                }

                rowId = db.insert(RuiXin.TNAME,RuiXin.TID,values);

                   if(rowId>0){

                           Uri noteUri=ContentUris.withAppendedId(RuiXin.CONTENT_URI, rowId);

                           getContext().getContentResolver().notifyChange(noteUri, null);

                           return noteUri;

                   }

                   throw new IllegalArgumentException("Unknown URI"+uri);

        }

 

        @Override

        public boolean onCreate() {

                // TODO Auto-generated method stub

                this.dBlite = new DBlite(this.getContext());

//                db = dBlite.getWritableDatabase();

//                return (db == null)?false:true;

                return true;

        }

 

        @Override

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

                        String[] selectionArgs, String sortOrder) {

                // TODO Auto-generated method stub

                db = dBlite.getWritableDatabase();                

                Cursor c;

                Log.d("-------", String.valueOf(sMatcher.match(uri)));

                switch (sMatcher.match(uri)) {

                case RuiXin.ITEM:

                        c = db.query(RuiXin.TNAME, projection, selection, selectionArgs, nullnullnull);

                 

                        break;

                case RuiXin.ITEM_ID:

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

                        c = db.query(RuiXin.TNAME, projection, RuiXin.TID+"="+id+(!TextUtils.isEmpty(selection)?"AND("+selection+')':""),selectionArgs, nullnull, sortOrder);

                    break;

                default:

                        Log.d("!!!!!!""Unknown URI"+uri);

                        throw new IllegalArgumentException("Unknown URI"+uri);

                }

                c.setNotificationUri(getContext().getContentResolver(), uri);

                return c;

        }

        @Override

        public int update(Uri uri, ContentValues values, String selection,

                        String[] selectionArgs) {

                // TODO Auto-generated method stub

                return 0;

        }

}

 

   如果ContentProvider的访问者需要知道ContentProvider中的数据发生变化,可以在ContentProvider发生数据变化时调用getContentResolver().notifyChange(uri, null)来通知注册在此URI上的访问者。

如果ContentProvider的访问者需要得到数据变化通知,必须使用ContentObserver对数据(数据采用uri描述)进行监听,当监听到数据变化通知时,系统就会调用ContentObserver的onChange()方法:

getContentResolver().registerContentObserver(Uri.parse("content://com.ljq.providers.personprovider/person"),

       truenew PersonObserver(new Handler()));

public class PersonObserver extends ContentObserver{

 

   public PersonObserver(Handler handler) {

      super(handler);

   }

   public void onChange(boolean selfChange) {

      //此处可以进行相应的业务处理

   }

}

 

另外ContentProvider不要忘记在Manifest里面注册哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值