2011年5月17日火曜日

AndroidStudyMemo=Using SMS

SMS usage has become ubiquitous in the last several years. Integrating messaging services,

even if only outbound, to an application can provide familiar social functionality to the

user. SMS functionality is provided to applications through the android.telephony

package.

 

Gaining Permission to Send and Receive SMS Messages

SMS functionality requires two different permissions, depending on if the application

sends or receives messages.The following XML, to be placed with AndroidManifest.xml,

shows the permissions needed for both actions:

              <uses-permission

              android:name="android.permission.SEND_SMS" />

              <uses-permission

              android:name="android.permission.RECEIVE_SMS" />

 

Sending an SMS

To send an SMS, an application first needs to get an instance of the SmsManager. Unlike

other system services, this is achieved by calling the static method getDefault() of

SmsManager:

              final SmsManager sms = SmsManager.getDefault();

Now that the application has the SmsManager, sending SMS is as simple as a single call:

              sms.sendTextMessage(

              "9995551212", null, "Hello!", null, null);

 

The application does not know if the actual sending of the SMS was successful without

providing a PendingIntent to receive the broadcast of this information.The following

code demonstrates configuring a PendingIntent to listen for the status of the SMS:

 

              Intent msgSent = new Intent("ACTION_MSG_SENT");

              final PendingIntent pendingMsgSent =

                            PendingIntent.getBroadcast(this, 0, msgSent, 0);

              registerReceiver(new BroadcastReceiver() {

                            public void onReceive(Context context, Intent intent) {

                                                        int result = getResultCode();

                                                        if (result != Activity.RESULT_OK) {

                                                                      Log.e("telephony",

                                                                      "SMS send failed code = " + result);

                                                                      pendingMsgReceipt.cancel();

                                                        } else {

                                                                      messageEntry.setText("");

                                                        }

                                          }

                            }, new IntentFilter("ACTION_MSG_SENT"));

 

The PendingIntent pendingMsgSent can be used with the call to the

sendTextMessage().The code for the message-received receipt is similar but is called

when the sending handset receives acknowledgment from the network that the destination

handset received the message.

 

If we put all this together with the preceding phone number formatting EditText, a

new entry field for the message, and a button,we can create a simple form for sending an

SMS message.The code for the button handling looks like the following:

 

              Button sendSMS = (Button) findViewById(R.id.send_sms);

                            sendSMS.setOnClickListener(new View.OnClickListener() {

                                          public void onClick(View v) {

                                                        String destination =

                                                                      numberEntry.getText().toString();

                                                        String message =

                                                                      messageEntry.getText().toString();

                                                        sms.sendTextMessage(destination, null, message,

                                                                      pendingMsgSent, pendingMsgReceipt);

                                                        registerReceiver(...);

                                          }

                            }

 

Within this application,we used the emulator "phone number" trick (its port number).This is a

great way to test sending SMS messages without using hardware or without incurring

charges by the handset operator.

 

A great way to extend this would be to set the sent receiver to modify a graphic on the

screen until the sent notification is received. Further, you could use another graphic to indicate

when the recipient has received the message.Alternatively, you could use

ProgressBar widgets track the progress to the user.

 

 

Receiving an SMS

Applications can also receive SMS messages.To do so, your application must register a

BroadcastReceiver to listen for the Intent action associated with receiving an SMS.An

application listening to SMS in this way doesn't prevent the message from getting to other

applications.

 

Expanding on the previous example, the following code shows how any incoming text

message can be placed within a TextView on the screen:

 

              final TextView receivedMessage = (TextView)findViewById(

              R.id.received_message);

              rcvIncoming = new BroadcastReceiver() {

                            public void onReceive(Context context, Intent intent) {

                                          Log.i("telephony", "SMS received");

                                          Bundle data = intent.getExtras();

                                          if (data != null) {

                                                        Object pdus[] =

                                                                      (Object[]) data.get("pdus");

                                                        String message = "New message:\n";

                                                        String sender = null;

                                                        for (Object pdu : pdus) {

                                                                      SmsMessage part = SmsMessage.

                                                                      createFromPdu((byte[])pdu);

                                                                      message += part.

                                                                      getDisplayMessageBody();

                                                                      if (sender == null) {

                                                                                    sender = part.

                                                                                    getDisplayOriginatingAddress();

                                                                      }

                                                        }

                                                        receivedMessage.setText(

                                                        message + "\nFrom: "+sender);

                                                        numberEntry.setText(sender);

                                          }

                            }

              };

              registerReceiver(rcvIncoming, new IntentFilter(

                            "android.provider.Telephony.SMS_RECEIVED"));

 

This block of code is placed within the onCreate() method of the Activity. First, the

message Bundle is retrieved. In it, an array of Objects holds several byte arrays that contain

PDU data?the data format that is customarily used by wireless messaging protocols.

Luckily, the Android SDK can decode these with a call to the static

SmsMessage.createFromPdu() utility method. From here,we can retrieve the body of

the SMS message by calling getDisplayMessageBody().

 

The message that comes in might be longer than the limitations for an SMS. If it is, it

will have been broken up in to a multipart message on the sending side.To handle this,we

loop through each of the received Object parts and take the corresponding body from

each, while only taking the sender address from the first.

 

Next, the code updates the text string in the TextView to show the user the received

message.The sender address is also updated so that the recipient can respond with less typing.

Finally,we register the BroadcastReceiver with the system.The IntentFilter used

here, android.provider.Telephony.SMS_RECEIVED, is a well-known but undocumented

IntentFilter used for this.As such,we have to use the string literal for it.

 

0 件のコメント:

コメントを投稿