开发者

Sending unique sms and receiving looong sms in android

So i have tried for a long time to find a way to make a app that can send and receive sms in android. That works fine. Here is the code:

For sending:

@SuppressWarnings("deprecation")
public void sendSMS(String phoneNumber, String message) {


    String SENT = "SMS_SENT";
    String DELIVERED = "SMS_DELIVERED";
    int unq = 0;
    Intent sent = new Intent(SENT);
    sent.putExtra("unq", unq);
    Intent delivered = new Intent(DELIVERED);
    delivered.putExtra("unq", unq);

 开发者_Python百科   PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, sent, 0);

    PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0,delivered, 0);

    // ---when the SMS has been sent---
    registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context arg0, Intent arg1) {

            switch (getResultCode()) {
            case Activity.RESULT_OK:
                Toast.makeText(getBaseContext(), "SMS sent",
                        Toast.LENGTH_SHORT).show();
                smsstatus = "0";
                smserror = "noError";
                //sendSmsStatus();
                break;
            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                Toast.makeText(getBaseContext(), "Generic failure",
                        Toast.LENGTH_SHORT).show();
                setSmsstatus("1");
                setSmserror("Generic failure");
                sendSmsStatus("Generic failure");
                break;
            case SmsManager.RESULT_ERROR_NO_SERVICE:
                Toast.makeText(getBaseContext(), "No service",
                        Toast.LENGTH_SHORT).show();
                setSmsstatus("2");
                setSmserror("No service");
                sendSmsStatus("No service");
                break;
            case SmsManager.RESULT_ERROR_NULL_PDU:
                Toast.makeText(getBaseContext(), "Null PDU",
                        Toast.LENGTH_SHORT).show();
                setSmsstatus("3");
                setSmserror("Null PDU");
                sendSmsStatus("Null PDU");
                break;
            case SmsManager.RESULT_ERROR_RADIO_OFF:
                Toast.makeText(getBaseContext(), "Radio off",
                        Toast.LENGTH_SHORT).show();
                setSmsstatus("4");
                setSmserror("Radio off");
                sendSmsStatus("Radio off");
                break;
            }

        }

    }, new IntentFilter(SENT));

    // ---when the SMS has been delivered---
    registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context arg0, Intent arg1) {

            switch (getResultCode()) {
            case Activity.RESULT_OK:
                Toast.makeText(getBaseContext(), "SMS delivered",
                        Toast.LENGTH_SHORT).show();

                break;
            case Activity.RESULT_CANCELED:
                Toast.makeText(getBaseContext(), "SMS not delivered",
                        Toast.LENGTH_SHORT).show();

                break;
            }

        }
    }, new IntentFilter(DELIVERED));

    SmsManager sms = SmsManager.getDefault();
    sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
}

For receiving:

public class SmsReceiver extends BroadcastReceiver {
@SuppressWarnings("deprecation")
@Override
public void onReceive(Context context, Intent intent) {
    // ---get the SMS message passed in---

    Bundle bundle = intent.getExtras();
    SmsMessage[] msgs = null;
    String str = "";
    Object sms = "";
    ArrayList<String> s = new ArrayList<String>();
    Manager m = Factory.getInstance().getManager();

    if (bundle != null) {
        // ---retrieve the SMS message received---
        Object[] pdus = (Object[]) bundle.get("pdus");
        msgs = new SmsMessage[pdus.length];
        for (int i = 0; i < msgs.length; i++) {
            msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
            str += "    SMS fra " + msgs[i].getOriginatingAddress() + "\n";
            str += "    Besked: ";
            str += msgs[i].getMessageBody().toString();
            str += "\n";
            sms = "SMS = "+msgs[i].getOriginatingAddress()+","+msgs[i].getMessageBody().toString();
            s.add(msgs[i].getOriginatingAddress());
            s.add(msgs[i].getMessageBody().toString());
        }
        // ---display the new SMS message---
        Toast.makeText(context, str, Toast.LENGTH_LONG).show();
        Manager.toastIt(context, str);              

        // Send the sms to the server
        //Connection.send(new Transmit("SmsReceived",s));
    }
}
}

This works great!.

And here comes the question. Is it posible to refactore my code to achive the following:

  1. Have a unique indentifier/flag on my send sms so i can make sure which sms i receive a status on. As you can see i have already tried to put extra on my 2 intents, and maybe that is the right way, but not only do i not now how to check/receive/extract the flag for the status, but also the flag really "unique" right now.

  2. Its nice that I can revieve a sms, but when its more than 160 chars it only shows me the first 160 chars. I had looked at how GTalkSMS does it, but was hoping my code could just be refactored a bit :)

  3. The last problem is, a mix of the 2 above. I cant send a sms thats more than 160 char. I know i have to use sendMultipartTextMessage, but i dont know how. My thought is that i could devide the "String message" by 100 to a Array but i dont know.

So feel free to refactore the code. I'm looking forward to see your replies! :D Please ask if you need anything explained better or more code! :)


Not Android specific, but read about the "Concatenated SMS" standard. Basically it's multiple messages that each specify they go with the previous one, but it goes over the air as entirely independent SMS.

Most phones hide this fact from the user, of course, but if you're directly receiving SMS it's likely you'll need to deal with it yourself - sending and receiving. Assuming Android uses this standard, which seems like a safe bet.

Since it's so common, I'm sure you can find a library that somebody's already written.

http://en.wikipedia.org/wiki/Concatenated_SMS


Everything you asked for is in the GTalkSMS code (seems you have missed it). :-) But I will point you to the right snippets.

In order to use sendMultipartTextMessage() and distinguish the different sent/delivered notification intents you need first to split the message string via SmsManager.divideMessage(message) and create two, one for sent notifications and one for the delivered notifications, PendingIntents ArrayLists, where, and this is the important part, every PendingIntent has to be created with a a unique request int:

PendingIntent.getBroadcast(context, UNIQUE_ID, deliveredIntent, PendingIntent.FLAG_ONE_SHOT)

This assures that andoird will broadcast an unique intent for every sent delivered notification. You can also add some extras to the intent, which could later tell you for which SMS the notification was. Code snippets can be found here: sendSMSByPhoneNumber()

Make sure that your SmsReceiver is aware that an incoming intent can contain more that one SMS for multiple senders, but a maximum of nbfOfpdus different senders. The GTalkSMS receiver will sure help you understand how to get this going. :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