Android Question SMS delivery report

pxpto

Member
Licensed User
Hi,

I 'm working on an app that sends SMS and receives the delivery reports. My problem is that I need to match the delivery report with the sent SMS. Matching the Sent/Report by phone number is not an option because I can send several SMS to the same number.

This is my test code:

B4X:
Sub Globals
    Dim ThisPhoneSms As PhoneSms   
    Dim PhoneId As PhoneId
    Dim PE As PhoneEvents   
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("deliveryreporttest.bal")

    PE.InitializeWithPhoneState("PE", PhoneId)
   
    ThisPhoneSms.Send2("+xxxxxxxxxxxx", "Test", True, True)
End Sub


Sub PE_SmsSentStatus (Success As Boolean, ErrorMessage As String, PhoneNumber As String, Intent As Intent)
    Log("--- PE_SmsSentStatus ---")
   
    Log("Success:" & Success)
    Log("ErrorMessage:" & ErrorMessage)
    Log("PhoneNumber:" & PhoneNumber)
   
    Log("Sent Intent: " & Intent)
    Log("Sent Intent GetData: " & Intent.GetData)
    Log("Sent Intent Action: " & Intent.Action)
    Log("Sent Intent Flags: " & Intent.Flags)
    Log("Sent Intent ExtrasToString: " & Intent.ExtrasToString)
End Sub


Sub PE_SmsDelivered (PhoneNumber As String, Intent As Intent)
    Log("--- PE_SmsDelivered ---")
   
    Log("PhoneNumber:" & PhoneNumber)
   
    Log("Delivered Intent: " & Intent)
    Log("Delivered Intent GetData: " & Intent.GetData)
    Log("Delivered Intent Action: " & Intent.Action)
    Log("Delivered Intent Flags: " & Intent.Flags)
    Log("Delivered Intent ExtrasToString: " & Intent.ExtrasToString)
    Log("Delivered Intent GetExtra(PDU): " & Intent.GetExtra("pdu"))
   
    Dim bc As ByteConverter
    Log("Decoded PDU: " & bc.HexFromBytes(Intent.GetExtra("pdu")))
End Sub

The log I get:

** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
--- PE_SmsSentStatus ---
Success:true
ErrorMessage:OK
PhoneNumber:+xxxxxxxxxxxx
Sent Intent: (Intent) Intent { act=b4a.smssent flg=0x10 (has extras) }
Sent Intent GetData: null
Sent Intent Action: b4a.smssent
Sent Intent Flags: 16
Sent Intent ExtrasToString: Bundle[{pdu_size=18, phone=+xxxxxxxxxxxx}]
--- PE_SmsDelivered ---
PhoneNumber:+xxxxxxxxxxxx
Delivered Intent: (Intent) Intent { act=b4a.smsdelivered flg=0x10 (has extras) }
Delivered Intent GetData: null
Delivered Intent Action: b4a.smsdelivered
Delivered Intent Flags: 16
Delivered Intent ExtrasToString: Bundle[{pdu=[B@41684508, phone=+xxxxxxxxxxxx, format=3gpp}]
Delivered Intent GetExtra(PDU): [B@41684508
Decoded PDU: 07910000000000F406880C91000000000006610131213075406101312130954000

I've hidden the destination number for privacy issues.

So, I see in the log that the SMS was sent and delivered.

When the SMS is delivered, I can see its PDU. Using this website to decode it, I can see that there is a value called "Reference" (Value "137") that is incremented automatically on each SMS I send.

(great article on how to decude PDU messages here)

According to the GSM specification, this "Reference" value in the delivery report is called TP-MR. It is the same as the TP-MR of the sent SMS for which the delivery report has been received.

This is exactly what I need: I need to know the reference number (TP-MR) of the sent SMS so that when I receive the delivery report I can match it with its reference number (TP-MR).

Does anyone know how to do this?

Regards,
Jorge
 

pxpto

Member
Licensed User
Thank you for your suggestion Earl. That was exactly what I needed.

I'm using B4A 3.50, so I coudn't use the inline Java code. I had to make a library with the "Send3" java code and I can get it to work.. sort of..

Here's my test code:

B4X:
Sub Globals
    Dim ThisPhoneSms As SendSmsWithExtraData
    Dim PhoneId As PhoneId
    Dim PE As PhoneEvents
End Sub

Sub Activity_Create(FirstTime As Boolean)
    PE.InitializeWithPhoneState("PE", PhoneId)
   
    Dim id As String
    Dim Extra As Map
   
    id = "123"
    Log("Sending SMS with id: " & id)
    Extra.Initialize
    Extra.Put("id", id)
    ThisPhoneSms.Send3("+000000000000", "Test", Extra, True, True)
   
    id = "456"
    Log("Sending SMS with id: " & id)
    Extra.Initialize
    Extra.Put("id", id)
    ThisPhoneSms.Send3("+000000000000", "Test", Extra, True, True)
End Sub

Sub PE_SmsSentStatus (Success As Boolean, ErrorMessage As String, PhoneNumber As String, Intent As Intent)
    Log("PE_SmsSentStatus:")
    Log("- PhoneNumber: " & PhoneNumber)
    Log("- Success: " & Success)
    Log("- id: " & Intent.GetExtra("id"))
End Sub

Sub PE_SmsDelivered (PhoneNumber As String, Intent As Intent)
    Log("PE_SmsDelivered:")
    Log("- PhoneNumber: " & PhoneNumber)
    Log("- id: " & Intent.GetExtra("id"))
End Sub

The result log is:

** Activity (main) Create, isFirst = true **
Sending SMS with id: 123
Sending SMS with id: 456
** Activity (main) Resume **
PE_SmsSentStatus:
- PhoneNumber: +000000000000
- Success: true
- id: 123
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
PE_SmsSentStatus:
- PhoneNumber: +000000000000
- Success: true
- id: 456
PE_SmsDelivered:
- PhoneNumber: +000000000000
- id: 123
PE_SmsDelivered:
- PhoneNumber: +000000000000
- id: 456

So, I send 2 SMS's to the same GSM number. The first one with "id" 123 and the second one with "id" 456. And then I receive the SentStatus for both.. and the SmsDelivered for both. And all events have the correct "id". Perfect!

The problem is that I can only run this code 1 time. If I run this code a second time I get this error:

main_globals (java line: 323)
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/sendsmswithextradata/SendSmsWithExtraData;
at com.reporttester.main._globals(main.java:323)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:174)
at com.reporttester.main.initializeGlobals(main.java:263)
at com.reporttester.main.afterFirstLayout(main.java:95)
at com.reporttester.main.access$100(main.java:16)
at com.reporttester.main$WaitForLayout.run(main.java:76)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:102)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.sendsmswithextradata.SendSmsWithExtraData" on path: DexPathList[[zip file "/data/app/com.reporttester-2/base.apk"],nativeLibraryDirectories=[/data/app/com.reporttester-2/lib/arm, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
... 15 more
Suppressed: java.lang.ClassNotFoundException: Didn't find class "com.sendsmswithextradata.SendSmsWithExtraData" on path: DexPathList[[dex file "/data/dalvik-cache/xposed_XResourcesSuperClass.dex"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 16 more
Suppressed: java.lang.ClassNotFoundException: com.sendsmswithextradata.SendSmsWithExtraData
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 17 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

The only way to make it work again is to delete the "Files" and "Objects" folders and leave just the .b4a file.

What am I doing wrong?

Library attached.
 

Attachments

  • SendSmsWithExtraData.zip
    3.8 KB · Views: 136
Upvote 0
Top