短信相关的两个类

//SmsMessage类是用来创建短信的,也只管创建,比如设置短信内容,计算短信长度。
 SmsManager类是用来发送短信的。



********************************************


Android开发之SmsManager和SmsMessage

Android的手机功能(通话与短信)都放在android.telephony包中,到了4.4时(也就是API19)android.provider.Telephony及相关类横空出世辅助电话功能以及制定安卓世界手机功能的新秩序。 
短信功能用到了SmsManager和SmsMessage两个主要类。

 

接受短信广播,由Intent解析出短信内容明文, intent中的短信是以pud形式传出的,即byte[][]二位数组,

从Android 4.4开始,SmsMessage不推荐使用createFromPdu(byte[] pdu)
推荐使用createFromPdu(byte[], String)。
 createFromPdu(byte[], String)
The message format is passed in the SMS_RECEIVED_ACTION as the format String extra, and will be either "3gpp" for GSM/UMTS/LTE messages in 3GPP format or "3gpp2" for CDMA/LTE messages in 3GPP2 format.

第一个参数:意图为SMS_RECEIVED_ACTION中的PDU信息,是一个byte[]数组

第二个参数:通过上面的那段英文可以知道,第二个参数为"3gpp"(GSM/UMTS/LTE)或者"3gpp2"(CDMA/LTE)。所以第二个参数想要获取,可以通过

String format = intent.getStringExtra("format");
获取到,然后传入到形参中。

 
发送短信via Intent
万能的intent能够帮我们做很多事,只要你有“意图”它就会满足你。

复制代码
1 private void sendMessageViaSystem() {
2         Uri uri = Uri.parse("smsto:"+etNumber.getText());
3         Intent intent = new Intent(Intent.ACTION_VIEW,uri);
4         intent.putExtra("sms_body",etMessage.getText().toString());
5         startActivity(intent);
6     }
复制代码
发送短信via SmsManager
1 private void sendMessage() {        
2         SmsManager smsManager = SmsManager.getDefault();
3         smsManager.sendTextMessage(etNumber.getText().toString(), null,
4                 etMessage.getText().toString(), null, null);
5     }
最简单的发送短信条件就是有电话号码和短信内容,调用SmsManager的sendTextMessage方法即可。

监听短信的发送状态
sendTextMessage方法的后两个参数是PendingIntent,函数原型如下:

复制代码
 1    * @param sentIntent if not NULL this <code>PendingIntent</code> is
 2      *  broadcast when the message is successfully sent, or failed.
 3      *  The result code will be <code>Activity.RESULT_OK</code> for success,
 4      *  or one of these errors:<br>
 5      *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
 6      *  <code>RESULT_ERROR_RADIO_OFF</code><br>
 7      *  <code>RESULT_ERROR_NULL_PDU</code><br>
 8      *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
 9      *  the extra "errorCode" containing a radio technology specific value,
10      *  generally only useful for troubleshooting.<br>
11      *  The per-application based SMS control checks sentIntent. If sentIntent
12      *  is NULL the caller will be checked against all unknown applications,
13      *  which cause smaller number of SMS to be sent in checking period.
14      * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
15      *  broadcast when the message is delivered to the recipient.  The
16      *  raw pdu of the status report is in the extended data ("pdu").
17     public void sendTextMessage(
18             String destinationAddress, String scAddress, String text,
19             PendingIntent sentIntent, PendingIntent deliveryIntent) 
复制代码
而我们要监听发送状态就要用到这两个参数。与这个两个PendingIntent联系的是两个Broadcast Receiver,其会接收到发送过程中状态广播。就像上面参数解释的一样。 
代码示例如下:

复制代码
 1 private String SMS_SEND_ACTIOIN = "SMS_SEND";
 2     private String SMS_DELIVERED_ACTION = "SMS_DELIVERED";
 3 
 4     private SmsStatusReceiver mSmsStatusReceiver;
 5     private SmsDeliveryStatusReceiver mSmsDeliveryStatusReceiver;
 6 
 7     @Override
 8     protected void onResume() {
 9         super.onResume();
10         mSmsStatusReceiver = new SmsStatusReceiver();
11         registerReceiver(mSmsStatusReceiver,new IntentFilter(SMS_SEND_ACTIOIN));
12 
13         mSmsDeliveryStatusReceiver = new SmsDeliveryStatusReceiver();
14         registerReceiver(mSmsDeliveryStatusReceiver,new IntentFilter(SMS_DELIVERED_ACTION));
15     }
16 
17     @Override
18     protected void onPause() {
19         super.onPause();
20         unregisterReceiver(mSmsStatusReceiver);
21         unregisterReceiver(mSmsDeliveryStatusReceiver);
22     }
23 
24     private void sendMessage() {        
25         SmsManager smsManager = SmsManager.getDefault();
26         PendingIntent sentIntent = PendingIntent.getBroadcast(this, 0, new Intent(SMS_SEND_ACTIOIN), 0);
27         PendingIntent deliveryIntent = PendingIntent.getBroadcast(this, 0,
28                 new Intent(SMS_DELIVERED_ACTION), 0);
29         smsManager.sendTextMessage(etNumber.getText().toString(), null,
30                 etMessage.getText().toString(), sentIntent, deliveryIntent);
31         Log.d(TAG,"sent message.");
32     }
33 
34     public class SmsStatusReceiver extends BroadcastReceiver {
35 
36         @Override
37         public void onReceive(Context context, Intent intent) {
38             Log.d(TAG,"SmsStatusReceiver onReceive.");
39             switch(getResultCode()) {
40                 case Activity.RESULT_OK:
41                     Log.d(TAG, "Activity.RESULT_OK");
42                     break;
43                 case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
44                     Log.d(TAG, "RESULT_ERROR_GENERIC_FAILURE");
45                     break;
46                 case SmsManager.RESULT_ERROR_NO_SERVICE:
47                     Log.d(TAG, "RESULT_ERROR_NO_SERVICE");
48                     break;
49                 case SmsManager.RESULT_ERROR_NULL_PDU:
50                     Log.d(TAG, "RESULT_ERROR_NULL_PDU");
51                     break;
52                 case SmsManager.RESULT_ERROR_RADIO_OFF:
53                     Log.d(TAG, "RESULT_ERROR_RADIO_OFF");
54                     break;
55             }
56         }
57     }
58 
59     public class SmsDeliveryStatusReceiver extends BroadcastReceiver {
60 
61         @Override
62         public void onReceive(Context context, Intent intent) {
63             Log.d(TAG,"SmsDeliveryStatusReceiver onReceive.");
64             switch(getResultCode()) {
65                 case Activity.RESULT_OK:
66                     Log.i(TAG, "RESULT_OK");
67                     break;
68                 case Activity.RESULT_CANCELED:
69                     Log.i(TAG, "RESULT_CANCELED");
70                     break;
71             }
72         }
73     }
复制代码
 

 

短信接收
与发送状态监听类似,短信的接收也是用广播接收器。为了一直对短信广播的接收,我采用了在Manifest中注册广播的方法。

android:priority系统默认最大值为1000,但是为了获得最高优先级,可以设置为int的最大值,即2147483647
1 <receiver android:name="com.linc.intercept.SmsReceiver" >
2             <intent-filter android:priority="1000" >
3                 <action android:name="android.provider.Telephony.SMS_RECEIVED" />
4             </intent-filter>
5         </receiver>
并且将用一个单独类作为短信接收类(这样的方式是不能将其放到内部类中的)。

复制代码
 1 public class SmsReceiver extends BroadcastReceiver {
 2     private static final String TAG = "SmsReceiver";
 3     public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
 4 
 5     @Override
 6     public void onReceive(Context context, Intent intent) {
 7         String action = intent.getAction();
 8         Log.d(TAG,"action: "+action);
 9         if (SMS_RECEIVED_ACTION.equals(action)) {
10             Bundle bundle = intent.getExtras();
11             StringBuffer messageContent = new StringBuffer();
12             if (bundle != null) {
13                 Object[] pdus = (Object[]) bundle.get("pdus");
14                 for (Object pdu : pdus) {
15                     SmsMessage message = SmsMessage.createFromPdu((byte[]) pdu);
16                     String sender = message.getOriginatingAddress();
17                     Log.d(TAG,"sender: "+sender);
18                     if ("10086".equals(sender) || "10010".equals(sender) ||
19                             "10001".equals(sender)) {
20                         messageContent.append(message.getMessageBody());
21                     }
22                 }
23                 if(!messageContent.toString().isEmpty()) {
24                     Log.d(TAG,"send message broadcast.");
25                     Intent intentBroadcast = new Intent();
26                     intentBroadcast.putExtra("message", messageContent.toString());
27                     intentBroadcast.setAction("sms_received");
28                     context.sendBroadcast(intentBroadcast);
29                     Log.d(TAG, "send broadcast and abort");
30 //                    abortBroadcast();
31                 }
32             }
33         }
34     }
35 }
复制代码
但是这样做的弊端就是,接收到的短信如何显示到界面?路有多条,我最后还是选择了广播。

复制代码
 1 private SmsReceiver mSmsReceiver;
 2         @Override
 3     protected void onResume() {
 4         super.onResume();
 5         mSmsReceiver = new SmsReceiver();
 6         IntentFilter intentFilter = new IntentFilter();
 7         intentFilter.addAction("sms_received");
 8         registerReceiver(mSmsReceiver, intentFilter);
 9     }
10         @Override
11     protected void onPause() {
12         super.onPause();
13         unregisterReceiver(mSmsReceiver);
14     }
15     public class SmsReceiver extends BroadcastReceiver {
16         public static final String SMS_RECEIVED_ACTION = "sms_received";
17 
18         @Override
19         public void onReceive(Context context, Intent intent) {
20             String action = intent.getAction();
21             Log.d(TAG,"action: "+action);
22             if (SMS_RECEIVED_ACTION.equals(action)) {
23                 Bundle bundle = intent.getExtras();
24 
25                 String messageContent = bundle.getString("message");
26                 tvMessage.setText(messageContent);
27             }
28         }
29     }
复制代码

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容