Android学习笔记(二十二)——短信接收与发送

        //此系列博文是《第一行Android代码》的学习笔记,如有错漏,欢迎指正!

        当手机接收到一条短信的时候, 系统会发出一条值为 android.provider.Telephony.SMS_RECEIVED 的广播, 这条广播里携带着与短信相关的所有数据。每个应用程序都可以在广播接收器里对它进行监听,收到广播时再从中解析出短信的内容即可。下面让我们一起来实践一下吧。

 

一、新建项目,构建布局文件:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent"
 4     android:orientation="vertical" >
 5     <LinearLayout
 6         android:layout_width="match_parent"
 7         android:layout_height="50dp" >
 8         <TextView
 9             android:layout_width="wrap_content"
10             android:layout_height="wrap_content"
11             android:layout_gravity="center_vertical"
12             android:padding="10dp"
13             android:text="From:" />
14         <TextView
15             android:id="@+id/sender"
16             android:layout_width="wrap_content"
17             android:layout_height="wrap_content"
18             android:layout_gravity="center_vertical" />
19     </LinearLayout>
20     <LinearLayout
21     android:layout_width="match_parent"
22     android:layout_height="50dp" >
23         <TextView
24             android:layout_width="wrap_content"
25             android:layout_height="wrap_content"
26             android:layout_gravity="center_vertical"
27             android:padding="10dp"
28             android:text="Content:" />
29         <TextView
30             android:id="@+id/content"
31             android:layout_width="wrap_content"
32             android:layout_height="wrap_content"
33             android:layout_gravity="center_vertical" />
34     </LinearLayout>
35 </LinearLayout>
View Code

        在布局文件中,我们添加了两个 LinearLayout,用于显示两行数据。分别用于显示短信的发送方和短信的内容。

 

二、构建内部类MessageReceiver:

 1 class MessageReceiver extends BroadcastReceiver {
 2         @Override
 3         public void onReceive(Context context, Intent intent) {
 4             Bundle bundle = intent.getExtras();
 5             Object[] pdus = (Object[]) bundle.get("pdus"); //  提取短信消息
 6             SmsMessage[] messages = new SmsMessage[pdus.length];
 7             for (int i = 0; i < messages.length; i++) {
 8                 messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
 9             }
10             String address = messages[0].getOriginatingAddress(); //  获取发送方号码
11             String fullMessage = "";
12             for (SmsMessage message : messages) {
13                 fullMessage += message.getMessageBody(); //  获 取短信内容
14             }
15             sender.setText(address);
16             content.setText(fullMessage);
17         }
18     }
View Code

       在 MainActivity中新建内部类MessageReceiver并使其继承于BroadcastReceiver类,我们从 Intent参数中取出了一个 Bundle 对象, 然后使用 pdu密钥来提取一个 SMS pdus 数组,其中每一个 pdu 都表示一条短信消息。接着使用 SmsMessage 的createFromPdu()方法将每一个 pdu 字节数组转换为 SmsMessage 对象,调用这个对象的getOriginatingAddress()方法就可以获取到短信的发送方号码,调用 getMessageBody()方法就可以获取到短信的内容,然后将每一个 SmsMessage 对象中的短信内容拼接起来,就组成了一条完整的短信。最后将获取到的发送方号码和短信内容显示在TextView上。

 

三、添加主活动逻辑:

 1 public class MainActivity extends AppCompatActivity {
 2 
 3     private TextView sender;
 4     private TextView content;
 5     private IntentFilter receiveFilter;
 6     private MessageReceiver messageReceiver;
 7     @Override
 8     protected void onCreate(Bundle savedInstanceState) {
 9         super.onCreate(savedInstanceState);
10         setContentView(R.layout.activity_main);
11         sender = (TextView) findViewById(R.id.sender);
12         content = (TextView) findViewById(R.id.content);
13         receiveFilter = new IntentFilter();
14         receiveFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
15         messageReceiver = new MessageReceiver();
16         registerReceiver(messageReceiver, receiveFilter);
17     }
18 
19 
20     @Override
21     protected void onDestroy() {
22         super.onDestroy();
23         unregisterReceiver(messageReceiver);
24     }
25     class MessageReceiver extends BroadcastReceiver {
26         @Override
27         public void onReceive(Context context, Intent intent) {
28             Bundle bundle = intent.getExtras();
29             Object[] pdus = (Object[]) bundle.get("pdus"); //  提取短信消息
30             SmsMessage[] messages = new SmsMessage[pdus.length];
31             for (int i = 0; i < messages.length; i++) {
32                 messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
33             }
34             String address = messages[0].getOriginatingAddress(); //  获取发送方号码
35             String fullMessage = "";
36             for (SmsMessage message : messages) {
37                 fullMessage += message.getMessageBody(); //  获 取短信内容
38             }
39             sender.setText(address);
40             content.setText(fullMessage);
41         }
42     }
43 
44 }
View Code

       主活动中运用了动态注册广播的技术。在 onCreate()方法中我们先对 MessageReceiver 进行注册,然后在 onDestroy()方法中再对它取消注册。

 

