zoukankan      html  css  js  c++  java
  • android四大组件之ContentProvider

    1.ContentProvider简介

            ContentProvider向我们提供了我们在应用程序之前共享数据的一种机制,每一个应用程序都是运行在不同的应用程序的,

    数据和文件在不同应用程序之间达到数据的共享不是没有可能,而是显得比较复杂,而正好Android中的ContentProvider则达到了这一需求,

    比如有时候我们需要操作手机里的联系人,手机里的多媒体等一些信息

     如果需要共享数据给其他应用程序 需要实现ContentProvider抽象类 实现其中的一些方法

    2.通过以下例子详解实现过程

    通过实现SQLiteOpenHelper创建数据库的管理类 实现数据库文件,数据库表的创建

    这里假设创建了一张表

       role(id integer primary key,rolename text)

     public class MyDatabaseHelper extends SQLiteOpenHelper {
    /**
    * 数据库的操作类
    */
    public SQLiteDatabase sdb;
    /**
    * 第二个参数表示 创建或者打开的文件名称
    * @param context 当前窗口
    * @param name    数据库名称
    * @param factory
    * @param version 版本号
    */
    public MyDatabaseHelper(Context context, String name,
    CursorFactory factory, int version) {
           super(context, name, factory, version);
            //调用getWritableDatabase或者 getReadableDatabase获取数据库的操作对象
            sdb=this.getWritableDatabase();
    }
    /**
    * 创建表
    * 当数据表不存在时自动调用 onCreate方法创建表
    */
    @Override
    public void onCreate(SQLiteDatabase db) {
          db.execSQL("create table if not exists role(id integer primary key,rolename text)");
    }
    /**
    * 升级数据库
    * 重新安装app时 如果访问的是同一个数据库文件  构造方法传入的版本号 大于之前app设置的版本号
    * 就会自动调用这个方法进行升级
    */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub
         db.execSQL("drop table if  exists role");
         this.onCreate(db);
    }

    }

    创建数据提供类

    public class RoleProvider extends ContentProvider {
    private Context context=null;
    MyDatabaseHelper mdh=null;

    public RoleProvider(){
    }
    /**
    * 一般的uri的配置 是在AndroidManifest.xml 配置 内容如下:
    *   Uri构造格式如下:content://<AndroidManifest.xml配置的provider的authorities名字>/自定义内容(也就是path)
    *      ui.addURI(authorities名字, 自定义的内容, 匹配返回的代码)
    *      
    *   假设:
    *      ui.addURI(“com.example.content.RoleProvider”, “a”, 1);
    *      ui.addURI(“com.example.content.RoleProvider, “b”, 2);
    *      可以使用 #匹配数字  *匹配任意数字
    *   
    *   如果使用ContentResove传入的uri为 :content://com.example.content.RoleProvider/a
    *   使用   ui.match(uri)方法 返回addURI的第三个参数就是返回 1
    */
    static UriMatcher ui=new UriMatcher(UriMatcher.NO_MATCH);
    static{
            //这里调用的uri 就是  content://com.example.content.RoleProvider/id/任意数字
           ui.addURI(RoleProvider.class.getName(), "id/#", 1);//通过id来查询
           //这里调用的uri 就是  content://com.example.content.RoleProvider/roleName/zs  如果类型匹配  ui.match方法返回 第三个参数2 
           ui.addURI(RoleProvider.class.getName(), "roleName/*", 2);//通过名称来查询
    }
    @Override
    public boolean onCreate() {
          this.context=this.getContext();
          mdh=new MyDatabaseHelper(context, "test.db", null, 1);
          return true;
    }


    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
    String[] selectionArgs, String sortOrder) {
          selection=(TextUtils.isEmpty(selection)?"1=1 ":selection);
          if(projection==null){
               projection=new String[]{"id","rolename"};
         }
         if(ui.match(uri)==1){
               long id=ContentUris.parseId(uri);
               selection+=" and (id="+id+")";

         }else{
              int roleNameIdx=uri.toString().lastIndexOf("/");
              String valueString="";
             if(roleNameIdx<=uri.toString().length()){
                    valueString=uri.toString().substring(roleNameIdx+1);
             }
            selection+=" and (roleName like '%"+valueString+"%')";
         }
         return mdh.getWritableDatabase().query("role", projection, selection, selectionArgs, null, null, sortOrder);
    }
    /**
    * mini类型存在两个值
    *    vnd.android.cursor.item  对应单条记录, 
              vnd.android.cursor.dir    应多条记录
           android调用查询方法时 循环Cursor 如果是返回单挑的item  不需要再去检测是否存在其他的记录 可以
                             提高性能   
    */
    @Override
    public String getType(Uri uri) {
             //返回为 1  表示通过id去查询 绝对只有单条记录
            if(ui.match(uri)==1){
                 return "vnd.android.cursor.item/single";
           }
           return "vnd.android.cursor.dir/mul";
    }
    /**
    * 插入了数据 可以返回 用于查询该数据的uri
    */
    @Override
    public Uri insert(Uri uri, ContentValues values) {
           long id=mdh.getWritableDatabase().insert("role", null, values);
          return ContentUris.withAppendedId(uri, id);
    }
    /**
    * 返回的是删除的受影响的行数
    */
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
          int count=mdh.getWritableDatabase().delete("role", selection, selectionArgs);
         return count;
    }
    /**
    * 返回的是被更新的行数
    */
    @Override
    public int update(Uri uri, ContentValues values, String selection,
    String[] selectionArgs) {
         int count=mdh.getWritableDatabase().update("role",values,selection, selectionArgs);
         return count;
    }


    }

    AndroidManifest.xml配置

      <provider 
                android:name=".RoleProvider"    这个是找到提供数据类的类名
                android:authorities="com.example.content.RoleProvider"></provider>   content://这个中间的内容就是android:authorities配置的内容


    在其他app中调用 

               Uri uri=Uri.parse("content://com.example.content.RoleProvider/roleName/"+roleName);
              Cursor cursor=cr.query(uri, null, null, null, null);
             while(cursor.moveToNext()){
                    int roleI=cursor.getInt(0);
                   String roleName=cursor.getString(1);

             }


  • 相关阅读:
    windows 程序设计自学:窗口正中显示Hello,World
    为网站图片增加延迟加载功能,提升用户体验
    线性表顺序存储
    sys.stdout sys.stderr的用法
    python 跳出嵌套循环方法
    * 与 ** 在调用函数时的作用
    twisted 学习笔记二:创建一个简单TCP客户端
    给命令行上色
    __new__ 的简单应用
    网友对twisted deferr的理解
  • 原文地址:https://www.cnblogs.com/liaomin416100569/p/9331234.html
Copyright © 2011-2022 走看看