Android读取与接收短信

4,613 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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有

  1. content://sms/inbox     收件箱
  2. content://sms/sent      已发送
  3. content://sms/draft     草稿
  4. content://sms/outbox    发件箱 我们这里只用读取收件箱的短信就可以了,所以选取content://sms/inbox

查询的字段

短信数据库中字段比较多,以下是常用的字段:

  1. address 发件人号码
  2. person 联系人姓名列表
  3. date 短信日期
  4. body 短信内容
  5. 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();
    }
}