Android监听短信,并读取短信内容

前段时间有个定制化的项目其中有个功能是监听手机短信并将接收到的短信内容上报给后台。
当我首次看到这个功能之后第一反应是通过BroadcastReceiver 注册一个短信的广播来实现。后来翻阅一些资料后发现使用ContentResolver实现起来更方便。
通过ContentProvider来实现短信的读取操作。
通过ContentResolver的registerContentObserver 注册ContentObserver观察者来实现短信监听效果。

package com.lijianjian.getsmsapp

import android.app.Service
import android.content.ContentResolver
import android.content.Intent
import android.database.ContentObserver
import android.net.Uri
import android.os.Handler
import android.os.HandlerThread
import android.os.IBinder
import android.util.Log

class ListenerSMSService : Service() {
    //用于在子线程中执行异步操作(这是指短信的查询操作)
    private var handlerThread: HandlerThread? = null
    private var threadHandler: Handler? = null

    override fun onBind(intent: Intent?): IBinder? {
        contentResolver.registerContentObserver(Uri.parse("content://sms/"), true, contentObserver)
        handlerThread = object : HandlerThread("sms") {
            override fun onLooperPrepared() {
                super.onLooperPrepared()
                threadHandler = Handler(handlerThread?.looper)
            }
        }
        handlerThread?.start()
        return MyBinder(this)
    }

    override fun onUnbind(intent: Intent?): Boolean {
        contentResolver.unregisterContentObserver(contentObserver)
        return super.onUnbind(intent)
    }

    private val contentObserver = object : ContentObserver(Handler()) {
    
        override fun onChange(selfChange: Boolean, uri: Uri?) {
            super.onChange(selfChange, uri)
            Log.e("contentObserver", "onChange(selfChange: Boolean, uri: Uri?)")
            uri?.let {
                val value = it.toString()
                Log.e("contentObserver", "uri==$value")
                if (value == "content://sms/inbox-insert") {
                    getSMSBody(Uri.parse("content://sms/inbox/"))
                }
            }
        }
    }

    private fun getSMSBody(uri: Uri) {
        threadHandler?.let {
            runnable.uri = uri
            runnable.contentResolver = contentResolver
            it.postDelayed(runnable, 3000)
        }
    }

    private val runnable = object : Runnable {
        var uri: Uri? = null
        var contentResolver: ContentResolver? = null
        override fun run() {
            contentResolver?.let {
                if (uri != null) {
                    val stringBuilder = StringBuilder()
                    val selection = arrayOf("_id", "body", "read")
                    val cursor = it.query(
                        uri!!,
                        selection,
                        " date >${System.currentTimeMillis() - 10 * 60 * 1000}",
                        null,
                        "date desc"
                    )
                    cursor?.let { cursor ->
                        val idIndex = cursor.getColumnIndex("_id")
                        val bodyIndex = cursor.getColumnIndex("body")
                        val readIndex = cursor.getColumnIndex("read")
                        if (cursor.count > 0) {
                            cursor?.moveToFirst()
                            do {
                                val id = cursor.getInt(idIndex)
                                val body = cursor.getString(bodyIndex)
                                val read = cursor.getString(readIndex)
                                stringBuilder.append("id=$id").append("body=$body")
                                    .append("read=$read").append("\n")
                            } while (cursor.moveToNext())
                        }
                    }
                    Log.e("stringBuilder", "stringBuilder==${stringBuilder.toString()}")
                }
            }
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,701评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,649评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,037评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,994评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,018评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,796评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,481评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,370评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,868评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,014评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,153评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,832评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,494评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,039评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,437评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,131评论 2 356

推荐阅读更多精彩内容

  • Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Goo...
    Androidgiao阅读 1,033评论 0 3
  • Android四大组件: activity: activity的生命周期:activity是context的子类,...
    梧桐树biu阅读 644评论 0 2
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,537评论 28 53
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,190评论 4 8
  • 步骤:发微博01-导航栏内容 -> 发微博02-自定义TextView -> 发微博03-完善TextView和...
    dibadalu阅读 3,138评论 1 3