• Android---------------ContentProvider的学习


    1.Uri  uri = Intent.getData()------------->可以获得Uri的地址

    2.Cursor cursor = getContentResolver().query(uri , null , null , null ,null);  ------------->这句话相当得到空行那个位置

    3.cursor.moveToFirst()------------------------------>定位到第一行

    4.String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))

        getColumnIndex(String columnName)  :  返回指定列的名称,如果不存在返回-1

    总结:跨进程访问和进程间内部访问区别在于Mainfest.xml文件中的权限的问题

    注意事项 : 一定在Mainfest里面注册信息

    <provider android:name="MyProvider"
              android:authorities="cn.scu.myprovider"/>

    进程内访问的一般步骤:

    1. 创建数据库类
    2. 自定义 ContentProvider
    3. 注册 创建的 ContentProvider类--------->指的是.xml文件里面的东西
    4. 进程内访问 ContentProvider的数据

    UriMatcher类的作用

    • ContentProvider 中注册URI
    • 根据 URI 匹配 ContentProvider 中对应的数据表

    在CotentProvider的这个类中写的

    public static final String AUTOHORITY = "cn.scu.myprovider";
    // 设置ContentProvider的唯一标识

    public static final int User_Code = 1;
    public static final int Job_Code = 2;

    // UriMatcher类使用:ContentProvider 中注册URI
    private static final UriMatcher mMatcher;
    static{
    mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    // 初始化
    mMatcher.addURI(AUTOHORITY,"user", User_Code);
    mMatcher.addURI(AUTOHORITY, "job", Job_Code);
    // URI资源路径 = content://cn.scu.myprovider/user ,则返回注册码User_Code
    // URI资源路径 = content://cn.scu.myprovider/job ,则返回注册码Job_Code
    }
    /**
    * 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
    */
    private String getTableName(Uri uri){
    String tableName = null;
    switch (mMatcher.match(uri)) {
    case User_Code:
    tableName = user //这个返回代表是表名
    break;
    case Job_Code:
    tableName = job;
    break;
    }
    return tableName;
    }
        @Override
    public Uri insert(Uri uri, ContentValues values) {
    // 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
    // 该方法在最下面
    String table = getTableName(uri);
    // 向该表添加数据
    db.insert(table, null, values);
    // 当该URIContentProvider数据发生变化时,通知外界(即访问该ContentProvider数据的访问者)
    mContext.getContentResolver().notifyChange(uri, null);
    // // 通过ContentUris类从URL中获取ID
    // long personid = ContentUris.parseId(uri);
    // System.out.println(personid);
    return uri;
    }
        /**
    * 查询数据
    */
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
    String[] selectionArgs, String sortOrder) {
    // 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
    // 该方法在最下面
    String table = getTableName(uri);

    // // 通过ContentUris类从URL中获取ID
    // long personid = ContentUris.parseId(uri);
    // System.out.println(personid);
    // 查询数据
    return db.query(table,projection,selection,selectionArgs,null,null,sortOrder,null);
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
    String sortOrder) {
    MatrixCursor matrixCursor;
    switch (sUriMatcher.match(uri)) {
    case LUCKY_MONEY_ENABLE:
    matrixCursor = new MatrixCursor(new String[]{
    TABLE_COLUMN
    });
    matrixCursor.addRow(new Object[]{
    mCommonConfig.getXiaomiLuckyMoneyEnable() ? true : false
    });
    break;
    case LUCKY_MONEY_FAST_OPEN:
    matrixCursor = new MatrixCursor(new String[]{
    TABLE_COLUMN
    });
    matrixCursor.addRow(new Object[]{
    mCommonConfig.isFastOpenEnable() ? true : false
    });
    break;
    case LUCKY_MONEY_FLOAT:
    matrixCursor = new MatrixCursor(new String[]{
    TABLE_COLUMN
    });
    matrixCursor.addRow(new Object[]{
    mCommonConfig.isDesktopFloatWindowEnable() ? true : false
    });
    break;
    case LUCKY_NETWORK_LATENCY:
    matrixCursor = new MatrixCursor(new String[]{
    TABLE_COLUMN
    });
    matrixCursor.addRow(new Object[]{
    mCommonConfig.getNetworkReduceLatency() ? true : false
    });
    break;
    case LUCKY_MONEY_HB_INFO:
    matrixCursor = new MatrixCursor(new String[]{
    "num_total",
    "money_total",
    "mm_money_total",
    "qq_money_total",
    "max_person",
    "max_group"
    });
    matrixCursor.addRow(new Object[]{
    mCommonConfig.getWarningLuckyMoneyCount(),
    mCommonConfig.getReceiveTotalLuckyMoney(),
    mCommonConfig.getMMMoney(),
    mCommonConfig.getQQMoney(),
    mCommonConfig.getPersonalLuckyMaxSource(),
    mCommonConfig.getLuckyMaxSource()
    });
    break;
    default:
    return null;
    }
    return matrixCursor;
    }



    在MainActivity中写的
    Uri uri_job = Uri.parse("content://cn.scu.myprovider/job");
    // 插入表中数据
    ContentValues values2 = new ContentValues();
    values2.put("_id", 3);
    values2.put("job", "NBA Player");

    // 获取ContentResolver
    ContentResolver resolver2 = getContentResolver();
    // 通过ContentResolver 根据URI ContentProvider中插入数据
    resolver2.insert(uri_job, values2);

    // 通过ContentResolver ContentProvider中查询数据
    Cursor cursor2 = resolver2.query(uri_job, new String[]{"_id", "job"}, null, null, null);
    while (cursor2.moveToNext()) {
    //System.out.println("query job:" + cursor2.getInt(0) + " " + cursor2.getString(1));
    // 将表中数据全部输出
    Log.i("ceshi", "int ===" + cursor2.getInt(0));
    Log.i("ceshi", "String ===" + cursor2.getString(1));
    }
    cursor2.close();
    // 关闭游标
    }


    Url url = Url.parse("content://cn.scu.myprovider/job");
    ContentValues value = new ContentValues();
    value.put(-_id , 3);
    vlaue.put(name , "lisan");
    ContentResolver resolver = getContentResolver();
    resolver.insert(url,value); --------------------------------->它实际调用的是ContentProvider里面写的那个insert()函数

    Cursor cursor = resolver.query(url , null , null ,null , null);------>它实际调用的是ContentProvider里面写的那个query那个函数
    while(cursor.moveToNext){

    }
    cursor.close() -------->一定关闭游标卡尺





    ContentObserver类
      
      定义:内容观察者
        作用:观察 Uri引起 ContentProvider 中的数据变化 & 通知外界(即访问该数据访问者)
        当ContentProvider 中的数据发生变化(增、删 & 改)时,就会触发该 ContentObserver类
        具体使用
    // 步骤1:注册内容观察者ContentObserver
        getContentResolver().registerContentObserver(uri);-------->注册监听器
        // 通过ContentResolver类进行注册,并指定需要观察的URI

    // 步骤2:当该URI的ContentProvider数据发生变化时,通知外界(即访问该ContentProvider数据的访问者)
        public class UserContentProvider extends ContentProvider {
          public Uri insert(Uri uri, ContentValues values) {
          db.insert("user", "userid", values);
          getContext().getContentResolver().notifyChange(uri, null);
          // 通知访问者
       }
    }

    // 步骤3:解除观察者
     getContentResolver().unregisterContentObserver(uri);
        // 同样需要通过ContentResolver类进行解除



    //注册ContentProvider的观察者
    this.getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, new SmsObserver(new Handler()));
    //根据自定义的ContentObserver监听类
        private final class SmsObserver extends ContentObserver
        {
            public SmsObserver(Handler handler) {
                super(handler);
            }

            public void onChange(boolean selfChange)
            {
        //这里面就是接受notifyChange的改变做相应的处理
        getContext().getContentResolver().notifyChange(uri, null);
            }
        }





    进程间进行数据共享

      1. 创建数据库类
      2. 自定义 ContentProvider
      3. 注册 创建的 ContentProvider

    进程1的AndroidManifest.xml的文件

      <provider android:name="MyProvider"

      android:authorities="scut.carson_ho.myprovider"

      // 声明外界进程可访问该Provider的权限(读 & 写)

      android:permission="scut.carson_ho.PROVIDER"

      // 权限可细分为读 & 写的权限

      // 外界需要声明同样的读 & 写的权限才可进行相应操作,否则会报错

       //android:readPermisson = "scut.carson_ho.Read"

       // android:writePermisson = "scut.carson_ho.Write"

      // 设置此provider是否可以被其他进程使用

      android:exported="true" />


    进程2的AndroidManifest.xml的文件

    // 声明本应用可允许通信的权限(全权限)

    <uses-permission android:name="scut.carson_ho.PROVIDER"/>

    // 细分读 & 写权限如下,但本Demo直接采用全权限

    //<uses-permission android:name="scut.carson_ho.Read"/>

    ///  <uses-permission android:name="scut.carson_ho.Write"/>

    // 注:声明的权限必须与进程1中设置的权限对应



     
     
     

      

     

  • 相关阅读:
    最全!即学即会 Serverless Devs 基础入门(上)
    一站式智能运维解决方案,企业系统的隐形守护者
    Serverless JOB | 传统任务新变革
    好的 MySQL 兼容性可以做到什么程度? PolarDBX 如何做生态兼容
    Apsara Stack 技术百科 | 如何「场景化」的企业上云
    事务、全局索引、透明分布式,再见,分区健!
    IT人才能嗑到的这对CP,甜!
    腾讯云:最简单CentOS7下安装GUI图形界面(最新)
    Navicat连接不上Mysql 8问题解决方案
    【JS】验证表单是否空白验证
  • 原文地址:https://www.cnblogs.com/liunx1109/p/9985964.html
Copyright © 2020-2023  润新知