B4A Library PhoneLibrary: Updated PhoneSms.Send

Discussion in 'Additional libraries, classes and official updates' started by Sorin Pohontu, Apr 2, 2015.

  1. Sorin Pohontu

    Sorin Pohontu Member Licensed User

    Hello Erel.

    As seen on this forum post, SmsSentStatus / SmsDelivered might not return the correct PhoneNumber.
    Also, current implementation of Send/Send2 will not work correctly is the message is longer than 160 chars.

    I've seen somewhere a post from Erel about original Java function for Send/Send2 and I've tried to find a working solution.

    1. Original function PhoneSms.Send2 is using the same requestCode for sending / pending Intent (0) with flag FLAG_UPDATE_CURRENT (134217728). On subsequent messages, the Intent data is updated / overwritten. The solution is to use an unique Intent requestCode for each message sent.

    2. I needed a working solution for MultiPart Messages.

    3. I needed additional data when sending a message. Current Send2 adds only PhoneNumber in Intent extra data:
    Code:
    i1.putExtra("phone", PhoneNumber);
    My current solution is using Java inline code (thanks for that in B4A since 4.30) and I think it would be nice to have this in official Phone library.

    Code:
    #If JAVA
    import java.util.Random;
    import java.util.ArrayList;
    import java.util.Map;
    import android.content.Context;
    import android.content.Intent;
    import android.app.PendingIntent;
    import android.telephony.SmsManager;

    public static void Send3(String PhoneNumber, String Text, Map<String, String> Extra, boolean ReceiveSentNotification, boolean ReceiveDeliveredNotification) {
        SmsManager sm = SmsManager.getDefault();

        /* Generate a unique requestCode for each Intent */
        Random randomNo = new Random();
        int requestCode = (int)(System.currentTimeMillis()/1000) + randomNo.nextInt(1000);

        Intent mSendIntent = new Intent("b4a.smssent");
        mSendIntent.putExtra("phone", PhoneNumber);

        // Add additional Extra Data
        for (Map.Entry<String, String> entry : Extra.entrySet()) {
            mSendIntent.putExtra(entry.getKey(), entry.getValue());
        }
        PendingIntent sentIntent = ReceiveSentNotification ? PendingIntent.getBroadcast(BA.applicationContext, requestCode, mSendIntent, PendingIntent.FLAG_UPDATE_CURRENT) : null;

        Intent mDeliveryIntent = new Intent("b4a.smsdelivered");
        mDeliveryIntent.putExtra("phone", PhoneNumber);

        // Add additional Extra Data
        for (Map.Entry<String, String> entry : Extra.entrySet()) {
            mDeliveryIntent.putExtra(entry.getKey(), entry.getValue());
        }
        PendingIntent deliveryIntent = ReceiveDeliveredNotification ? PendingIntent.getBroadcast(BA.applicationContext, requestCode, mDeliveryIntent, PendingIntent.FLAG_UPDATE_CURRENT) : null;

        if (Text.length() > 160) {
            ArrayList<String> parts = sm.divideMessage(Text);
            int numParts = parts.size();
            ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>();
            ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>();
            for (int i = 0; i < numParts; i++) {
                if (ReceiveSentNotification) {
                    sentIntents.add(PendingIntent.getBroadcast(BA.applicationContext, requestCode, mSendIntent, PendingIntent.FLAG_UPDATE_CURRENT));
                }
                if (ReceiveDeliveredNotification) {
                    deliveryIntents.add(PendingIntent.getBroadcast(BA.applicationContext, requestCode, mDeliveryIntent, PendingIntent.FLAG_UPDATE_CURRENT));
                }
            }
            sm.sendMultipartTextMessage(PhoneNumber, null, parts, ReceiveSentNotification ? sentIntents : null, ReceiveDeliveredNotification ? deliveryIntents : null);
        }
        else {
            sm.sendTextMessage(PhoneNumber, null, Text, sentIntent, deliveryIntent);
        }
    }
    #End If
    Usage with message as a Map:
    Code:
    Sub SendSMS(Message As Map)
       
    Dim Extra As Map

       
    ' Extra Data
       Extra.Initialize
       Extra.Put(
    "message_id""xxxx")

       NativeMe.RunMethod(
    "Send3"Array(Message.Get("to"), Message.Get("message"), Extra, truetrue))
    End Sub
    Now, In SmsSentStatus / SmsDelivered, I can extract Extra info with:
    Code:
    Log(Intent.GetExtra("phone"))
    Log(Intent.GetExtra("message_id"))
    I'm looking forward for feedback :)

    Have a nice day,
    /Sorin
     
    Last edited: Apr 2, 2015
  2. Tayfur

    Tayfur Well-Known Member Licensed User

    I added something for fix

    add lib : javaobject

    Code:
    Sub Globals
         
    Public NativeMe As JavaObject
    end sub

    Sub SendSMS(Message As Map)
       
    Dim Extra As Map

       
    ' Extra Data
       Extra.Initialize
       Extra.Put(
    "message_id""msj_id_"&Message.Get("to"))
        NativeMe=Me 
    ' >>> I add it
       NativeMe.RunMethod("Send3"Array(Message.Get("to"), Message.Get("message"), Extra, TrueTrue))
    End Sub
     
  3. Sorin Pohontu

    Sorin Pohontu Member Licensed User

    NativeMe Object should be initialized, I assumed in this example that is initialized before :)
     
  4. Tayfur

    Tayfur Well-Known Member Licensed User


    it is work; I looked some error and i searched for fix (Because I am not expert, I dont know java).
    I use your code.
    finally your code is work. nice job.
    thanks.
     
  5. Sorin Pohontu

    Sorin Pohontu Member Licensed User

    Glad that my code helped you :)
     
  6. Jeffrey Cameron

    Jeffrey Cameron Active Member Licensed User

    Thank you Sorin! +1 for adding this to the Phone library as a PhoneSms method.

    In the application I am developing I need to keep track of the messages I've sent (reply to middle-ware server that they were or were not sent out) and most likely I could have multiple messages to the same telephone number which would make knowing which exact message was sent impossible.

    I remembered coming across this post some time ago while I was looking for something else. And while implementing Sorin's code it is not difficult, it did take me almost 40 minutes of searching through the forum to find this exact post (perhaps my search skills are just lacking). So, having a built-in .Send3 method would have been much easier ;)
     
    Jehoschua likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice