Kotlin 开发Android app(十六):ContentProvider的使用

news2024/11/17 22:41:18

android的四大组件,已经介绍了两个,这一节介绍ContentProvider。前面的广播可以进行 app内的通讯,如果需要进行app之间的通讯,在android 中使用的是ContentProviderContentProvider 也分为三种,一,作为数据的存储和查询,也就是别人来调用你ContentProvider。二,调用者ContentResolver ,用来调用插入和查询数据。三,观察者ContentObserver ,比如监控短信的变化。

在这里插入图片描述

ContentProvider 提供者

ContentProvider 提供者作为一个母体,用来通过数据的查询和插入,这样做的好处是,让每个服务都相互独立,而且有可以像外部提供相应的接口。比如通讯录,短信息等。他们作为一种服务,根据用户的权限来提供特有的服务。

这里我们也建立一个ContentProvider ,用户可以来调用,提供查询和插入的功能。我们用sqlite对数据进行存储和查询。

    inner class DBHelper(context:Context,name:String,
                         factory:SQLiteDatabase.CursorFactory?,version:Int):SQLiteOpenHelper(context,name,factory, version){
        override fun onCreate(_db: SQLiteDatabase?) {
            var sql:String = "CREATE TABLE " + DATUM_TABLE_NAME +
                    " (" + "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
                    Constants.TEXT+
                    " VARCHAR(20)" + ")"
            _db?.execSQL(sql)
        }

        override fun onUpgrade(_db: SQLiteDatabase?, p1: Int, p2: Int) {
            var sql:String = "DROP TABLE IF EXISTS " + DATUM_TABLE_NAME
            _db?.execSQL(sql)
            onCreate(_db)
        }

    }

创建 ContentProvider

class DataProvider : ContentProvider() 

实现两个接口 queryinsert

    override fun query(
        uri: Uri,
        p: Array<out String>?,
        s: String?,
        args: Array<out String>?,
        sort: String?
    ): Cursor? {
        val qb = SQLiteQueryBuilder()
        qb.tables = DATUM_TABLE_NAME
        qb.projectionMap = projMap

        var s1 = s
        if (sUriMatcher.match(uri) != DATUM) {
            if (sUriMatcher.match(uri) == DATUM_ID)
                s1 = s + "_id = " + uri?.lastPathSegment
            else
                throw IllegalArgumentException("Unknown URI " + uri)
        }
        val db = dbHelper?.readableDatabase
        val c = qb.query(db, p, s1, args, null, null, sort)
        c.setNotificationUri(context?.contentResolver ?: null, uri)
        return c
    }

insert 接口

   override fun insert(uri: Uri, cv: ContentValues?): Uri? {
        var m:Int = sUriMatcher.match(uri).toInt()
        m = 1
        if (m != 1){
            throw IllegalArgumentException("Unknown URI " + uri)
        }

        val v: ContentValues
        if (cv != null)
            v = ContentValues(cv)
        else
            v = ContentValues()

        val db = dbHelper?.writableDatabase
        val rId = db?.insert(DATUM_TABLE_NAME, Constants.TEXT, v)
        if (rId != null) {
            if (rId > 0) {
                val uri = ContentUris.withAppendedId(Constants.URL, rId)
                context?.contentResolver?.notifyChange(uri, null)
                return uri
            }
        } else {
            throw SQLException("Failed to insert row into " + uri)
        }
        return null
    }

如何调用呢?

        var textView = findViewById<TextView>(R.id.textView)
        var btn = findViewById<Button>(R.id.btn)

        // Inserting data into content provider
        val tuple = ContentValues()
        tuple.put(Constants.TEXT, Constants.TEXT_DATA)
        contentResolver.insert(Constants.URL, tuple)

        // Reading from content provider
        val cols = arrayOf(Constants.ID, Constants.TEXT)
        val u = Constants.URL
        val c = contentResolver.query(u, cols, null, null, null)
        if (c!!.moveToLast())
            textView.text = "Data read from content provider: " +
                    c!!.getString(c.getColumnIndex(Constants.TEXT))
        else
            textView.text = "Access denied"

AndroidManifest.xml 上 添加:

        <provider
            android:name="com.kotlin.kotlin_start_ch16.DataProvider"
            android:authorities="com.kotlin.kotlin_start_ch16.provider"
            android:exported="true"
            android:multiprocess="true"/>

模拟插入数据后,对数据进行查询,并显示在textview上。

contentResolver 获取短信数据

app获取短信需要相应的权限,首先要确认和申请权限。在AndroidManifest.xml 上添加,

<uses-permission android:name="android.permission.READ_SMS" />

这样还不够,需要进行权限的用户授权。

fun checkPermission():Boolean{
        var result = ContextCompat.checkSelfPermission(applicationContext,Manifest.permission.READ_SMS)
        return result==PackageManager.PERMISSION_GRANTED
    }

    fun requestPermission(i:Int){
        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_SMS),i)
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }

