要在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、问题:读取短信时,如何过滤出特定发件人的短信?
回答:可以在查询短信时,通过指定selection
和selectionArgs
参数来过滤出特定发件人的短信,要过滤出发件人为“123456789”的短信,可以这样写:
String selection = Telephony.Sms.ADDRESS + " = ?"; String[] selectionArgs = new String[] { "123456789" }; Cursor cursor = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);