第一行代码-8.2 接收和发送短信

来源:互联网 发布:ubuntu磁盘一直不足 编辑:程序博客网 时间:2024/05/01 12:22

  接收和发送短信也是通过调用Android提供的API实现的,所以我们自己也可以实现短信应用。
1、接收短信
  当手机接收到一条信息的时候,系统会发送一条名为android.provider.Telephony.SMS_RECEIVED的广播,这条广播里
携带着与短信相关的所有数据。每个应用程序都可以在广播接收器里对它进行监听,收到广播时再从中解析出短信的内容即可。
  首先新建SMSTest项目,然后设置布局:

<!-- SMSTest-activity_main.xml --><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <LinearLayout        android:layout_width="match_parent"        android:layout_height="50dp" >        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:padding="10dp"            android:text="From:" />        <TextView            android:id="@+id/sender"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical" />    </LinearLayout>    <LinearLayout android:layout_width="match_parent"        android:layout_height="50dp" >        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:padding="10dp"            android:text="Content:" />        <TextView            android:id="@+id/content"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical" />    </LinearLayout></LinearLayout>


  然后在MainActivity中新建内部类MessageReceiver继承BroadcastReceiver,用于接收广播。

// MainActivity.javaclass MessageReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        Bundle bundle = intent.getExtras();        Object[] pdus = (Object[]) bundle.get("pdus"); // 提取短信消息        SmsMessage[] messages = new SmsMessage[pdus.length];        for (int i = 0; i < pdus.length; i++) {            messages[i] = SmsMessage.createFromPdu((byte[])pdus[i]);        }        String address = messages[0].getOriginatingAddress(); // 获取发送方号码        String fullMessage = "";        for (SmsMessage message : messages) {            fullMessage += message.getDisplayMessageBody(); // 获取短信内容        }        sender.setText(address);        content.setText(fullMessage);    }

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

// MainActivity.java@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    sender = (TextView) findViewById(R.id.sender);    content = (TextView) findViewById(R.id.content);    receiveFilter = new IntentFilter();    receiveFilter.addAction("android.provider.Telephony.SMS_RECEIVED");    messageReceiver = new MessageReceiver();    registerReceiver(messageReceiver, receiveFilter);}@Overrideprotected void onDestroy() {    unregisterReceiver(messageReceiver);    super.onDestroy();}

  最后添加接收短信的权限:

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

  (但是在手机上却接收不了短信,不知道是不是手机的问题,待解决)

2、拦截短信
  现在我们有自己接收短信的应用,系统的接收广播就没有必要了,由于短信是一个有序广播,所以可以用之前拦截广播的方式,在自己的应用中将短信拦截掉。关键的两行代码:

receiveFilter.setPriority(100);abortBroadcast();

  但是这会导致系统无法接收到短信,可能会造成数据的丢失,所以使用这个功能需要慎重考虑。

3、发送短信
  首先在activity_main.xml中添加如下代码:

<LinearLayout android:layout_width="match_parent"        android:layout_height="50dp" >        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:padding="10dp"            android:text="To:" />        <EditText            android:id="@+id/to"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:layout_weight="1" />    </LinearLayout>    <LinearLayout android:layout_width="match_parent"        android:layout_height="50dp" >        <EditText            android:id="@+id/msg_input"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:layout_weight="1" />        <Button            android:id="@+id/send"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            android:text="Send" />    </LinearLayout>

  然后定义发送按钮的点击事件:

to = (EditText) findViewById(R.id.to);        msgInput = (EditText) findViewById(R.id.msg_input);        send = (Button) findViewById(R.id.send);        send.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View arg0) {                SmsManager smsManager = SmsManager.getDefault();                smsManager.sendTextMessage(to.getText().toString(), null, msgInput.getText().toString(), null, null);            }        });

  其中,sendTextMessage有五个参数,第一个参数是发送号码,第三个参数是发送内容,其他三个参数暂时用不上。
  最后是发送短信的权限:

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

  做到这一步,其实已经可以发送短信了。但是短信究竟有没有发送成功并不知道,这个时候就可以用到第四个参数:sendIntent了。这里也是用PendingIntent,因为是“合适时机的提醒”。

sendFilter = new IntentFilter();sendFilter.addAction("SENT_SMS_ACTION");sendStatusReceiver = new SendStatusReceiver();registerReceiver(sendStatusReceiver, sendFilter);send.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View arg0) {        // 发送短信        SmsManager smsManager = SmsManager.getDefault();        // 发送广播,提醒短信发送成功        Intent sendIntent = new Intent("SENT_SMS_ACTION");        PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, 0, sendIntent, 0);        smsManager.sendTextMessage(to.getText().toString(), null, msgInput.getText().toString(), pi, null);    }});class SendStatusReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        if (getResultCode() == RESULT_OK) {            // 短信发送成功            Toast.makeText(context, "短信发送成功", Toast.LENGTH_LONG).show();        }        else {            // 短信发送失败            Toast.makeText(context, "短信发送失败", Toast.LENGTH_LONG).show();        }    }}@Overrideprotected void onDestroy() {    unregisterReceiver(messageReceiver);    unregisterReceiver(sendStatusReceiver);    super.onDestroy();}

  PendingIntent的写法还是要注意的,这里的广播不需要用sendBroadcast发送了,而是等短信发送成功之后自动发送。
  实现效果:

0 0
原创粉丝点击