Android四大组件之ContentProvider(二)

上节提到的四大组件之ContentProvider的简单使用,在这篇文章中详细的介绍其中的一些方法。

1.String getType(Uri uri)方法

首先看看官方对它的解释:

    /**
     * Implement this to handle requests for the MIME type of the data at the
     * given URI.  The returned MIME type should start with
     * <code>vnd.android.cursor.item</code> for a single record,
     * or <code>vnd.android.cursor.dir/</code> for multiple items.
     * This method can be called from multiple threads, as described in
     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
     * and Threads</a>.
     *
     * <p>Note that there are no permissions needed for an application to
     * access this information; if your content provider requires read and/or
     * write permissions, or is not exported, all applications can still call
     * this method regardless of their access permissions.  This allows them
     * to retrieve the MIME type for a URI when dispatching intents.
     *
     * @param uri the URI to query.
     * @return a MIME type string, or {@code null} if there is no type.
     */
    public abstract @Nullable String getType(@NonNull Uri uri);

本人英文小白,大家可以自行百度翻译;我自己的理解是:

给定一个Uri返回相对应的MIME类型;注意,应用程序不需要权限;如果您的内容提供者需要读取和/或写权限,或不导出,所有应用程序仍然可以调用此方法不考虑其访问权限。这使他们在调度意图时检索URI的MIME类型。

返回MIME类型有何要求:

  1. vnd.android.cursor.dir/或者vnd.android.cursor.item/开头,根据Uri判断是处理单条数据还是全部数据
  2. 后接vnd.< aothority >.< path>结尾
    例:uri = “content://org.wdl.provider/books”
    返回的MIME为:vnd.android.cursor.dir/vnd.org.wdl.provider.books

MIME的内容见:(https://blog.csdn.net/qq_34341338/article/details/82997517)

作用:

  1. 隐式的启动activity等,通过IntentFliter匹配
    在这里插入图片描述

  2. 结合query(Uri, String[], String, String[], String)这个方法来解释一下:

    在该方法中,返回一个Cursor游标对象。而Cursor中是单条的记录还是一个集合,需要和在getType()方法中返回的类型保持一致。当返回的 MIME类型是Xxx.CONTENT_ITEMS时,Cursor应该是一个集合;当返回的MIME类型是 Xxx.CONTENT_ITEM时,Cursor应该是单条记录。

    由于在getType()方法里面,我们显示的返回了android平台可以识别的MIME类型,所以在执行query()方法返回Cursor对象的时候,系统将不需要再进行验证,从而可以说是节省了系统开销

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

仔细观察前面ContentProvider的使用时,发现在insert,update,delete后都会调用该方法通知所有注册在该Uri上的监听者。而为了提供监听ContentProvider数据的改变,Android提供了ContentObserver基类

如何使用?

  1. 自定义监听类继承自ContentObserver
  2. 重写onChange()方法,当被监听的ContentProvider数据改变时,会回调onChange()方法
  3. 注册监听器,ContentResolver向指定的Uri注册监听器,方法:
    registerContentObserver(Uri uri,boolean notifyForDescendents,ContentObserver observer)
  • uri:ContentProvider的Uri
  • notifyForDescendents:当值为true时,假如监听的Uri为content://abc,那么Uri为content://abc/xyz或者content://abc/xyz/fox的数据改变时也会触发该监听器;值为false则只有Uri为content://abc的数据改变时才会触发
  • observer:监听器实例

使用:

package com.wdl.contentproviderclient

import android.content.ContentResolver
import android.content.ContentUris
import android.content.ContentValues
import android.content.Intent
import android.database.ContentObserver
import android.net.Uri
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.util.Log
import kotlinx.android.synthetic.main.activity_main.*
import java.lang.StringBuilder

class MainActivity : AppCompatActivity() {
    lateinit var resolver:ContentResolver
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        resolver = contentResolver
        //注册该URI的监听
        resolver.registerContentObserver(Uri.parse("content://sms"),true,
                SmsObserver(resolver,null))
        btnQuery.setOnClickListener {
            val intent = Intent("com.wdl.mime")
            intent.data = Books.Book.BOOKS_CONTENT_URI
            startActivity(intent)
            val cursor = resolver.query(Books.Book.BOOKS_CONTENT_URI
                    ,null,"price=?", arrayOf("50.2"),null)
            //cursor.close()
            val stringBuilder = StringBuilder()
            while (cursor.moveToNext()){
                val id = cursor.getInt(cursor.getColumnIndexOrThrow(Books.Book.ID))
                val name = cursor.getString(cursor.getColumnIndexOrThrow(Books.Book.NAME))
                val price = cursor.getInt(cursor.getColumnIndexOrThrow(Books.Book.PRICE))
                stringBuilder.append("id=$id,name=$name,price=$price \n")
            }
            cursor.close()
            Log.e("wdl",stringBuilder.toString())
        }
        btnDelete.setOnClickListener {
            //val index = contentResolver.delete(uri,null,null)
            val index = resolver.delete(Books.Book.BOOKS_CONTENT_URI,"price=?", arrayOf("55.2"))

            Log.e("wdl",""+index)
        }
        btnInsert.setOnClickListener {
            val value = ContentValues()
            value.put(Books.Book.NAME,"smwdl")
            value.put(Books.Book.PRICE,50.2)
            val uri = resolver.insert(Books.Book.BOOKS_CONTENT_URI,value)
            Log.e("wdl",uri.toString())
        }
        btnUpdate.setOnClickListener {
            val value = ContentValues()
            value.put(Books.Book.PRICE,55.2)
            val uri = ContentUris.withAppendedId(Books.Book.BOOK_CONTENT_URI,1)
            val index = resolver.update(uri
                    ,value,"name like ?", arrayOf("smwdl"))
            Log.e("wdl",""+index)
        }
    }

    private class SmsObserver constructor(val resolver: ContentResolver, handler: Handler?): ContentObserver(handler) {
        //数据更改时回调此方法
        override fun onChange(selfChange: Boolean) {
            val cursor = resolver.query(Uri.parse("content://sms/inbox"),null
                    ,null
                    ,null
                    ,null)
            while (cursor.moveToNext()){
                val builder = StringBuilder()
                builder.append("address=${cursor.getString(cursor.getColumnIndexOrThrow("address"))},")
                        .append("subject=${cursor.getString(cursor.getColumnIndexOrThrow("subject"))}")
                        .append("body=${cursor.getString(cursor.getColumnIndexOrThrow("body"))}")
                        .append("time=${cursor.getLong(cursor.getColumnIndexOrThrow("date"))}")
                Log.e("wdl",builder.toString())
            }
            cursor.close()
        }
    }
}

3.批量操作数据

未完待完成。。。。。。

Demo下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值