Android 中自定义ContentProvider与ContentObserver的使用简单实例

Android 中自定义ContentProvider与ContentObserver的使用简单实例,第1张

概述Android中自定义ContentProvider与ContentObserver的使用简单实例示例说明:该示例中一共包含两个工程。其中一个工程完成了自定义ContentProvider,另外一个工程用于测试该自定义ContentProvider且在该工程中使用了

AndroID 中自定义ContentProvIDer与ContentObserver的使用简单实例

示例说明:

该示例中一共包含两个工程。其中一个工程完成了自定义ContentProvIDer,另外一个工程用于测试该自定义ContentProvIDer且在该工程中使用了ContentObserver监听自定义ContentProvIDer的数据变化

以下代码为工程TestContentProvIDer

ContentProvIDerTest如下:

package cn.testcontentprovIDer; import androID.content.ContentProvIDer; import androID.content.ContentUris; import androID.content.ContentValues; import androID.content.UriMatcher; import androID.database.Cursor; import androID.database.sqlite.sqliteDatabase; import androID.net.Uri; /**  * Demo描述:  * 自定义ContentProvIDer的实现  * ContentProvIDer主要用于在不同的应用程序之间共享数据,这也是官方推荐的方式.  *  * 注意事项:  * 1 在AndroIDManifest.xml中注册ContentProvIDer时的属性  *  androID:exported="true"表示允许其他应用访问.  * 2 注意*和#这两个符号在Uri中的作用  *  其中*表示匹配任意长度的字符  *  其中#表示匹配任意长度的数据  *  所以:  *  一个能匹配所有表的Uri可以写成:  *  content://cn.bs.testcontentprovIDer/*  *  一个能匹配person表中任意一行的Uri可以写成:  *  content://cn.bs.testcontentprovIDer/person/#  *   */ public class ContentProvIDerTest extends ContentProvIDer {   private sqliteDatabaSEOpenHelper msqliteDatabaSEOpenHelper;   private final static String AUTHORITY="cn.bs.testcontentprovIDer";   private static UriMatcher mUriMatcher;   private static final int PERSON_DIR = 0;   private static final int PERSON = 1;      /**    * 利用静态代码块初始化UriMatcher    * 在UriMatcher中包含了多个Uri,每个Uri代表一种 *** 作    * 当调用UriMatcher.match(Uri uri)方法时就会返回该uri对应的code;    * 比如此处的PERSONS和PERSON    */   static {     mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);     // 该URI表示返回所有的person,其中PERSONS为该特定Uri的标识码     mUriMatcher.addURI(AUTHORITY,"person",PERSON_DIR);     // 该URI表示返回某一个person,其中PERSON为该特定Uri的标识码     mUriMatcher.addURI(AUTHORITY,"person/#",PERSON);   }         /**    * 在自定义ContentProvIDer中必须覆写getType(Uri uri)方法.    * 该方法用于获取Uri对象所对应的MIME类型.    *    * 一个Uri对应的MIME字符串遵守以下三点:    * 1 必须以vnd开头    * 2 如果该Uri对应的数据可能包含多条记录,那么返回字符串应该以"vnd.androID.cursor.dir/"开头    * 3 如果该Uri对应的数据只包含一条记录,那么返回字符串应该以"vnd.androID.cursor.item/"开头    */   @OverrIDe   public String getType(Uri uri) {     switch (mUriMatcher.match(uri)) {     case PERSON_DIR:       return "vnd.androID.cursor.dir/"+AUTHORITY+".persons";     case PERSON:       return "vnd.androID.cursor.item/"+AUTHORITY+".person";     default:       throw new IllegalArgumentException("unkNown uri"+uri.toString());     }   }         @OverrIDe   public boolean onCreate() {     msqliteDatabaSEOpenHelper=new sqliteDatabaSEOpenHelper(getContext());     return true;   }       /**    * 插入 *** 作:    * 插入 *** 作只有一种可能:向一张表中插入    * 返回结果为新增记录对应的Uri    * 方法db.insert()返回结果为新增记录对应的主键值    */   @OverrIDe   public Uri insert(Uri uri,ContentValues values) {     sqliteDatabase db = msqliteDatabaSEOpenHelper.getWritableDatabase();     switch (mUriMatcher.match(uri)) {     case PERSON_DIR:       long newID = db.insert("person","name,phone,salary",values);       //向外界通知该ContentProvIDer里的数据发生了变化,以便ContentObserver作出相应        getContext().getContentResolver().notifyChange(uri,null);        return ContentUris.withAppendedID(uri,newID);     default:       throw new IllegalArgumentException("unkNown uri" + uri.toString());     }   }      /**    * 更新 *** 作:    * 更新 *** 作有两种可能:更新一张表或者更新某条数据    * 在更新某条数据时原理类似于查询某条数据,见下.    */   @OverrIDe   public int update(Uri uri,ContentValues values,String selection,String[] selectionArgs) {     sqliteDatabase db = msqliteDatabaSEOpenHelper.getWritableDatabase();     int updatednum = 0;     switch (mUriMatcher.match(uri)) {     // 更新表     case PERSON_DIR:       updatednum = db.update("person",values,selection,selectionArgs);       break;     // 按照ID更新某条数据     case PERSON:       long ID = ContentUris.parseID(uri);       String where = "personID=" + ID;       if (selection != null && !"".equals(selection.trim())) {         where = selection + " and " + where;       }       updatednum = db.update("person",where,selectionArgs);       break;     default:       throw new IllegalArgumentException("unkNown uri" + uri.toString());     }     //向外界通知该ContentProvIDer里的数据发生了变化,以便ContentObserver作出相应      getContext().getContentResolver().notifyChange(uri,null);      return updatednum;   }      /**    * 删除 *** 作:    * 删除 *** 作有两种可能:删除一张表或者删除某条数据    * 在删除某条数据时原理类似于查询某条数据,见下.    */   @OverrIDe   public int delete(Uri uri,String[] selectionArgs) {     sqliteDatabase db = msqliteDatabaSEOpenHelper.getWritableDatabase();     int deletednum = 0;     switch (mUriMatcher.match(uri)) {     // 删除表     case PERSON_DIR:       deletednum = db.delete("person",selectionArgs);       break;     // 按照ID删除某条数据     case PERSON:       long ID = ContentUris.parseID(uri);       String where = "personID=" + ID;       if (selection != null && !"".equals(selection.trim())) {         where = selection + " and " + where;       }       deletednum = db.delete("person",null);      return deletednum;   }    /**    * 查询 *** 作:    * 查询 *** 作有两种可能:查询一张表或者查询某条数据    *    * 注意事项:    * 在查询某条数据时要注意--因为此处是按照personID来查询    * 某条数据,但是同时可能还有其他限制.例如:    * 要求personID为2且name为xiaoming1    * 所以在查询时分为两步:    * 第一步:    * 解析出personID放入where查询条件    * 第二步:    * 判断是否有其他限制(如name),若有则将其组拼到where查询条件.    *    * 详细代码见下.    */   @OverrIDe   public Cursor query(Uri uri,String[] projection,String[] selectionArgs,String sortOrder) {     sqliteDatabase db = msqliteDatabaSEOpenHelper.getWritableDatabase();     Cursor cursor =null;     switch (mUriMatcher.match(uri)) {     // 查询表     case PERSON_DIR:       cursor = db.query("person",projection,selectionArgs,null,sortOrder);       break;     // 按照ID查询某条数据     case PERSON:       // 第一步:       long ID = ContentUris.parseID(uri);       String where = "personID=" + ID;       // 第二步:       if (selection != null && !"".equals(selection.trim())) {         where = selection + " and " + where;       }       cursor = db.query("person",sortOrder);       break;     default:       throw new IllegalArgumentException("unkNown uri" + uri.toString());     }     return cursor;   }     } 

sqliteDatabaSEOpenHelper如下:

package cn.testcontentprovIDer; import androID.content.Context; import androID.database.sqlite.sqliteDatabase; import androID.database.sqlite.sqliteOpenHelper; public class sqliteDatabaSEOpenHelper extends sqliteOpenHelper {   public sqliteDatabaSEOpenHelper(Context context) {     super(context,"contentprovIDertest.db",1);   }    @OverrIDe   public voID onCreate(sqliteDatabase db) {     db.execsql("create table person(personID integer primary key autoincrement,name varchar(20),phone varchar(12),salary Integer(12))");       }    //当数据库版本号发生变化时调用该方法   @OverrIDe   public voID onUpgrade(sqliteDatabase db,int arg1,int arg2) {     //db.execsql("ALTER table person ADD phone varchar(12) NulL");     //db.execsql("ALTER table person ADD salary Integer NulL");   }  } MainActivity如下:[java] vIEw plain copypackage cn.testcontentprovIDer; import androID.app.Activity; import androID.os.Bundle; public class MainActivity extends Activity {   @OverrIDe   protected voID onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentVIEw(R.layout.main);   }  } 

AndroIDManifest.xml如下:

<?xml version="1.0" enCoding="utf-8"?> <manifest xmlns:androID="http://schemas.androID.com/apk/res/androID"   package="cn.testcontentprovIDer"   androID:versionCode="1"   androID:versionname="1.0" >    <uses-sdk     androID:minSdkVersion="8"     androID:targetSdkVersion="8" />    <uses-permission androID:name="androID.permission.INTERNET" />   <uses-permission androID:name="androID.permission.ACCESS_NETWORK_STATE" />   <uses-permission androID:name="androID.permission.WRITE_EXTERNAL_STORAGE" />   <uses-permission androID:name="androID.permission.MOUNT_UNMOUNT_fileSYstemS" />      <application     androID:allowBackup="true"     androID:icon="@drawable/ic_launcher"     androID:label="@string/app_name"     androID:theme="@style/Apptheme" >     <activity       androID:name="cn.testcontentprovIDer.MainActivity"       androID:label="@string/app_name" >       <intent-filter>         <action androID:name="androID.intent.action.MAIN" />          <category androID:name="androID.intent.category.LAUNCHER" />       </intent-filter>     </activity>           <provIDer        androID:name="cn.testcontentprovIDer.ContentProvIDerTest"       androID:authoritIEs="cn.bs.testcontentprovIDer"       androID:exported="true"      />   </application>  </manifest> 

main.xml如下:

<relativeLayout    xmlns:androID="http://schemas.androID.com/apk/res/androID"   xmlns:tools="http://schemas.androID.com/tools"   androID:layout_wIDth="match_parent"   androID:layout_height="match_parent"   >     <button     androID:layout_wIDth="wrap_content"     androID:layout_height="wrap_content"     androID:text="该应用包含一个自定义的ContentProvIDer"     androID:textSize="15sp"    androID:layout_centerInParent="true"   />  </relativeLayout> 

以下代码为工程TestBaIDu

MainActivity如下:

package cn.testbaIDu; import androID.net.Uri; import androID.os.Bundle; import androID.os.Handler; import androID.vIEw.VIEw; import androID.vIEw.VIEw.OnClickListener; import androID.Widget.button; import androID.app.Activity; import androID.content.ContentResolver; import androID.content.ContentValues; import androID.database.ContentObserver; import androID.database.Cursor; /**  * Demo描述:  * 应用A(TestBaIDu)调用另外一个应用(TestContentProvIDer)中的自定义ContentProvIDer,即:  * 1 自定义ContentProvIDer的使用  * 2 其它应用调用该ContentProvIDer  * 3 ContentObserver的使用  *  * 备注说明:  * 1 该例子在以前版本的基础上整理了代码  * 2 该例子在以前版本的基础上融合了ContentObserver的使用  *  利用ContentObserver随时监听ContentProvIDer的数据变化.  *  为实现该功能需要在自定义的ContentProvIDer的insert(),update(),delete()  *  方法中调用getContext().getContentResolver().notifyChange(uri,null);  *  向外界通知该ContentProvIDer里的数据发生了变化,以便ContentObserver作出相应   *  * 测试方法:  * 1 依次测试ContentProvIDer的增查删改(注意该顺序)!!  * 2 其它应用查询该ContentProvIDer的数据  *  */ public class MainActivity extends Activity {   private button mAddbutton;   private button mDeletebutton;   private button mUpdatebutton;   private button mquerybutton;   private button mTypebutton;   private long lastTime=0;   private ContentResolver mContentResolver;   private ContentObserverSubClass mContentObserverSubClass;   @OverrIDe   protected voID onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentVIEw(R.layout.main);     init();     initContentObserver();   }    private voID init() {     mContentResolver=this.getContentResolver();          mAddbutton=(button) findVIEwByID(R.ID.addbutton);     mAddbutton.setonClickListener(new ClickListenerImpl());          mDeletebutton=(button) findVIEwByID(R.ID.deletebutton);     mDeletebutton.setonClickListener(new ClickListenerImpl());          mUpdatebutton=(button) findVIEwByID(R.ID.updatebutton);     mUpdatebutton.setonClickListener(new ClickListenerImpl());          mquerybutton=(button) findVIEwByID(R.ID.querybutton);     mquerybutton.setonClickListener(new ClickListenerImpl());          mTypebutton=(button) findVIEwByID(R.ID.typebutton);     mTypebutton.setonClickListener(new ClickListenerImpl());        }          // 注册一个针对ContentProvIDer的ContentObserver用来观察内容提供者的数据变化   private voID initContentObserver() {     Uri uri = Uri.parse("content://cn.bs.testcontentprovIDer/person");     mContentObserverSubClass=new ContentObserverSubClass(new Handler());     this.getContentResolver().registerContentObserver(uri,true,mContentObserverSubClass);   }      @OverrIDe   protected voID onDestroy() {     super.onDestroy();     if (mContentObserverSubClass!=null) {       this.getContentResolver().unregisterContentObserver(mContentObserverSubClass);     }   }             // 自定义一个内容观察者ContentObserver   private class ContentObserverSubClass extends ContentObserver {      public ContentObserverSubClass(Handler handler) {       super(handler);     }      //采用时间戳避免多次调用onChange( )     @OverrIDe     public voID onChange(boolean selfChange) {       super.onChange(selfChange);       System.out.println("ContentObserver onChange() selfChange="+ selfChange);       if (System.currentTimeMillis()-lastTime>2000) {         ContentResolver resolver = getContentResolver();         Uri uri = Uri.parse("content://cn.bs.testcontentprovIDer/person");         // 获取最新的一条数据         Cursor cursor = resolver.query(uri,"personID desc limit 1");         while (cursor.movetoNext()) {           int personID = cursor.getInt(cursor.getColumnIndex("personID"));           System.out.println("内容提供者中的数据发生变化,现数据中第一条数据的personID="+ personID);         }         cursor.close();         lastTime=System.currentTimeMillis();       }else{         System.out.println("时间间隔过短,忽略此次更新");       }                   }          @OverrIDe     public boolean deliverSelfNotifications() {       return true;     }        }                private class ClickListenerImpl implements OnClickListener {     @OverrIDe     public voID onClick(VIEw v) {       switch (v.getID()) {       case R.ID.addbutton:         Person person = null;         for (int i = 0; i < 5; i++) {           person = new Person("xiaoming" + i,"9527" + i,(8888 + i));           testInsert(person);         }         break;       case R.ID.deletebutton:         testDelete(1);         break;       case R.ID.updatebutton:         testUpdate(3);         break;       case R.ID.querybutton:         // 查询表         // queryFromContentProvIDer(-1);          // 查询personID=2的数据         testquery(2);         break;       case R.ID.typebutton:         testType();         break;       default:         break;       }      }    }   private voID testInsert(Person person) {     ContentValues contentValues=new ContentValues();     contentValues.put("name",person.getname());     contentValues.put("phone",person.getPhone());     contentValues.put("salary",person.getSalary());     Uri insertUri=Uri.parse("content://cn.bs.testcontentprovIDer/person");     Uri returnUri=mContentResolver.insert(insertUri,contentValues);     System.out.println("新增数据:returnUri="+returnUri);   }      private voID testDelete(int index){     Uri uri=Uri.parse("content://cn.bs.testcontentprovIDer/person/"+String.valueOf(index));     mContentResolver.delete(uri,null);   }      private voID testUpdate(int index){     Uri uri=Uri.parse("content://cn.bs.testcontentprovIDer/person/"+String.valueOf(index));     ContentValues values=new ContentValues();     values.put("name","hanmeimei");     values.put("phone","1234");     values.put("salary",333);     mContentResolver.update(uri,null);   }    private voID testquery(int index) {     Uri uri=null;     if (index<=0) {       //查询表       uri=Uri.parse("content://cn.bs.testcontentprovIDer/person");     } else {        //按照ID查询某条数据       uri=Uri.parse("content://cn.bs.testcontentprovIDer/person/"+String.valueOf(index));     }          //对应上面的:查询表     //Cursor cursor= mContentResolver.query(uri,null);          //对应上面的:查询personID=2的数据     //注意:因为name是varchar字段的,所以应该写作"name='xiaoming1'"     //   若写成"name=xiaoming1"查询时会报错     Cursor cursor= mContentResolver.query(uri,"name='xiaoming1'",null);          while(cursor.movetoNext()){       int personID=cursor.getInt(cursor.getColumnIndex("personID"));       String name=cursor.getString(cursor.getColumnIndex("name"));       String phone=cursor.getString(cursor.getColumnIndex("phone"));       int salary=cursor.getInt(cursor.getColumnIndex("salary"));       System.out.println("查询得到:personID=" + personID+",name="+name+",phone="+phone+",salary="+salary);     }     cursor.close();   }      private voID testType(){     Uri dirUri=Uri.parse("content://cn.bs.testcontentprovIDer/person");     String dirType=mContentResolver.getType(dirUri);     System.out.println("dirType:"+dirType);          Uri itemUri=Uri.parse("content://cn.bs.testcontentprovIDer/person/3");     String itemType=mContentResolver.getType(itemUri);     System.out.println("itemType:"+itemType);   }  } 

Person如下:

package cn.testbaIDu;  public class Person {   private Integer ID;   private String name;   private String phone;   private Integer salary;   public Person(String name,String phone,Integer salary) {     this.name = name;     this.phone = phone;     this.salary=salary;   }   public Person(Integer ID,String name,Integer salary) {     this.ID = ID;     this.name = name;     this.phone = phone;     this.salary=salary;   }   public Integer getID() {     return ID;   }   public voID setID(Integer ID) {     this.ID = ID;   }   public String getname() {     return name;   }   public voID setname(String name) {     this.name = name;   }   public String getPhone() {     return phone;   }   public voID setPhone(String phone) {     this.phone = phone;   }   public Integer getSalary() {     return salary;   }   public voID setSalary(Integer salary) {     this.salary = salary;   }   @OverrIDe   public String toString() {     return "Person [ID=" + ID + ",name=" + name + ",phone=" + phone+ ",salary=" + salary + "]";   }          } 

main.xml如下:

<relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"   xmlns:tools="http://schemas.androID.com/tools"   androID:layout_wIDth="match_parent"   androID:layout_height="match_parent" >    <button     androID:ID="@+ID/addbutton"     androID:layout_wIDth="wrap_content"     androID:layout_height="wrap_content"     androID:layout_centerHorizontal="true"     androID:layout_margintop="30dip"     androID:text="增加"     androID:textSize="20sp" />       <button     androID:ID="@+ID/querybutton"     androID:layout_wIDth="wrap_content"     androID:layout_height="wrap_content"     androID:layout_centerHorizontal="true"     androID:layout_margintop="30dip"      androID:layout_below="@ID/addbutton"     androID:text="查询"     androID:textSize="20sp" />       <button     androID:ID="@+ID/deletebutton"     androID:layout_wIDth="wrap_content"     androID:layout_height="wrap_content"     androID:layout_centerHorizontal="true"     androID:layout_margintop="30dip"     androID:layout_below="@ID/querybutton"     androID:text="删除"     androID:textSize="20sp" />    <button     androID:ID="@+ID/updatebutton"     androID:layout_wIDth="wrap_content"     androID:layout_height="wrap_content"     androID:layout_centerHorizontal="true"     androID:layout_margintop="30dip"      androID:layout_below="@ID/deletebutton"     androID:text="修改"     androID:textSize="20sp" />       <button     androID:ID="@+ID/typebutton"     androID:layout_wIDth="wrap_content"     androID:layout_height="wrap_content"     androID:layout_centerHorizontal="true"     androID:layout_margintop="30dip"      androID:layout_below="@ID/updatebutton"     androID:text="类型"     androID:textSize="20sp" />  </relativeLayout> 

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

总结

以上是内存溢出为你收集整理的Android 中自定义ContentProvider与ContentObserver的使用简单实例全部内容,希望文章能够帮你解决Android 中自定义ContentProvider与ContentObserver的使用简单实例所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1144577.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存