Let’s use the SMS Retriever API in Xamarin Android, and possibly avoid the troubles of new Google Play Store SMS/Call Log access restrictions! 😉 Is your Android App ready for the new Google Play Store permission policy?
SMS Retriever API, in a nutshell…
Android SMS Retriever API allows you to access the SMS Messages in the phone without having to request SMS read access permission, thus giving a complete peace of mind for the user. 🙂 Allowing specific SMS messages to be read from the Inbox, which are specifically targeted to be delivered for the app we’re requesting from. This is the perfect solution for One Time Password (OTP) mobile number verification implementation in our Android apps.
Furthermore from Google Docs: https://developers.google.com/identity/sms-retriever/
Now that the introduction is out of the way… Let’s get started!
How it works, in short…
NO! I’m not gonna get into detailed explanation, but in simplest terms we are going to have an object called SmsRetrieverClient that’s going to wait for an incoming SMS message with the matching hash key to the app we are using. This active waiting is going to execute for 5 minutes and automatically dispose itself.
When the certain SMS arrived at the inbox during the 5 minute waiting , the SmsRetrieverClient then sends a broadcast to the app with the captured message content, for any listening broadcast receivers registered in the app. From there we pick up the message inside our broadcast receiver and we process it or do whatever the heck we want with it. 😛
But in case if the SMS wasn’t received by the phone it would still execute the broadcast but with a time out failure code, so that we know the 5 minutes waiting exceeded and the SMS wasn’t received or read.
So there’s mainly 2 components to it, SmsRetrieverClient object, and the Broadcast Receiver object. Not to mention the App Hash key, which is also very crucial element here, you need to make sure the SMS that’s sent to the device has the App hash key that’s derived from the signing keystore of the app’s running instance.
In Xamarin…
Yes this is completely available in Xamarin Android as well, right out of the box! Just a matter of figuring out the right namespaces and method calls comparing to the official Google Android Docs! 🙂
Although I’m quite surprised I could not find any official Documentation from Xamarin regarding this important API. Thus here I am filling that void! 😀
Let’s get started!
Add em Nuget!
To use SMS Retriever API in Xamarin we need to install Xamarin.GooglePlayServices.Auth nuget package to our Android project.
Just pick the latest version as you prefer and hit install.
Activate the SMSRetrieverClient…
Then we need to implement the executing of the activation of SMSRetrieverClient that is the client object that’s going to actively watch out for any incoming SMS messages with the hash key that is similar to the app we are requesting it from.
You could initiate the SMSRetrieverClient inside a button click event or invoke it from a Service instance method, choice is up to you. 🙂
private void btnStartSMSRetreiver_OnClick(object sender, EventArgs eventArgs)
{
// Get an instance of SmsRetrieverClient, used to start listening for a matching SMS message.
SmsRetrieverClient _client = SmsRetriever.GetClient(this.ApplicationContext);
// Starts SmsRetriever, which waits for ONE matching SMS message until timeout
// (5 minutes). The matching SMS message will be sent via a Broadcast Intent with
// action SmsRetriever#SMS_RETRIEVED_ACTION.
_client.StartSmsRetriever();
}
As you can see we’re instantiating the SmsRetrieverClient using the Application Context, and calling the StartSmsRetriever() method to activate listening to the incoming SMS messages with matching app hash key included.
A little cherry on top…
Here are some extra bits you could adopt if needed regarding the SmsRetrieverClient. You could get the return result of the SmsRetrieverClient initiation as follows…
...
var task = _client.StartSmsRetriever();
// You could also Listen for success/failure of StartSmsRetriever initiation
task.AddOnSuccessListener(new SuccessListener());
task.AddOnFailureListener(new FailureListener());
}
...
internal class SuccessListener : Java.Lang.Object, IOnSuccessListener
{
public void OnSuccess(Object result)
{
// do as you wish on Success init
}
}
internal class FailureListener : Java.Lang.Throwable, IOnFailureListener
{
public void OnFailure(Exception e)
{
// do as you wish on Failure init
}
}
And even await for the init result asynchronously as follows…
...
var task = await _client.StartSmsRetriever();
...
But don’t forget to switch the caller method to an async method! 😉
Well that’s just some cherry on top features if you ever wanted to try!
Next the BroadcastReceiver…
So here’s the other piece of the puzzle, the BroadcastReceiver that will be listening to the broadcasts of the above SmsRetreieverClient.
SMS Retriever API has provided us with an intent filter SmsRetriever.SmsRetrievedAction which we will use to register our BroadcastReceiver, which we’re going name as SMSBroadcastReceiver, and implement as following…
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { SmsRetriever.SmsRetrievedAction })]
public class SMSBroadcastReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action != SmsRetriever.SmsRetrievedAction)
return;
var extrasBundleundle = intent.Extras;
if (extrasBundleundle == null) return;
var status = (Statuses)extrasBundleundle.Get(SmsRetriever.ExtraStatus);
switch (status.StatusCode)
{
case CommonStatusCodes.Success:
// Get SMS message contents
var messageContent = (string)extrasBundleundle.Get(SmsRetriever.ExtraSmsMessage);
// Extract one-time code from the message and complete verification
// by sending the code back to your server.
ShowResultOnUI("SMS retrieved: " + messageContent);
break;
case CommonStatusCodes.Timeout:
// Waiting for SMS timed out (5 minutes)
// Handle the error ...
ShowResultOnUI("Timed Out Error! SMS retrieval failed!");
break;
}
}
}
So once the SmsRetrieverClient does its job, either success or failure it will hit our Broadcast Receiver above and pass in the results, with Status code and Content of the Message if success, which will be included in the Extra Bundle as you can see above.
Once we receive the results, its up to you to do whatever you want with it, as you can see in the code itself! 😉
That’s pretty much it! simple and straightforward eh! 😀 But I wouldn’t end there without mentioning some important other bits that you need to make sure to get it right!
Other important bits…
Here are some helpful tips for you to troubleshoot any issues you’re having with getting the SMS Retriever API to function as it should.
SMS format..
You need to make sure you’re sending the correct SMS format as mentioned in the Google Android Documentation.
<#> Your ExampleApp code is: 123ABC78 FA+9qCX9VSu
It should be same format as above, although you could make some alterations to the message content, but the structure should be same. Start with “<#>” followed by the content of the SMS and ending with the App Hash key. You can learn more about it from their documentation: SMS Retriever API: Construct a verification message
Please, get your App Hash Key right!
I’ve seen people get this wrong all the time. It is such an easy simple process but a delicate one. So if you can’t get your implementation of SMS Retriever API to function properly, you should definitely take a look at your app hash key, whether you’ve generated the correct key and using the properly in the SMS content.
Given Xamarin Android development, there’s no official documentation provided by Xamarin yet, that’s why I have written a step by step blog article to how to easily generate the accurate App hash key, give it a try if it could be of any help…
You can check it out here: App Hash Key Helper extension for Xamarin Android apps!
Let’s see it in action! 😀
Let’s fire it up and see the beauty of Android SMS Retriever API in Xamarin!
Look at the beauty eh! 😀 No SMS Read permission required 😉 way to give some peace of mind for your users for a simple functionalities such as OTP or Phone number verification!
You can try out my full blown demo in my github repo:
https://github.com/UdaraAlwis/XAndroidSMSRetrieverAPIDemo
It’s got all the bits I talked about above fully functional 🙂
in Xamarin.Forms Android?
Even if you’re using Xamarin.Forms the same implementation above can be applied easily. Just simply create a platform specific service to invoke the SMSRetrieverAPIClient on Android and call it from Xamarin.Forms at run time, then from the BroadcastReceiver just return back the results by using Xamarin.Forms MessagingCenter… 😉
Simple eh! 😀
There you have it fellas!
Cheers! Share the love! 😀 ❤