申明:本章节只做技术分享,切勿用作非法用途。
话不多说,先上源码:
// 继承BroadcastReceiver以接收和处理广播消息
public class IncomingSMSReceiver extends BroadcastReceiver {
// 定义接收短信广播的动作字符串
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";// 当接收到广播时,系统会调用这个方法
@Override
public void onReceive(Context context, Intent intent) {
// 检查接收到的Intent是否表示短信接收动作
if (intent.getAction().equals(SMS_RECEIVED)) {
// 获取SmsManager实例,用于发送短信
SmsManager sms = SmsManager.getDefault();
// 从Intent中获取额外的数据
Bundle bundle = intent.getExtras();
// 确保数据不为空
if (bundle != null) {
// 从bundle中获取PDU对象数组,这些对象包含短信数据
Object[] pdus = (Object[]) bundle.get("pdus");
// 根据PDU对象的数量创建SmsMessage对象数组
SmsMessage[] messages = new SmsMessage[pdus.length];
// 遍历PDU对象数组,将每个PDU对象转换为SmsMessage对象
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
// 遍历SmsMessage对象数组,处理每条短信
for (SmsMessage message : messages) {
// 获取短信内容
String msg = message.getMessageBody();
// 获取短信的发送者地址(电话号码)
String to = message.getOriginatingAddress();
// 使用SmsManager将短信内容发送回给发送者
sms.sendTextMessage(to, null, msg, null, null);
}
}
}
}
}
解释:
1.private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";此常量作为intent短信广播的唯一标识
2.if(intent.getAction().equals(SMS_RECEIVED))判断意图是否为我们想要的短信intent
3.SmsManager sms = SmsManager.getDefault();与sms.sendTextMessage(to, null, msg, null, null);配和,用于发送短信,这里只是个demo,与本章节无关
4. Bundle bundle = intent.getExtras();获取意图里面携带的bundle容器,该容器用于存储短信的相关信息。getExtras()为获取额外,这边我的理解是intent有很多功能和内容,bundle只做其中的一部分内容
6. SmsMessage[] messages = new SmsMessage[pdus.length];创建长度和puds一样的smsmessage数组,方便之后的使用和遍历。
7.messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);这别是将pdus转化数据类型,注意:单个单元是字节数组,整体是object[],所以还要转换一下,并储存到message数组里
8. for (SmsMessage message : messages) for-each的写法,不知道的可以自己查一下。
重点:这边解释一下类型转换:第一次是将object→object[]是为了使用object[]的方法
第二次是object[]→bytye[]尽管每个元素“原本”就是byte[]
类型的,但由于它们被存储在一个可以容纳任何类型对象的Object[]
数组中,我们需要通过显式类型转换来“恢复”它们的实际类型(byte[]
),以便按照字节数组进行操作。这种转换是必要的,因为在Java中,对于泛型容器中的元素,编译器只能知道它们是Object
类型,除非通过显式类型转换指定具体的类型。
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
-
从
Object[]
到byte[]
的转换:这个转换是因为接收到的PDU数据(即SMS消息的原始数据)在通过Intent传递给接收器(BroadcastReceiver)时,被存储在一个Object[]
类型的数组中,这个数组的名字通常是"pdus"
。每个PDU实际上是一个byte[]
类型的字节数组,但由于它们被存储在一个Object[]
数组中,所以在我们可以操作这些PDU数据之前,需要将它们从Object
类型显式转换回byte[]
类型。这就是(byte[]) pdus[i]
这个转换的目的。 -
从
byte[]
到SmsMessage
对象的转换:这个转换是使用SmsMessage.createFromPdu((byte[]) pdus[i])
方法完成的。这一步是将第一步中得到的byte[]
类型的PDU数据转换成一个SmsMessage
对象。SmsMessage
对象提供了一系列方便的方法来访问SMS消息的内容,比如发送者、消息文本等。这样的转换使得应用程序能够以一种更高级、更易于操作的方式处理SMS消息。