四、权限的声明:

<uses-permission android:name="android.permission.RECEIVE_SMS" />

       我们想要程序接收到系统短信是需要取得系统权限的。

       最后程序的运行效果如图:

      

 

        既然已经能够接收短信了,我们顺便天添加发送短信的功能。

五、修改布局文件:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent"
 4     android:orientation="vertical" >
 5     <LinearLayout
 6         android:layout_width="match_parent"
 7         android:layout_height="50dp" >
 8         <TextView
 9             android:layout_width="wrap_content"
10             android:layout_height="wrap_content"
11             android:layout_gravity="center_vertical"
12             android:padding="10dp"
13             android:text="From:" />
14         <TextView
15             android:id="@+id/sender"
16             android:layout_width="wrap_content"
17             android:layout_height="wrap_content"
18             android:layout_gravity="center_vertical" />
19     </LinearLayout>
20     <LinearLayout
21     android:layout_width="match_parent"
22     android:layout_height="50dp" >
23         <TextView
24             android:layout_width="wrap_content"
25             android:layout_height="wrap_content"
26             android:layout_gravity="center_vertical"
27             android:padding="10dp"
28             android:text="Content:" />
29         <TextView
30             android:id="@+id/content"
31             android:layout_width="wrap_content"
32             android:layout_height="wrap_content"
33             android:layout_gravity="center_vertical" />
34     </LinearLayout>
35     <LinearLayout
36         android:layout_width="match_parent"
37         android:layout_height="50dp" >
38         <TextView
39             android:layout_width="wrap_content"
40             android:layout_height="wrap_content"
41             android:layout_gravity="center_vertical"
42             android:padding="10dp"
43             android:text="To:" />
44         <EditText
45             android:id="@+id/to"
46             android:layout_width="0dp"
47             android:layout_height="wrap_content"
48             android:layout_gravity="center_vertical"
49             android:layout_weight="1" />
50     </LinearLayout>
51 
52     <LinearLayout
53         android:layout_width="match_parent"
54         android:layout_height="50dp" >
55         <EditText
56             android:id="@+id/msg_input"
57             android:layout_width="0dp"
58             android:layout_height="wrap_content"
59             android:layout_gravity="center_vertical"
60             android:layout_weight="1" />
61         <Button
62             android:id="@+id/send"
63             android:layout_width="wrap_content"
64             android:layout_height="wrap_content"
65             android:layout_gravity="center_vertical"
66             android:text="Send" />
67     </LinearLayout>
68 </LinearLayout>
View Code

      我们又新增了两个 LinearLayout,分别用于手机号码和内容。

 

