目录
  • 1、注册ContentProvider
  • 2、内容URI
    • 内容URI的标准格式
    • 通配符
  • 3、创建自己的ContentProvider
    • 4、访问其他程序中的数据

      1、注册ContentProvider

      右击com.example.myapplication包->New->Other->Content Provider。会弹出窗口

      Kotlin ContentProvider使用方法介绍

      点击finish,完成创建ContentProvider类,这时你可以在注册代码中看到

      <provider
                  android:name=".MyContentProvider"
                  android:authorities="com.example.myapplication.provider"
                  android:enabled="true"
                  android:exported="true"></provider>

      注册ContentProvider时通常指定属性

      属性 描述
      name 指定该ContentProvider的实现类的类名
      authorities 指定该ContentProvider对应的URI
      enabled 指定该ContentProvider是否可用
      exported 指定该ContentProvider是否允许其他应用调用

      2、内容URI

      ContentResolver中的增删改查方法都不接收表名参数,而是使用一个Uri参数代替,这个参数被称为内容URI。

      内容URI的标准格式

      content://<authorities>/<path>

      (1)以路径结尾:表示期望访问该表地所有数据

      (2)以id结尾:表示期望访问该表拥有相应id的数据

      <authorities>:authorities是用于对不同的应用程序做区分的,一般会采用包名的方式命名,比如包名为com.example.myapplication,那么<authorities>为com.example.myapplication.provider。

      <path>:path是用于对同一应用程序的不同表做区分的,比如com.example.myapplication.provider/table1。

      通配符

      *表示匹配任意长度的任意字符

      #表示匹配任意长度的数字

      一个能够匹配任意表的内容URI格式

      content://com.example.myapplication.provider/*

      一个能够匹配table表中任意一行数据的内容URI格式

      content://com.example.myapplication.provider/table1/#

      把内容URI字符串解析成Uri对象

      val uri=Uri.parse("content://com.example.myapplication.provider/table1")

      3、创建自己的ContentProvider

      重写ContentProvider类的6个抽象方法

      • onCreate()。初始化ContentProvider的时候调用。通常会在这里完成对数据库的创建和升级等操作,返回true表示ContentProvider初始化成功,返回false则表示失败。
      • query()。从ContentProvider中查询数据。uri参数用于确认查询哪张表,projection参数用于确定查询哪些列,selection和selectionArgs参数用于约束查询哪些行,sortOrder参数用于对结果进行排序,查询的结果存放在Cursor对象中返回。
      • insert()。向ContentProvider中添加一条数据,uri参数用于确定要添加的表,待添加的数据保存在values参数中。添加完成后,返回一个用于表示这条新纪录的URI。
      • updata()。更新ContentProvider中已有的数据,uri参数用于确定更新哪一张表中的数据,新数据保存在values参数中,selection和selectionArgs参数用于约束更新哪些行,受影响的行数将作为返回值返回。
      • delete()。从ContentProvider中删除数据。uri参数用于确定删除哪一张表中的数据,selection和selectionArgs参数用于约束删除哪些行,被删除的行数将作为返回值返回。
      • getType()。根据传入的内容URI返回相应的MIME类型。

      getType方法中,一个内容URI所对应的MIME字符串主要由3部分组成,Android对这3部分做了如下格式规定

      • 必须以vnd开头
      • 如果内容URI以路径结尾,则后接android.cursor.dir/。
      • 如果内容URI以id结尾,则后接android.cursor.item/。
      • 最后接上vnd.<acthority>.<path>。

      例子:content://com.example.myapplication.provider/table1

      MIME类型:vnd.android.cursor.dir/vnd.com.example.myapplication.provider.table1

          override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
          }
          override fun getType(uri: Uri): String? {
              
          }
          override fun insert(uri: Uri, values: ContentValues?): Uri? {
          }
          override fun onCreate(): Boolean {
          }
          override fun query(uri: Uri, projection: Array<String>?, selection: String?,
                                    selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
          }
          override fun update(uri: Uri, values: ContentValues?, selection: String?,
                                     selectionArgs: Array<String>?): Int {
          }

      (2)利用UriMatcher这个类实现匹配内容URI的功能,来判断出调用方期望访问的时哪张表中的数据。

      UriMatcher的addURI()方法,接收三个参数,可以分别把authority、path和一个自定义代码传进去。这样,当调用UriMatcher的match()方法时,把一个Uri对象传入,就会返回一个与这个Uri对象匹配的一个自定义代码。

      class MyContentProvider : ContentProvider() {
          private val table1Dir=0
          private val table1Item=1
          private val table2Dir=2
          private val table2Item=3
          private val uriMatcher=UriMatcher(UriMatcher.NO_MATCH)
          init {
              uriMatcher.addURI("com.example.app.provider","table1",table1Dir)
              uriMatcher.addURI("com.example.app.provider","table1/#",table1Item)
              uriMatcher.addURI("com.example.app.provider","table2",table2Dir)
              uriMatcher.addURI("com.example.app.provider","table2Item",table2Item)
          }
         ...
          override fun query(uri: Uri, projection: Array<String>?, selection: String?,
                                    selectionArgs: Array<String>?, sortOrder: String?): Cursor? 
        {
              when(uriMatcher.match(uri)){
                  table1Item->{
                      //查询table1表中的所有数据
                  }
                  table1Item->{
                      //查询table1表中的单条数据
                  }
                  table2Dir->{
                      //查询table2表中的所有数据
                  }
                  table2Item->{
                      //查询table2表中的单条数据
                  }
              }
          }
      ...
      }

      4、访问其他程序中的数据

      1、ContentResolver的基本用法

      要访问ContentProvider中共享的数据,就要调用Context的getContentResolver()方法获取ContentResolver的实例,然后对数据进行增减改查的操作。

      (1)查询

      val cursor=contentResolver.query(uri,projection,selection,selectionArgs,sortOrder)
              if (cursor != null) {
                  while (cursor.moveToNext()){
                      val column1=cursor.getString(cursor.getColumnIndex("column1"))
                      val column2=cursor.getString(cursor.getColumnIndex("colum2"))
                  }
                  cursor.close()
              }

      (2)增加

             val values= contentValuesOf("column1" to "text","column2" to 1)
              contentResolver.insert(uri,values)

      (3)修改

              val values= contentValuesOf("column1" to "")
              contentResolver.update(uri, values,"column1 = ? and column2 = ?", arrayOf("text","1"))

      (4)删除

      contentResolver.delete(uri,"column2 = ?", arrayOf("1"))
      声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。