持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
之前一个项目中遇到一个小需求,读取并监听手机中的短信,在Android中,短信存储在系统短信库里面,通过ContentProvier的形式向外部提供接口。
读取短信
首先需要添加读取短信权限
<uses-permission android:name="android.permission.READ_SMS"/>
由于短信读取是动态权限,所以还需要动态申请
@SmartPermission(Manifest.permission.READ_SMS)
private void readSms() {
}
读取短信需要使用到ContentResolver.query(uri,projection,selection,selectionArgs,sortOrder)方法,他需要提供以下参数。
短信Uri
关于短信常见的Uri有
content://sms/inbox
收件箱content://sms/sent
已发送content://sms/draft
草稿content://sms/outbox
发件箱 我们这里只用读取收件箱的短信就可以了,所以选取content://sms/inbox
。
查询的字段
短信数据库中字段比较多,以下是常用的字段:
- address 发件人号码
- person 联系人姓名列表
- date 短信日期
- body 短信内容
- type 短信类型(ALL=0,INBOX=1,SEND=2,DRAFT = 3,OUTBOX = 4,FAILED = 5,QUEUED = 6)
由于业务比较简短,所以只需要查询发件人,短信内容等信息,而且不需要筛选,所以selection,selectionArgs直接传null,排序根据日期倒叙,sortOrder传date desc,完整的查询代码为:
Uri SMS_INBOX = Uri.parse("content://sms/inbox");
ContentResolver cr = getContentResolver();
String[] projection = new String[]{"_id", "address", "person", "body", "date", "type"};
Cursor cur = cr.query(SMS_INBOX, projection, null, null, "date desc");
if (null != cur) {
if (cur.moveToNext()) {
String number = cur.getString(cur.getColumnIndex("address"));//手机号
String name = cur.getString(cur.getColumnIndex("person"));//联系人姓名列表
String body = cur.getString(cur.getColumnIndex("body"));//短信内容
add(number,name,body);
}
}
监听短信
监听短信需要使用BroadcastReceiver
public class SmsReceiver extends BroadcastReceiver {
}
四大组件都需要在AndroidManifest中注册,除此之外,接受短信的广播接受者还需要动态注册,否则接收不到短信。
smsFilter = new IntentFilter();
smsFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
smsFilter.addAction("android.provider.Telephony.SMS_DELIVER");
smsReceiver = new SmsReceiver();
registerReceiver(new SmsReceiver(), smsFilter);
然后重写BroadcastReceiver的onReceive方法接受短信。
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onReceive(Context context, Intent intent) {
StringBuilder content = new StringBuilder();
Bundle bundle = intent.getExtras();
String format = intent.getStringExtra("format");
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
for (Object object : pdus) {
SmsMessage message = SmsMessage.createFromPdu((byte[]) object, format);
sender = message.getOriginatingAddress();
content.append(message.getMessageBody());
millis = message.getTimestampMillis();
status = message.getStatus();
}
String body = content.toString();
}
}