B4A Library SMS retriever API

Starting from Android 6 there is an Api from Google which can Listen for a Incoming SMS for you. But you do not need any Permission for this.
The SMS ends up in the Devices standard SMS App but your app can do an Phoneauthentification using an SMS from your Server.

Usually the way would be:
1. Ask the User for the Device Phonenumber
2. Send this Phonenumber to your Server.
3. Your Server send a SMS to the Device with an specific format.
4. The SMS retriever Api waits 5 Minutes (from which point it is started) and captures this SMS if it has the correct AppHash in it and the Format is correct.
5. You extract the Code from the SMS and send it to your Server.
6. Your server can now compare the outgoing Code to the one you give now.

Only the Point 4 is relevant with this Library.

SETUP

To setup the RetrieverApi in your App:
- Add the following to your Manifest
CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)
AddApplicationText(
<receiver android:name="anywheresoftware.b4a.objects.MySMSBCR" android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
</intent-filter>
</receiver>
)

Add this to you main module
B4X:
#AdditionalJar: com.google.android.gms:play-services-base
#AdditionalJar: com.google.android.gms:play-services-auth
#AdditionalJar: com.google.android.gms:play-services-auth-api-phone
#AdditionalJar: com.google.android.gms:play-services-identity
#AdditionalJar: com.google.android.gms:play-services-gcm
#AdditionalJar: com.google.android.gms:play-services-basement
In your Activity where you want to wait for an SMS from your Server
B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim verify As SMSVerification
End Sub

B4X:
Sub btnSMSverificationstart_Click
    verify.Initialize("SMSVerification")
    Do While verify.getSMSMessage = "---"
        Sleep(250)
    Loop
    Dim smsorg As String = verify.getSMSMessage
    'Log("SMS Text is: "&smsorg)
    Dim sms As String = smsorg.Replace("<#>","")
    sms = sms.SubString2(0,sms.Length-14)
    Log("Token from SMS:"&sms)
End Sub

In Step 4 you need to inform your Server and send him the Phonenumber where the SMSRetrieverApi is running on. The Server need then to Send a SMS with a Specific Format:

  • The message must start from any of the following .
    * <#>
    * Two consecutive zero-width space characters (U+200B)
  • Keep in mind that message must not exceeds 140 bytes
  • Contain a one-time code
  • And the special 11 character hash for you app.

In the Example the is a Second Library used, SignatureHelper. It is only for Development use. It is to find out the 11 character hash for your app (see above).

Add it to your app.
B4X:
    Dim signature As SignatureHelper
    signature.Initialize("") ' Only needed to get the Hashcode for your app. Should
    ' only be used in Development to get the Hash and copy it.
    ' DO NOT USE IT IN PRODUCTION CODE.
    Log(signature.getAppSignatures)
will print your apps hashcode in the Log. Copy the Code (you need to use it in your Server when you send the SMS). Once you copied the Hashcode for your app you can totally remove the SignatureHelper from your project. It is not needed anymore. And it contains code you do not want in your productionapp.
The SignatureHelper ist just to find out your HashCode! It should not be in your app in productioncode.

This library is Donationware. You can download the library, you can test the library. But if you want to USE the library in your App you need to Donate for it.
Please click here to donate (You can donate any amount you want to donate for the library (or my work) :)
 

Attachments

  • SMSVerificationEx.zip
    9.7 KB · Views: 761
  • SMSVerificationV1.0.zip
    4.4 KB · Views: 810
  • SignatureHelperV0.0.zip
    2.8 KB · Views: 809
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Starting from Android 6 there is an Api from Google which can Listen for a Incoming SMS for you. But you do not need any Permission for this.
The SMS ends up in the Devices standard SMS App but your app can do an Phoneauthentification using an SMS from your Server.