当用户确认以后,才可以进行短信的获取。

        if (!checkPermission()){
            requestPermission(123)
        }
        btn.setOnClickListener {

            val cols = arrayOf("_id","address","date","type","body")
            var c = contentResolver.query(Uri.parse("content://sms/"),cols,null,null, null)

            while (c!!.moveToNext()){

                var body=c.getString(4)
                textView.text = body

                var s = SmsInfo(c.getInt(0),c.getString(1),c.getLong(2),c.getString(4))

                sms.add(s)

            }
            var text:String = ""
            sms.forEach{
                text = text + it.address + "\n"
                text = text + it.info + "\n"
            }

            textView.text = text

        }

ContentObserver监控短信的到来

ContentObserver监控短信同样的需要相应的权限,可以看看上节的代码,要监控短信需要新建一个类继承ContentObserver,并进行注册:

            smsContentObserver = SmsContentObserver(this, Handler(Looper.getMainLooper()), conversationsHandler)
            //smsContentObserver = SmsContentObserver(this, Handler(Looper.getMainLooper()))
            smsContentObserver?.let {
                //it.start()
                contentResolver.registerContentObserver(Telephony.Sms.CONTENT_URI, true, it)
                contentResolver.registerContentObserver(Telephony.Mms.CONTENT_URI, true, it)
                contentResolver.registerContentObserver(Telephony.MmsSms.CONTENT_URI, true, it)
            }

收到短信后,对短信进行处理:

    private fun newSms() {
        val newSms: Map<Int, SmsObject> = smsDeleteDetector.newSms()
        newSms.forEach {
            if ((it.value._type).toInt() == Telephony.Sms.Inbox.MESSAGE_TYPE_INBOX) {
                logToastHelper.showLogMsg(
                    context,
                    "$tag Inbox ID:${it.value._id}  ThreadId:${it.value._threadId} ",
                    "SMS From ${it.value._address} : ${it.value._body}"
                )
            } else if (((it.value._type).toInt()) == Telephony.Sms.Inbox.MESSAGE_TYPE_SENT) {
                logToastHelper.showLogMsg(
                    context,
                    "$tag Outbox ID:${it.value._id}  ThreadId:${it.value._threadId}",
                    "SMS Sent To ${it.value._address} : ${it.value._body}"
                )
            }
        }
    }

小结

如果一步一步的进行安卓基础知识的学习,会觉得android的设计还是很有层次的,每一组组件都设计的比较完善,编程者用起来其实都会觉得比较简单的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/55215.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

物通博联持续参与京东方(BOE)工厂数字化项目

创新引领 数字驱动 京东方科技集团股份有限公司&#xff08;BOE&#xff09;创立于1993年&#xff0c;是全球领先的半导体显示技术、产品与服务提供商&#xff0c;核心业务包括显示器件、智慧系统和健康服务。产品广泛应用于手机、平板电脑、笔记本电脑、显示器、电视、车载、…

php万年历源代码!源代码![上一年、上一月、下一月、下一年、附加当天日期加背景颜色]-私聊源码

//当前年 $year isset($_GET[year])?$_GET[year]:date(Y); //echo $year; //制作当前月的变量 $monthisset($_GET[month])?$_GET[month]:date(n); //本月有多少天 $day date(t,mktime(0,0,0,$month,1,$year)); //本月从1号开始是星期几 $w date(w,mktime(0,0,0,$month,1…

python处理csv文件

如何使用python处理csv文件 素材准备 ​ csv⽂件其实就是⽂本⽂件&#xff0c;遵循了⼀定的格式&#xff0c;常⻅的csv⽂件⼀般是⽤逗号来隔开列&#xff0c;⽤换⾏符隔开不同的⾏&#xff0c;注意这⾥的符号都是英⽂符号。我们可以直接⽤open函数来打开csv⽂件&#xff1b; …

.net----数据库的访问ADO.NET、DataAdapter和DataSet

数据库的访问前言ADO.NET的概述ADO.NET数据源访问处理数据类库的两个组件&#xff1a;引用System.Data.dll和System.Xml.dll使用ADO.NET连接和操作数据库使用数据提供程序访问数据库操作的典型步骤&#xff1a;&#xff08;1&#xff09;建立数据库连接&#xff08;2&#xff0…

艾美捷曲妥珠单抗Trastuzumab参数和相关研究

曲妥珠单抗是一种重组人源化单克隆抗体&#xff0c;特异性地作用于人表皮生长因子受体-2(HER2)的细胞外部位。此抗体含人IgG1 框架&#xff0c;互补决定区源自鼠抗p185 HER2 抗体&#xff0c;能够与HER2 绑定。 HER2 原癌基因或C-erbB2 编码一个单一的受体样跨膜蛋白&#xff0…

Tyramide Cy5.5,Cyanine5.5 Tyramide,花青素Cy5.5酪酰胺远红色近红外发射染料

​一、理论分析&#xff1a; 中文名&#xff1a;花青素Cy5.5 酪酰胺 英文名&#xff1a;Cyanine5.5 Tyramide&#xff0c;Cy5.5 Tyramide&#xff0c;Tyramide Cy5.5 CAS号&#xff1a;N/A 化学式&#xff1a;C48H52CIN3O2 分子量&#xff1a;738.4 二、产品详情&#xff1a; 外…

【D3.js】1.20-给 D3 元素添加工具提示

title: 【D3.js】1.20-给 D3 元素添加工具提示 date: 2022-12-02 15:04 tags: [JavaScript,CSS,HTML,D3.js,SVG] 继续增强交互性&#xff1a;给元素添加悬停提示。 一、学习目标 如何给元素添加悬停提示&#xff1f; 通过title元素&#xff1a;增加title元素&#xff0c;通过.…

HTML+CSS+JS网页设计期末课程大作业——海贼王(8个页面)动漫网页设计

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 精彩专栏推荐&#x1f4…

vector类的常用接口说明

目录 一、(constructor)构造函数声明 二、vector的迭代器 三、vector的增删改查 四、insert和erase&#xff0c;以及查找find&#xff08;find不属于vector&#xff0c;是stl提供的算法&#xff09; 五、三种遍历方式 六、源代码 vector是可变大小数组的序列容器 一、(c…

海豚调度器分布式部署

前置准备 服务器 node01,node02,node03三台服务器&#xff08;本教程服务器系统版本Linux version 3.10.0-1160.el7.x86_64&#xff09; node01作为master&#xff0c;api&#xff0c;alert节点&#xff0c;node02和node03作为worker节点 安装包下载 下载dolphinscheduler和…

RFID数据采集成为MES系统精准数据

随着信息化、自动化成为企业发展趋势&#xff0c;制造执行系统(MES)是连接计划层和现场控制层之间的纽带&#xff0c;成为企业制造战略重要技术手段。MES生产执行系统主要在生产过程层及管理层之间加强数据集成与分析的力度&#xff0c;拓展优化技术应用的范围&#xff0c;真正…

猿创征文|Python学习工具千千万,我心中的TOP10

前言&#xff1a; 大家好&#xff0c;我是是Dream呀&#xff0c;在我们平时的开发和生活中&#xff0c;每天都在使用、寻找、贡献、创作各类开发者工具&#xff0c;包括开源服务、付费软件、API等。好的工具可以极大帮助我们提升效率&#xff0c;服务业务。作为一名资深的Pytho…

MFC下拉框控件用法

目录 一、属性方式设置下拉框内容 1.Combo Box下拉框 2.Data属性 3.Type属性 4.Sort属性 二、初始化OnInitDialog设置下拉框内容 1.添加Combo Box下拉框变量 2.AddString方法添加选项 3.SetCurSel设置默认显示内容 4.InsertString方法插入内容 4.DeleteString删除指…

数据中心网络设计- 叶脊(Spine-Leaf)网络架构

大家好&#xff0c;我是技福的小咖老师。 随着业务形态的变化&#xff0c;数据中心网络的交换架构也在不断的发展。传统的三层网络结构应用广泛而且技术成熟&#xff0c;但随着技术的发展趋势&#xff0c;它的瓶颈也不断涌现&#xff0c;导致越来越多的网络工程师放弃这种结构…

[附源码]计算机毕业设计JAVA校园一卡通管理信息系统台

[附源码]计算机毕业设计JAVA校园一卡通管理信息系统台 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM…

C#上位机系列(5)—示波器二基础代码+线条绘制

本文是讲解C#.net平台的Winform框架下的第四个内容&#xff0c;手把手介绍上位机项目的创建方式以及一些写软件时常用的功能&#xff0c;讲解从零开始的每一个步骤。 接上一节的介绍&#xff0c;本次内容为上位机项目中示波功能代码的基本函数和画图功能。 目的是通过几行代码…

【联邦学习】联邦学习量化——non-iid数据集下的仿真

文章目录改进项目背景量化函数的改进non-iid数据集的设置Fedlab划分数据集的踩雷改进项目背景 在前面的项目中&#xff0c;虽然对联邦学习中&#xff0c;各个ue训练出来的模型上传的参数进行了量化&#xff0c;并仿真的相关结果。但是仍有一些俺不是非常符合场景的情况&#x…

《Hive性能调优实战》读书笔记

很不错的一本书。章节划分清晰明了&#xff0c;可根据个人需要读相应的章节。Hive各个方面的知识体系都有涉及。可作为工具书&#xff0c;常读常新&#xff0c;值得翻阅。 第2章 Hive问题排查与调优思路 优化方法 PL-SQL和T-SQL经验总结&#xff1a; 通过改写SQL&#xff0…

Hust计算机组成原理实验

文章目录logisim的使用1.添加门电路2.添加引脚3.添加导线4.添加文本5.测试电路补充工具实验一&#xff0c;运算器实验8位串行可控加减法器分析一位全加器八位串行加法器即可给出8位串行可控加减法器回答问题CLA74182&#xff08;先行进位加法器&#xff09;参数公式问题位快速加…

10个最常见的JavaScript问题

如今&#xff0c;JavaScript几乎是所有现代web应用程序的核心。这就是为什么JavaScript问题以及找出导致这些问题的错误是web开发人员的首要任务。 用于单页应用程序&#xff08;SPA&#xff09;开发、图形和动画以及服务器端JavaScript平台的强大的基于JavaScript的库和框架并…