前段时间有个定制化的项目其中有个功能是监听手机短信并将接收到的短信内容上报给后台。
当我首次看到这个功能之后第一反应是通过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()}")
}
}
}
}
}
网友评论