我就叨叨
看书的过程查了点资料,短信还有好多内容啊,先来个最基本的,后面补充吧。
短信接收流程:http://www.cnblogs.com/not-code/archive/2011/11/27/2265287.html
还是要看看啊,不然怎么得到的pdus?format?
权限
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
<uses-permission android:name="android.permission.READ_SMS"></uses-permission>
<uses-permission android:name="android.permission.SEND_SMS" />
接收短信
监控短信的两种方法:http://www.blogjava.net/anymobile/articles/328396.html
当手机收到一条短信时,系统会发出一条值为 android.provider.Telephony.SMS_RECEIVED 的广播,这条广播里
携带着与短信相关的所有数据。每个应用程序都可以在广播接收器里对它进行监听,收到广
播时再从中解析出短信的内容即可。
class SMSBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
abortBroadcast();
Bundle bundle = intent.getExtras();
//String format = intent.getStringExtra("format");
Object msg[] = (Object[]) bundle.get("pdus");
SmsMessage smsMessage[] = new SmsMessage[msg.length];
String fullMsg = "";
for(int i = 0; i < msg.length; i++){
//smsMessage[i] = SmsMessage.createFromPdu((byte[]) msg[i], format);
smsMessage[i] = SmsMessage.createFromPdu((byte[]) msg[i]);
fullMsg = fullMsg + smsMessage[i].getMessageBody();
}
从 Intent参数中取出了一个 Bundle 对象,然后使用 pdu密钥来提取一个 SMS pdus 数组,其中每一个 pdu 都表示一条短信消息。接着使用 SmsMessage 的createFromPdu()方法将每一个 pdu 字节数组转换为 SmsMessage 对象,调用这个对象的getOriginatingAddress()方法就可以获取到短信的发送方号码,调用 getMessageBody()方法就
可以获取到短信的内容,然后将每一个 SmsMessage 对象中的短信内容拼接起来,就组成了一条完整的短信。
注意:createFromPdu(byte[])已经过时了,从 API level 23 以后应该用createFromPdu(byte[], String)
参考:https://www.zhihu.com/question/37080814
第二个参数应该是短信的类型, 大概是GSM与CDMA短信的解码方式不同,所以应该传入这个参数,
Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
String format = intent.getStringExtra("format");
拦截短信
4.4以后不管我设置优先级多高,都没拦截成功,abortBroadcast()也没起作用。
原因:4.4升级了对安全类软件的控制,无法再通过abort或者删除短信数据库的方式实现短信拦截;
具体参考:http://blog.youkuaiyun.com/l173864930/article/details/17112227
http://blog.youkuaiyun.com/l173864930/article/details/17019615
发送短信
sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SmsManager smsManager = SmsManager.getDefault();
Intent intent = new Intent("SENT_SMS_ACTION");
PendingIntent pi = PendingIntent.getBroadcast(SMSActivity.this, 0, intent, 0);
smsManager.sendTextMessage(toEdit.getText().toString().trim(), null, sendEdit.getText().toString(),
pi, null);
}
});
class SendStatusReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if(getResultCode() == RESULT_OK){
Toast.makeText(SMSActivity.this, "send success", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(SMSActivity.this, "send fail", Toast.LENGTH_LONG).show();
}
}
}
在 Send按钮的点击事件里面我们调用了 PendingIntent 的 getBroadcast()方法获取到了一个 PendingIntent 对象,并将它作为第四个参数传递到 sendTextMessage()方法中。然后又注册了一个新的广播接收器 SendStatusReceiver,这个广播接收器就是专门用于监听短信发送状态的,当 getResultCode()的值等于 RESULT_OK就会提示发送成功,否则提示发送失败。
完整代码
public class SMSActivity extends AppCompatActivity {
private TextView senderText;
private TextView contentText;
private EditText toEdit;
private EditText sendEdit;
private Button sendBtn;
private SMSBroadcastReceiver receiver;
private SendStatusReceiver sendStatusReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sms);
initView();
registerSMSReceiver();
registerSendReceiver();
}
private void initView(){
senderText = (TextView)findViewById(R.id.sender);
contentText = (TextView)findViewById(R.id.content);
toEdit = (EditText)findViewById(R.id.to);
sendEdit = (EditText)findViewById(R.id.msg_input);
sendBtn = (Button)findViewById(R.id.send);
sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SmsManager smsManager = SmsManager.getDefault();
Intent intent = new Intent("SENT_SMS_ACTION");
PendingIntent pi = PendingIntent.getBroadcast(SMSActivity.this, 0, intent, 0);
smsManager.sendTextMessage(toEdit.getText().toString().trim(), null, sendEdit.getText().toString(),
pi, null);
}
});
}
private void registerSMSReceiver(){
receiver = new SMSBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
intentFilter.setPriority(1000);
registerReceiver(receiver, intentFilter);
}
private void registerSendReceiver(){
sendStatusReceiver = new SendStatusReceiver();
IntentFilter filter = new IntentFilter("SENT_SMS_ACTION");
registerReceiver(sendStatusReceiver, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
unregisterReceiver(sendStatusReceiver);
}
class SMSBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
abortBroadcast();
Bundle bundle = intent.getExtras();
//String format = intent.getStringExtra("format");
Object msg[] = (Object[]) bundle.get("pdus");
SmsMessage smsMessage[] = new SmsMessage[msg.length];
String fullMsg = "";
for(int i = 0; i < msg.length; i++){
//smsMessage[i] = SmsMessage.createFromPdu((byte[]) msg[i], format);
smsMessage[i] = SmsMessage.createFromPdu((byte[]) msg[i]);
fullMsg = fullMsg + smsMessage[i].getMessageBody();
}
String address = smsMessage[0].getOriginatingAddress();
senderText.setText(address);
contentText.setText(fullMsg);
}
}
}
class SendStatusReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if(getResultCode() == RESULT_OK){
Toast.makeText(SMSActivity.this, "send success", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(SMSActivity.this, "send fail", Toast.LENGTH_LONG).show();
}
}
}
}