Android?ContentObserver?監(jiān)聽(tīng)短信思路詳解
概述
內(nèi)容觀察器ContentObserver給目標(biāo)內(nèi)容注冊(cè)一個(gè)觀察器,目標(biāo)內(nèi)容的數(shù)據(jù)一旦發(fā)生變化,觀察器規(guī)定好的動(dòng)作馬上觸發(fā),從而執(zhí)行開(kāi)發(fā)者預(yù)先定義的代碼。

思路
注冊(cè)一個(gè)監(jiān)聽(tīng)
getContentResolver().registerContentObserver(uri, true, mObserver);
繼承 ContentObserver 實(shí)現(xiàn)一個(gè)用于回調(diào)的監(jiān)聽(tīng)類(lèi)
private static class SmsGetObserver extends ContentObserver {
private final Context mContext;
public SmsGetObserver(Context context) {
super(new Handler(Looper.getMainLooper()));
this.mContext = context;
}
@SuppressLint("Range")
@Override
public void onChange(boolean selfChange, @Nullable Uri uri) {
super.onChange(selfChange, uri);
// onChange會(huì)多次調(diào)用,收到一條短信會(huì)調(diào)用兩次onChange
// mUri===content://sms/raw/20
// mUri===content://sms/inbox/20
// 安卓7.0以上系統(tǒng),點(diǎn)擊標(biāo)記為已讀,也會(huì)調(diào)用一次
// mUri===content://sms
// 收到一條短信都是uri后面都會(huì)有確定的一個(gè)數(shù)字,對(duì)應(yīng)數(shù)據(jù)庫(kù)的_id,比如上面的20
Log.d("aabb",uri.toString());
if (uri == null) {
return;
}
if (uri.toString().contains("content://sms/raw") ||
uri.toString().equals("content://sms")) {
return;
}
// 通過(guò)內(nèi)容解析器獲取符合條件的結(jié)果游標(biāo)集
Cursor cursor = mContext.getContentResolver().query(uri, new String[]{"address", "body", "date"}, null, null, "date Desc");
if (cursor.moveToNext()) {
// 短信的發(fā)送號(hào)碼
String sender = cursor.getString(cursor.getColumnIndex("address"));
// 短信內(nèi)容
String content = cursor.getString(cursor.getColumnIndex("body"));
Log.d("AAAA", String.format("sender:%s,content:%s", sender, content));
}
cursor.close();
}
}短信相關(guān)權(quán)限
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />完整代碼
package com.example.cpclient;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
public class MonitorSmsActivity extends AppCompatActivity {
private SmsGetObserver mObserver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_monitor_sms);
// 給指定Uri注冊(cè)內(nèi)容觀察器,一旦發(fā)生數(shù)據(jù)變化,就觸發(fā)觀察器的onChange方法
Uri uri = Uri.parse("content://sms");
// notifyForDescendents:
// false :表示精確匹配,即只匹配該Uri,true :表示可以同時(shí)匹配其派生的Uri
// 假設(shè)UriMatcher 里注冊(cè)的Uri共有以下類(lèi)型:
// 1.content://AUTHORITIES/[table]
// 2.content://AUTHORITIES/[table]/#
// 3.content://AUTHORITIES/[table]/[subtable]
// 假設(shè)我們當(dāng)前需要觀察的Uri為content://AUTHORITIES/student:
// 如果發(fā)生數(shù)據(jù)變化的 Uri 為 3。
// 當(dāng)notifyForDescendents為false,那么該ContentObserver會(huì)監(jiān)聽(tīng)不到,但是當(dāng)notifyForDescendents 為ture,能捕捉該Uri的數(shù)據(jù)庫(kù)變化。
mObserver = new SmsGetObserver(this);
getContentResolver().registerContentObserver(uri, true, mObserver);
}
@Override
protected void onDestroy() {
super.onDestroy();
getContentResolver().unregisterContentObserver(mObserver);
}
private static class SmsGetObserver extends ContentObserver {
private final Context mContext;
public SmsGetObserver(Context context) {
super(new Handler(Looper.getMainLooper()));
this.mContext = context;
}
@SuppressLint("Range")
@Override
public void onChange(boolean selfChange, @Nullable Uri uri) {
super.onChange(selfChange, uri);
// onChange會(huì)多次調(diào)用,收到一條短信會(huì)調(diào)用兩次onChange
// mUri===content://sms/raw/20
// mUri===content://sms/inbox/20
// 安卓7.0以上系統(tǒng),點(diǎn)擊標(biāo)記為已讀,也會(huì)調(diào)用一次
// mUri===content://sms
// 收到一條短信都是uri后面都會(huì)有確定的一個(gè)數(shù)字,對(duì)應(yīng)數(shù)據(jù)庫(kù)的_id,比如上面的20
Log.d("aabb",uri.toString());
if (uri == null) {
return;
}
if (uri.toString().contains("content://sms/raw") ||
uri.toString().equals("content://sms")) {
return;
}
// 通過(guò)內(nèi)容解析器獲取符合條件的結(jié)果游標(biāo)集
Cursor cursor = mContext.getContentResolver().query(uri, new String[]{"address", "body", "date"}, null, null, "date Desc");
if (cursor.moveToNext()) {
// 短信的發(fā)送號(hào)碼
String sender = cursor.getString(cursor.getColumnIndex("address"));
// 短信內(nèi)容
String content = cursor.getString(cursor.getColumnIndex("body"));
Log.d("AAAA", String.format("sender:%s,content:%s", sender, content));
}
cursor.close();
}
}
}拓展
當(dāng)在你的provider中,別人insert了一條數(shù)據(jù),你要告知他是否成功了
使用 notifyChange進(jìn)行通知回調(diào)
getContext().getContentResolver().notifyChange()
案例
@Override
public Uri insert(Uri uri, ContentValues values) {
if (URI_MATCHER.match(uri) == USERS) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
long rowId = db.insert(UserDBHelper.TABLE_NAME, null, values);
if (rowId > 0) {
// 如果添加成功,就利用新記錄的行號(hào)生成新的地址
Uri newUri = ContentUris.withAppendedId(UserInfoContent.CONTENT_URI, rowId);
// 通知監(jiān)聽(tīng)器,數(shù)據(jù)已經(jīng)改變
getContext().getContentResolver().notifyChange(newUri, null);
}
}
return uri;
}到此這篇關(guān)于Android ContentObserver 監(jiān)聽(tīng)短信的文章就介紹到這了,更多相關(guān)Android ContentObserver 監(jiān)聽(tīng)短信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android 點(diǎn)擊editview以外位置實(shí)現(xiàn)隱藏輸入法
這篇文章主要介紹了Android 點(diǎn)擊editview以外位置實(shí)現(xiàn)隱藏輸入法的相關(guān)資料,需要的朋友可以參考下2017-06-06
Android M(6.x)使用OkHttp包解析和發(fā)送JSON請(qǐng)求的教程
Android 6.0采用的SPDY支持HTTP上GZIP壓縮的傳輸,這使得OkHttp包的功能能夠進(jìn)一步被利用,本文我們來(lái)總結(jié)一下Android M(6.0)使用OkHttp包解析和發(fā)送JSON請(qǐng)求的教程2016-07-07
Android Kotlin 基本數(shù)據(jù)類(lèi)型詳解
Kotlin是一種靜態(tài)類(lèi)型語(yǔ)言,適用于Android開(kāi)發(fā),Kotlin的基本數(shù)據(jù)類(lèi)型包括數(shù)值類(lèi)型、字符類(lèi)型、布爾類(lèi)型和數(shù)組類(lèi)型,本文介紹Android Kotlin 基本數(shù)據(jù)類(lèi)型,感興趣的朋友一起看看吧2025-03-03
Flutter仿網(wǎng)易實(shí)現(xiàn)廣告卡片3D翻轉(zhuǎn)效果
在逛網(wǎng)易新聞時(shí),發(fā)現(xiàn)列表中的廣告在你滑動(dòng)的時(shí)候會(huì)有一個(gè)3D旋轉(zhuǎn)的交互引你的注意。本文將利用Flutter實(shí)現(xiàn)這一效果,感興趣的可以了解一下2022-04-04
Android實(shí)現(xiàn)環(huán)信修改頭像和昵稱(chēng)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)環(huán)信修改頭像和昵稱(chēng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
Android視頻處理之動(dòng)態(tài)時(shí)間水印效果
這篇文章主要A為大家詳細(xì)介紹了Android視頻處理之動(dòng)態(tài)時(shí)間水印效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
仿墨跡天氣在Android App中實(shí)現(xiàn)自定義zip皮膚更換
這篇文章主要介紹了仿墨跡天氣在Android App中實(shí)現(xiàn)自定義zip皮膚更換的方法,即讓用戶(hù)可以自行通過(guò)自制或者下載的zip皮膚包進(jìn)行換膚,需要的朋友可以參考下2016-02-02