六、修改主活动代码:

  1 package com.mycompany.notificationtest;
  2 
  3 import android.app.Notification;
  4 import android.app.NotificationManager;
  5 import android.app.PendingIntent;
  6 import android.content.BroadcastReceiver;
  7 import android.content.Context;
  8 import android.content.Intent;
  9 import android.content.IntentFilter;
 10 import android.support.v7.app.AppCompatActivity;
 11 import android.os.Bundle;
 12 import android.telephony.SmsManager;
 13 import android.telephony.SmsMessage;
 14 import android.view.View;
 15 import android.widget.Button;
 16 import android.widget.EditText;
 17 import android.widget.TextView;
 18 import android.widget.Toast;
 19 
 20 public class MainActivity extends AppCompatActivity {
 21 
 22     private TextView sender;
 23     private TextView content;
 24     private IntentFilter receiveFilter;
 25     private MessageReceiver messageReceiver;
 26     private EditText to;
 27     private EditText msgInput;
 28     private Button send;
 29     private IntentFilter sendFilter;
 30     private SendStatusReceiver sendStatusReceiver;
 31 
 32     @Override
 33     protected void onCreate(Bundle savedInstanceState) {
 34         super.onCreate(savedInstanceState);
 35         setContentView(R.layout.activity_main);
 36         sender = (TextView) findViewById(R.id.sender);
 37         content = (TextView) findViewById(R.id.content);
 38         receiveFilter = new IntentFilter();
 39         receiveFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
 40         messageReceiver = new MessageReceiver();
 41         registerReceiver(messageReceiver, receiveFilter);
 42         
 43         to = (EditText)findViewById(R.id.to);
 44         msgInput = (EditText)findViewById(R.id.msg_input);
 45         send = (Button)findViewById(R.id.send);
 46         send.setOnClickListener(new View.OnClickListener() {
 47             @Override
 48             public void onClick(View v) {
 49                 SmsManager smsManager = SmsManager.getDefault();
 50                 Intent sentIntent = new Intent("SENT_SMS_ACTION");
 51                 PendingIntent pi = PendingIntent.getBroadcast
 52                         (MainActivity.this, 0, sentIntent, 0);
 53                 smsManager.sendTextMessage(to.getText().toString(), null,
 54                         msgInput.getText().toString(), pi, null);
 55 
 56             }
 57         });
 58 
 59         sendFilter = new IntentFilter();
 60         sendFilter.addAction("SENT_SMS_ACTION");
 61         sendStatusReceiver = new SendStatusReceiver();
 62         registerReceiver(sendStatusReceiver, sendFilter);
 63     }
 64 
 65 
 66     @Override
 67     protected void onDestroy() {
 68         super.onDestroy();
 69         unregisterReceiver(messageReceiver);
 70         unregisterReceiver(sendStatusReceiver);
 71     }
 72     class MessageReceiver extends BroadcastReceiver {
 73         @Override
 74         public void onReceive(Context context, Intent intent) {
 75             Bundle bundle = intent.getExtras();
 76             Object[] pdus = (Object[]) bundle.get("pdus"); //  提取短信消息
 77             SmsMessage[] messages = new SmsMessage[pdus.length];
 78             for (int i = 0; i < messages.length; i++) {
 79                 messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
 80             }
 81             String address = messages[0].getOriginatingAddress(); //  获取发送方号码
 82             String fullMessage = "";
 83             for (SmsMessage message : messages) {
 84                 fullMessage += message.getMessageBody(); //  获 取短信内容
 85             }
 86             sender.setText(address);
 87             content.setText(fullMessage);
 88         }
 89     }
 90 
 91 
 92     class SendStatusReceiver extends BroadcastReceiver {
 93         @Override
 94         public void onReceive(Context context, Intent intent) {
 95             if (getResultCode() == RESULT_OK) {
 96 //  短信发送成功
 97                 Toast.makeText(context, "Send succeeded", Toast.LENGTH_LONG).show();
 98             } else {
 99 //  短信发送失败
100                 Toast.makeText(context, "Send failed", Toast.LENGTH_LONG).show();
101             }
102         }
103 
104     }
105 }
View Code

       我们先获取到了布局文件中新增控件的实例,然后在 Send 按钮的点击事件里面处理了发送短信的具体逻辑。当 Send 按钮被点击时,会先调用 SmsManager 的getDefault()方法获取到 SmsManager的实例,然后再调用它的 sendTextMessage()方法就可以去发送短信了。sendTextMessage()方法接收五个参数,其中第一个参数用于指定接收人的手机号码,第三个参数用于指定短信的内容,其他的几个参数我们暂时用不到,直接传入 null就可以了。

 

七、修改权限:

<uses-permission android:name="android.permission.SEND_SMS" />

 

     在manifest文件中加入上述发送短信的权限声明就大功告成了。

 

 

   //End.

posted @ 2016-05-17 20:14  Vincent_Bryan  阅读(278)  评论(2编辑  收藏  举报