要在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);