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 件のコメント:
コメントを投稿