当前位置:首页 > 行业动态 > 正文

Android本地短信如何读取?——短信数据获取方法解析

Android读取本地短信可通过ContentResolver查询SMS内容提供者实现。

Android读取本地短信

一、权限申请

要在Android应用中读取短信,首先需要在AndroidManifest.xml文件中声明读取短信的权限:

<uses-permission android:name="android.permission.READ_SMS" />

二、动态权限请求(针对Android 6.0及以上系统)

除了在AndroidManifest.xml中声明权限外,还需要在代码中动态请求用户授权访问短信权限,以下是实现步骤:

1、检查权限是否已授予

   if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
       // 请求权限
       ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, READ_SMS_PERMISSION_CODE);
   } else {
       // 已有权限,继续读取短信
       readSms();
   }

2、处理权限请求结果

   @Override
   public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
       if (requestCode == READ_SMS_PERMISSION_CODE) {
           if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
               readSms(); // 权限被授予,读取短信
           } else {
               Toast.makeText(this, "权限被拒绝,无法读取短信", Toast.LENGTH_SHORT).show();
           }
       }
   }

使用ContentResolver从短信数据库中提取信息,以下是示例代码:

private void readSms() {
    Uri uri = Telephony.Sms.CONTENT_URI;
    String[] projection = new String[] { Telephony.Sms._ID, Telephony.Sms.ADDRESS, Telephony.Sms.BODY, Telephony.Sms.DATE };
    String selection = null;
    String[] selectionArgs = null;
    String sortOrder = Telephony.Sms.DEFAULT_SORT_ORDER;
    Cursor cursor = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
    if (cursor != null && cursor.moveToFirst()) {
        do {
            String id = cursor.getString(cursor.getColumnIndex(Telephony.Sms._ID));
            String address = cursor.getString(cursor.getColumnIndex(Telephony.Sms.ADDRESS));
            String body = cursor.getString(cursor.getColumnIndex(Telephony.Sms.BODY));
            long date = cursor.getLong(cursor.getColumnIndexOrThrow(Telephony.Sms.DATE));
            // 在这里对短信内容进行处理,例如显示在界面上
        } while (cursor.moveToNext());
        cursor.close();
    }
}

四、短信数据库中的字段说明

字段名 类型 描述
_id INTEGER 一个自增字段,从1开始
thread_id INTEGER 序号,同一发信人的id相同
address TEXT 发件人手机号码
person STRING 联系人列表里的序号,陌生人为null
date DATE 发件日期
protocol INTEGER 协议,分为:0 SMS_RPOTO, 1 MMS_PROTO
read INTEGER 是否阅读 0未读,1已读
status INTEGER 状态 -1接收,0 complete, 64 pending, 128 failed
type INTEGER ALL = 0; INBOX = 1; SENT = 2; DRAFT = 3; OUTBOX = 4; FAILED = 5; QUEUED = 6;
body TEXT 短信内容
service_center STRING 短信服务中心号码编号,如+8613800755500
subject STRING 短信的主题
reply_path_present BOOLEAN TP-Reply-Path
locked INTEGER 是否锁定

五、相关问题与解答

1、问题:为什么在AndroidManifest.xml中声明了读取短信权限后,还需要动态请求权限?

回答:在Android 6.0(API级别23)及以上系统中,引入了动态权限的概念,以提高应用的安全性和隐私性,即使应用在AndroidManifest.xml中声明了所需的权限,也必须在运行时动态请求这些权限,并获得用户的明确授权,才能执行相关操作,这是为了确保用户对自己的设备和数据有更多的控制权,防止应用在未经用户同意的情况下访问敏感数据。

2、问题:读取短信时,如何过滤出特定发件人的短信?

回答:可以在查询短信时,通过指定selectionselectionArgs参数来过滤出特定发件人的短信,要过滤出发件人为“123456789”的短信,可以这样写:

String selection = Telephony.Sms.ADDRESS + " = ?";
String[] selectionArgs = new String[] { "123456789" };
Cursor cursor = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);