Usually the way would be:
1. Ask the User for the Device Phonenumber
2. Send this Phonenumber to your Server.
3. Your Server send a SMS to the Device with an specific format.
4. The SMS retriever Api waits 5 Minutes (from which point it is started) and captures this SMS if it has the correct AppHash in it and the Format is correct.
5. You extract the Code from the SMS and send it to your Server.
6. Your server can now compare the outgoing Code to the one you give now.

Only the Point 4 is relevant with this Library.

SETUP

To setup the RetrieverApi in your App:
- Add the following to your Manifest


Add this to you main module
B4X:
#AdditionalJar: com.google.android.gms:play-services-base
#AdditionalJar: com.google.android.gms:play-services-auth
#AdditionalJar: com.google.android.gms:play-services-auth-api-phone
#AdditionalJar: com.google.android.gms:play-services-identity
#AdditionalJar: com.google.android.gms:play-services-gcm
#AdditionalJar: com.google.android.gms:play-services-basement
In your Activity where you want to wait for an SMS from your Server
B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim verify As SMSVerification
End Sub

B4X:
Sub btnSMSverificationstart_Click
    verify.Initialize("SMSVerification")
    Do While verify.getSMSMessage = "---"
        Sleep(250)
    Loop
    Dim smsorg As String = verify.getSMSMessage
    'Log("SMS Text is: "&smsorg)
    Dim sms As String = smsorg.Replace("<#>","")
    sms = sms.SubString2(0,sms.Length-14)
    Log("Token from SMS:"&sms)
End Sub

In Step 4 you need to inform your Server and send him the Phonenumber where the SMSRetrieverApi is running on. The Server need then to Send a SMS with a Specific Format:

  • The message must start from any of the following .
    * <#>
    * Two consecutive zero-width space characters (U+200B)
  • Keep in mind that message must not exceeds 140 bytes
  • Contain a one-time code
  • And the special 11 character hash for you app.

In the Example the is a Second Library used, SignatureHelper. It is only for Development use. It is to find out the 11 character hash for your app (see above).

Add it to your app.
B4X:
    Dim signature As SignatureHelper
    signature.Initialize("") ' Only needed to get the Hashcode for your app. Should
    ' only be used in Development to get the Hash and copy it.
    ' DO NOT USE IT IN PRODUCTION CODE.
    Log(signature.getAppSignatures)
will print your apps hashcode in the Log. Copy the Code (you need to use it in your Server when you send the SMS). Once you copied the Hashcode for your app you can totally remove the SignatureHelper from your project. It is not needed anymore. And it contains code you do not want in your productionapp.
The SignatureHelper ist just to find out your HashCode! It should not be in your app in productioncode.

This library is Donationware. You can download the library, you can test the library. But if you want to USE the library in your App you need to Donate for it.
Please click here to donate (You can donate any amount you want to donate for the library (or my work) :)
It seems that with Android 9 it will no longer be possible to read text messages with the phone library.
Will this still be possible with this?
 

DonManfred

Expert
Licensed User
Longtime User

DonManfred

Expert
Licensed User
Longtime User
It seems that with Android 9 it will no longer be possible to read text messages with the phone library.
Will this still be possible with this?
i can confirm that the Library does work with Android 9 as my Phone got a Firmwareupdate recently.

The Library does work in Android 9.
 

DonManfred

Expert
Licensed User
Longtime User
The retriever api expect the SMS to have a specific format and content. Just sending 1234 will not work.

B4X:
Dim signature As SignatureHelper
    signature.Initialize("") ' Only needed to get the Hashcode for your app. Should
    ' only be used in Development to get the Hash and copy it.
    ' DO NOT USE IT IN PRODUCTION CODE.
    Log(signature.getAppSignatures)
This code helps you to get your app Signature. This code should NOT be used in your productive app!
 

mcqueccu

Well-Known Member
Licensed User
Longtime User
Nice one. Works ok. Just for information part of the sms was cut off in the log because the apphash i got is 11 characters in length.

B4X:
 sms = sms.SubString2(0,sms.Length-14) '<------I replaced the 14 with my apphash length 11 and it was ok
 
Top