I want unit test a SMS broadcast reveiver's onReceive method but don't know how to create the SMS intent. The onReceive method looks like this:
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction()
.equals("android.provider.Telephony.SMS_RECEIVED")) {
StringBuilder sb = new StringBuilder();
Bundle bundle = intent.getExtras();
if (bundle != null) {
SmsMessage[] messages = getMessagesFromIntent(intent);
}
}
}
private SmsMessage[] getMessagesFromIntent(Intent intent) {
SmsMessage retMsgs[] = null;
Bundle bdl = intent.getE开发者_如何学运维xtras();
try {
Object pdus[] = (Object[]) bdl.get("pdus");
retMsgs = new SmsMessage[pdus.length];
for (int n = 0; n < pdus.length; n++) {
byte[] byteData = (byte[]) pdus[n];
retMsgs[n] = SmsMessage.createFromPdu(byteData);
}
} catch (Exception e) {
Log.e("GetMessages", "fail", e);
}
return retMsgs;
}
Any tips?
/Christian
I think you are using the gsm version of SmsMessage. The gsm version is depreciated. SmsMessage works differently. You should have these imports: import android.telephony.SmsManager and import android.telephony.SmsMessage. The following code will extract the message body and originating address. The following code works in my broadcast receiver (note the individual pdu extraction).
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdus.length; i++) {
smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
originatingAddress = smsMessage.getOriginatingAddress();
if (!phoneNumber.equals(originatingAddress)) {
phoneNumber = originatingAddress; // Retain the last number if different
}
messageBody += smsMessage.getMessageBody() + "\n"; // concatenate all parts
}
}
The messageBody variable is set to "" earlier in the code.
For testing, just start an emulator and use the Emulator Control view to send text messages. You can get one by following the menu Windos->Show View->Other...->Emulator Control. The view has Telephony and GPS entry capabilities. Stuff a bunch of Log.d into the code and watch logcat...
you didn't described your question correctly,but wjat i get,you have difficulty in Message,sending,receiving or tracking. so for them:
1.Receive and show: (complete reference)
package com.shaikhhamadali.blogspot.textmessage;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast;
public class SMSReceiver extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
Bundle myBundle = intent.getExtras();
SmsMessage [] messages = null;
String strMessage = "";
if (myBundle != null)
{
//get message in pdus format(protocol discription unit)
Object [] pdus = (Object[]) myBundle.get("pdus");
//create an array of messages
messages = new SmsMessage[pdus.length];
for (int i = 0; i < messages.length; i++)
{
//Create an SmsMessage from a raw PDU.
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
//get the originating address (sender) of this SMS message in String form or null if unavailable
strMessage += "SMS From: " + messages[i].getOriginatingAddress();
strMessage += " : ";
//get the message body as a String, if it exists and is text based.
strMessage += messages[i].getMessageBody();
strMessage += "\n";
}
//show message in a Toast
Toast.makeText(context, strMessage, Toast.LENGTH_SHORT).show();
}
}
}
send messege: (complete reference)
package com.shaikhhamadali.blogspot.textmessage;
import java.util.Set; import android.os.Bundle; import android.app.Activity; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.telephony.SmsManager; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MessageSender extends Activity { private final static String TAG = "MessageSenderActivity"; private final static String INTENT_ACTION_SENT = "com.shaikhhamadali.blogspot.textmessage.INTENT_ACTION_SENT"; private final static String INTENT_ACTION_DELIVERY = "com.shaikhhamadali.blogspot.textmessage.INTENT_ACTION_DELIVERY"; private final static int REQUEST_CODE_ACTION_SENT = 1; private static final int REQUEST_CODE_ACTION_DELIVERY = 2; private BroadcastReceiver smsSentDeliveredReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_message_sender); //Receiver edit text final EditText eTReceiverNumebr = (EditText) findViewById(R.id.eTReceiverNo); //Sender edit text final EditText eTMessage = (EditText) findViewById(R.id.eTMessage); //Send Message Button Button btnSend = (Button) findViewById(R.id.btnSend); btnSend.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //get receiver number String number = eTReceiverNumebr.getText().toString(); //get message to send String message = eTMessage.getText().toString(); //call send sms message method to send the sms sendSMS(number, message); } }); //initialize broadcast receiver for message delivery initializeReceivers(); } private void sendSMS(String number, String message) { /*create intent instance and pass INTENT_ACTION_SENT * INTENT_ACTION_SENT is used to send an sms on GSM * */ Intent sentIntent = new Intent(INTENT_ACTION_SENT); /*create pendingintent instance and pass this as context instance,REQUEST_CODE_ACTION_SENT and FLAG_UPDATE_CURRENT * REQUEST_CODE_ACTION_SENT=1 defined at top * FLAG_UPDATE_CURRENT: Flag for use with getActivity(Context, int, Intent, int), * getBroadcast(Context, int, Intent, int), and getService(Context, int, Intent, int): * if the described PendingIntent already exists, then keep it but its replace * its extra data with what is in this new Intent. This can be used if you are * creating intents where only the extras change, and don't care that any * entities that received your previous PendingIntent will be able to launch * it with your new extras even if they are not explicitly given to it. * */ PendingIntent pendingSentIntent = PendingIntent.getBroadcast(this, REQUEST_CODE_ACTION_SENT, sentIntent, PendingIntent.FLAG_UPDATE_CURRENT); /*create intent instance and pass INTENT_ACTION_DELIVERY * INTENT_ACTION_DELIVERY is used to receive an sms delivery on GSM * */ Intent deliveryIntent = new Intent(INTENT_ACTION_DELIVERY); /*create pendingintent instance and pass this as context instance,REQUEST_CODE_ACTION_DELIVERY and FLAG_UPDATE_CURRENT * REQUEST_CODE_ACTION_DELIVERY=2 defined at top * FLAG_UPDATE_CURRENT:Flag for use with getActivity(Context, int, Intent, int), * getBroadcast(Context, int, Intent, int), and getService(Context, int, Intent, int): * if the described PendingIntent already exists, then keep it but its replace its * extra data with what is in this new Intent. This can be used if you are creating * intents where only the extras change, and don't care that any entities that received * your previous PendingIntent will be able to launch it with your new extras even if * they are not explicitly given to it. * */ PendingIntent pendingDeliveryIntent = PendingIntent.getBroadcast(this, REQUEST_CODE_ACTION_DELIVERY, deliveryIntent, PendingIntent.FLAG_UPDATE_CURRENT); //Create instance of SmsManager and get the default instance of the Sms manager SmsManager smsManager = SmsManager.getDefault(); /* Second parameter is the service center number. Use null if you want *to use the default number */ smsManager.sendTextMessage(number, null, message, pendingSentIntent, pendingDeliveryIntent); } @Override protected void onPause() { super.onPause(); unregisterReceiver(smsSentDeliveredReceiver); } @Override protected void onResume() { super.onResume(); //Create instance of intent filter and add actions we defined IntentFilter filter = new IntentFilter(INTENT_ACTION_SENT); filter.addAction(INTENT_ACTION_DELIVERY); //register receiver for our defined actions registerReceiver(smsSentDeliveredReceiver, filter); } private void initializeReceivers() { //sent sms delivery receiver smsSentDeliveredReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { //call process broadcasts method processBroadcasts(intent); } }; } private void processBroadcasts(Intent intent) { //get action String action = intent.getAction(); //log as info in logcat the received action Log.i(TAG, "Received: " + action); if (action.equals(INTENT_ACTION_SENT)) { Bundle bundle = intent.getExtras(); // can check for error messages //log as info in logcat that message sent Log.i(TAG, "Message: Sent"); //show toast that message sent Toast.makeText(this, "Message sent", Toast.LENGTH_LONG).show(); } else if (action.equals(INTENT_ACTION_DELIVERY)) { Bundle bundle = intent.getExtras(); Set<String> keys = bundle.keySet(); // can check for error messages //log as info in logcat that message Delivered Log.i(TAG, "Message: Delivered"); //show toast that message Delivered Toast.makeText(this, "Message delivered", Toast.LENGTH_LONG).show(); } } }
精彩评论