当手机接收到一条短信的时候,系统就会发出一条值为
android.provider.Telephony.SMS_RECEIVED
的广播,这条广播里携带着与短信相关的所有数据,系统发出的短信广播是一条有序广播
接收短信
- 在活动创建的时候,组件初始化操作并注册接收短信的监听器:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
....
eceiveFilter = new IntentFilter();
receiveFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
messageReceiver = new MessageReceiver();
//动态注册监听器
registerReceiver(messageReceiver, receiveFilter);
}
- 动态注册广播接收器,需要在活动销毁时,取消注册
@Override
protected void onDestroy() {
super.onDestroy();
//取消注册广播接收器
unregisterReceiver(messageReceiver);
}
- 实现接收短信的广播接收器
class MessageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 从Intent参数中取出一个Bundle对象
Bundle bundle = intent.getExtras();
//使用pdu密钥来提取一个SMS pdus数组,其中每一个pdu都表示一条短信消息
Object[] pdus = (Object[]) bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < messages.length; i++) {
//使用SmsMessage()的静态方法createFromPdu()方法将每一个pdu字节数组转换为SmsMessage对象
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
//调用SmsMessage对象的getOriginatingAddress()方法就可以获取到短信的发送发号码
String address = messages[0].getOriginatingAddress();
String fullMessage = "";
for (SmsMessage message : messages) {
//调用SmsMessage对象的getMessageBody()方法就可以获取到短信的内容,将每一个SmsMessage对象中的短信内容拼接起来,就组成了一条完整的短信内容
fullMessage += message.getMessageBody();
}
//给界面上的组件设置内容,将信息发送方的电话号码和信息内容显示在界面上
sender.setText(address);
content.setText(fullMessage);
}
}
- 接收短信要声明权限
<uses-permission android:name="android.permission.RECEIVE_SMS" />
拦截短信
系统发出的短信广播是一条有序广播
- 提高我们自定义信息接收器的优先级,让它能够先于系统短信程序接收到短信广播
receiveFilter = new IntentFilter();
receiveFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
//设置优先级
receiveFilter.setPriority(100);
messageReceiver = new MessageReceiver();
registerReceiver(messageReceiver, receiveFilter);
- 自定义的信息接收器接收到广播程序,处理完逻辑以后,需要终止广播的继续传递
sender.setText(address);
content.setText(fullMessage);
//终止此广播的继续传递
abortBroadcast();
拦截短信的功能谨慎使用,防止丢失重要的数据
发送短信
- 发送普通文本内容内的短信,使用的是
SmsMessage
类的sendTextMessage()
方法
//首先调用SmsMessage类的getDefault()方法获取到SmsMessage的实例对象
SmsManager smsManager = SmsManager.getDefault();
/*
* destinationAddress:手机号码
* scAddress:服务中心号码
* text:短信内容
* sentIntent:PendingIntent,信息发送成功或失败时触发
* deliveryIntent:PendingIntent,信息抵达收件人触发
*/
smsManager.sendTextMessage((String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent);
- 当发送过长文本内容的短信时,首先将信息内容切割(不超过一条短信的长度要求),而后发送
//切割短信内容
ArrayList<String> texts = smsManager.divideMessage(String text);
//发送短信内容(参数代表的意义相同)
smsManager.sendMultipartTextMessage(String destinationAddress, String scAddress, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents)
短信发送成功的提示
发送短信时,第四个参数sentIntent,是一个PendingIntent类型,此参数在短信发送成功或失败时触发
当信息发送成功或失败时,我们发出一个广播,通过监听这个广播来实现通知用户信息是否发送成功
- 接收广播的逻辑实现
class SendStatusReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (getResultCode() == RESULT_OK) {
Toast.makeText(context, "Send succeeded", Toast.LENGTH_LONG)
.show();
} else {
Toast.makeText(context, "Send failed", Toast.LENGTH_LONG)
.show();
}
}
}
- 注册广播接收器以及给按钮添加发送短信的功能逻辑
//注册广播接收器,指定监听的广播内容
IntentFilter sendFilter = new IntentFilter();
sendFilter.addAction("SENT_SMS_ACTION");
sendStatusReceiver = new SendStatusReceiver();
registerReceiver(sendStatusReceiver, sendFilter);
//发送短信,并当短信发送成功或失败时,触发发出指定内容的广播
send.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
SmsManager smsManager = SmsManager.getDefault();
Intent sentIntent = new Intent("SENT_SMS_ACTION");
PendingIntent pi = PendingIntent.getBroadcast(
MainActivity.this, 0, sentIntent, 0);
smsManager.sendTextMessage(to.getText().toString(), null,
msgInput.getText().toString(), pi, null);
}
});