×

iFour Logo

How to verify OTP in Android without SMS read permission using Xamarin.Forms?

Kapil Panchal - November 27, 2020

Listening is fun too.

Straighten your back and cherish with coffee - PLAY !

  • play
  • pause
  • pause
How to verify OTP in Android without SMS read permission using Xamarin.Forms?

In this blog, we will be going to talk about how to verify OTP in android without SMS read permission using Xamarin.Forms. Now a days most of mobile application uses OTP registration for users. So that user can type the OTP and access the appliance.But it's crazy if the SMS will automatically populate to the user application without typing, in case OTP should be received on the equivalent device.

By providing the Read_SMS permission to android its manifest file, we will also retrieve the OTP by using LocalBoardcastManager.But the matter is, Google Play did not allow us to without telling them, why we are providing the Read_SMS permission to the user to read the SMS from the user's mobile. Google Play thinks that your application may be a SPY Application. So, Google will ask a few questions, why we offer Read_SMS permission. Because now a days all authentication is OTP based. So that anybody can steal your OTP Message. For protecting users, google provides an SMS Retriever API, which works without granting Read_SMS permission from the manifest. But we'd like to follow the SMS Retriever API rules for reading the OTP Message from the user device

How to create a project and how to verify OTP in android without SMS read permission?

Please follow these stepsto verify OTP in the android without SMS read permission using Xamarin.Forms

Step 1:Create a xamarin project in android application.

Step 2:After creating the project, click the project name in the solution explorer then right-click and select the Manage NuGet packages to install the package.

Google_play_service

  Fig: Google Play service package install.

Installation_permission

  Image 2: Installation permission

Step 3: After installation of the package,create a user interface for typing and submit the OTP number.


FIleName:MainPage.xaml



          
          




              

Step 4:Dependency service

DependencyService allows applications to call platform-specific functionality from shared code. This feature allows Xamarin.Forms applications to test everything that a native application can do. We need to design an interface that defines how it will interact with the specific functions of the platform. Here, OTP reading will only support the Android platform and IOS will support autocompletion, so create aDependencyService interface to concentrate to SMS collector. Create a new class and interface for CommonServices.

Now create a folder Dependency and store the dependency file.

File name:ListenToMessageRetriver

Code:
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;

namespace DemoOFOTPVerification.Dependency
{
  public class CommonMessageServices
  {
      public static void ListenToSmsRetriever()
      {
          DependencyService.Get()?.ListenToMessageRetriever();
      }
  }
  public interface IListenToMessageRetriever
  {
      void ListenToMessageRetriever();
  }
}
                

Step 5:Messaging center

Xamarin.FormsMessagingCenter allows different components to communicate without recognizing each other outside of a simple messaging convention. MessagingCenter may be a static class with subscribe and Send methods that are used throughout the answer.

Subscribe: Listen to messages with a specific signature and take certain actions when you receive them. Multiple subscribers can listen to the same message.

Send:Post a message for listeners to act. If there are no subscribed listeners, the message will be ignored.

File Name:Utils.cs

Code:
iusing DemoOFOTPVerification.Enum;
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;

namespace DemoOFOTPVerification.Utils
{
  public static class Utils
  {
      private static readonly object c1 = new object();
      public static void Subscribe(this object subscriber, SmsDataeventSubscriber, ActioncallBack)
      {
MessagingCenter.Subscribe(subscriber, eventSubscriber.ToString(), new Action((e, a) => { callBack(a); }));
      }
      public static void Notify(SmsDataeventNotified, TArgs argument)
      {
MessagingCenter.Send(c1, eventNotified.ToString(), argument);
      }
  }
}
                

Step 6:Create an Enum folder and store the enum class in this folder.

File name: Code:
using System;
using System.Collections.Generic;
using System.Text;
namespace DemoOFOTPVerification.Enum
{
  public enumSmsData
  {
SmsRecieved,  
  }
}
                

Step 7: Write the code in MainPage.xaml.cs file.

The code on the back adds the subscriber message listener and if a message is received in a specific format from the mail application, the message is notified and reads and assigns the OTP value to the Entry Control.

File name:

MainPage.xaml.cs Code:
using DemoOFOTPVerification.Dependency;
using DemoOFOTPVerification.Enum;
using DemoOFOTPVerification.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace DemoOFOTPVerification
{
  public partial class MainPage :ContentPage
  {
      public MainPage()
      {
      InitializeComponent();
      this.Subscribe(SmsData.SmsRecieved, =>
          {
      otpEntry.Text = (string);
          });
      }

      private void Subscribe(SmsDatasmsRecieved, Action p)
      {
          throw new NotImplementedException();
      }

      private void Button_Clicked(object sender, EventArgs e)
      {
    CommonMessageServices.ListenToSmsRetriever();
      }
  }
}
                

Step 8:How to listen to the message using dependency.

Let's start by creating a dependency on the Android project. If you haven't added the Xamarin.GooglePlayServices.AuthNuGet package, try adding it before creating the instance.

Get the sample SmsRetrieverClient used to start listening to a corresponding SMS message.

SmsRetrieverClient Client = SmsRetriever.GetClient (Application.Context);

Starts SmsRetriever waiting for the corresponding SMS until the timeout (5 minutes). The corresponding SMS message will be sent with the intention of a transmission.

File Name:ListenToMessage.cs

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using DemoOFOTPVerification.Droid;
using Application = Android.App.Application;

[assembly: Dependency(typeof(ListenToSms))]
namespace DemoOFOTPVerification.Droid.Dependency
{
  public class ListenToMessage: IListenToSmsRetriever
  {
      public void ListenToMessageRetriever()
      {
SmsRetrieverClientSMSclient = SmsRetriever.GetClient(Application.Context);
var task1 = SMSclient.StartSmsRetriever();
          task1.AddOnSuccessListener(new SuccessListener());
          task1.AddOnFailureListener(new FailureListener());
      }
      private class SuccessListener : Object, IOnSuccessListener
      {
          public void OnSuccess(Object result)
          {
          }
      }
      private class FailureListener : Object, IOnFailureListener
      {
          public void OnFailure(Exception e)
          {
          }
      }
  }
}
                

Planning to Hire Xamarin App Development Company? Your Search ends here.

Step 9:BrodcastReceiver

BroadcastReceivewill listen to API broadcasts from the SmsRetrieverClient.SMS Retriever above, has provided a purpose filter SmsRetriever.SmsRetrivedAction, which we will call SMSBroadcastReceiver and use it to record our BroadcastReceiver, which we will implement below.

File name: Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

namespace DemoOFOTPVerification.Droid
{

  [BroadcastReceiver(Enabled = true, Exported = true)]
  [IntentFilter(new[] { SmsRetriever.SmsRetrievedAction })]
  public class SmsReceiver :BroadcastReceiver
  {
      private static readonlystring[] OtpMessageBodyKeywordSet = { "DevEnvExe Generated OTP" }; 
      public override void OnReceive(Context context, Intent intent)
      {
          try
          {
              if (intent.Action != SmsRetriever.SmsRetrievedAction) return;
var bundle = intent.Extras;
              if (bundle == null) return;
              var status = (Statuses)bundle.Get(SmsRetriever.ExtraStatus);
              switch (status.StatusCode)
              {
                  case CommonStatusCodes.Success:
                      var message = (string)bundle.Get(SmsRetriever.ExtraSmsMessage);
varfoundKeyword = OtpMessageBodyKeywordSet.Any(k =>message.Contains(k));
                      if (!foundKeyword) return;
var code = ExtractNumber(message);
Utilities.Notify(Events.SmsRecieved, code);
                      break;
                  case CommonStatusCodes.Timeout:
                      break;
              }

          }
          catch (System.Exception)
          {
          }
      }
      private static string ExtractNumber(string text)
      {
          if (string.IsNullOrEmpty(text)) return "";
var number = Regex.Match(text, @"\d+").Value;
          return number;
      }
  }
}
                

Step 10:Generate Key using Hash Key Helper

The hash chain consists of your application's package name and your application's public key certificate. To generate the hash code, simply run the following C# method to generate a hash that will be included in your SMS message.

You need to make sure to create a hash key and add it to the OTP message. Without the correct hash, your application will not receive the message reminder. The hash key will be created and stored once per application. Then you can remove this helper class from your code and create a new class in the native Android project.

File name: AppHashKeyHelperForSMSCode:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

namespace DemoOFOTPVerification.Droid.Helper
{
  public class AppHashKeyHelperForSMS
  {
      private static string HASH_TYPE = "SHA-256";
      private static int NUM_HASHED_BYTES = 9;
      private static int NUM_BASE64_CHAR = 11;
private static string GetPackageSignature(Context context)
      {
PackageManagerpackageManager = context.PackageManager;
var signatures = packageManager.GetPackageInfo(context.PackageName, PackageInfoFlags.Signatures).Signatures;
          return signatures.First().ToCharsString();
      }

      public static string GetAppHashKey(Context context)
      {
          string keystoreHexSignature = GetPackageSignature(context);

          String appInfo = context.PackageName + " " + keystoreHexSignature;
          try
          {
MessageDigestmessageDigest = MessageDigest.GetInstance(HASH_TYPE);
messageDigest.Update(Encoding.UTF8.GetBytes(appInfo));
byte[] hashSignature = messageDigest.Digest();

hashSignature = Arrays.CopyOfRange(hashSignature, 0, NUM_HASHED_BYTES);
              String base64Hash = Android.Util.Base64.EncodeToString(hashSignature, Base64Flags.NoPadding | Base64Flags.NoWrap);
              base64Hash = base64Hash.Substring(0, NUM_BASE64_CHAR);

              return base64Hash;
          }
          catch (NoSuchAlgorithmException e)
          {
              return null;
          }
      }
  }
}
                

Conclusion


In this blog, we have explained how to implement code without verifying OTP in android using Xamarin.forms.First of all, you can install the google play services authentication package, install in your project than create the class of dependency services, broadcastreceiver, Key helper and messaging center.By automatically reading the OTP, the users can easily complete verification flows via SMS.

How to verify OTP in Android without SMS read permission using Xamarin.Forms? In this blog, we will be going to talk about how to verify OTP in android without SMS read permission using Xamarin.Forms. Now a days most of mobile application uses OTP registration for users. So that user can type the OTP and access the appliance.But it's crazy if the SMS will automatically populate to the user application without typing, in case OTP should be received on the equivalent device. By providing the Read_SMS permission to android its manifest file, we will also retrieve the OTP by using LocalBoardcastManager.But the matter is, Google Play did not allow us to without telling them, why we are providing the Read_SMS permission to the user to read the SMS from the user's mobile. Google Play thinks that your application may be a SPY Application. So, Google will ask a few questions, why we offer Read_SMS permission. Because now a days all authentication is OTP based. So that anybody can steal your OTP Message. For protecting users, google provides an SMS Retriever API, which works without granting Read_SMS permission from the manifest. But we'd like to follow the SMS Retriever API rules for reading the OTP Message from the user device How to create a project and how to verify OTP in android without SMS read permission? Please follow these stepsto verify OTP in the android without SMS read permission using Xamarin.Forms Step 1:Create a xamarin project in android application. Step 2:After creating the project, click the project name in the solution explorer then right-click and select the Manage NuGet packages to install the package.   Fig: Google Play service package install.   Image 2: Installation permission Step 3: After installation of the package,create a user interface for typing and submit the OTP number. FIleName:MainPage.xaml Step 4:Dependency service DependencyService allows applications to call platform-specific functionality from shared code. This feature allows Xamarin.Forms applications to test everything that a native application can do. We need to design an interface that defines how it will interact with the specific functions of the platform. Here, OTP reading will only support the Android platform and IOS will support autocompletion, so create aDependencyService interface to concentrate to SMS collector. Create a new class and interface for CommonServices. Read More: Hybrid Mobile App Development - Xamarin Or Telerik AppBuilder Now create a folder Dependency and store the dependency file. File name:ListenToMessageRetriver Code: using System; using System.Collections.Generic; using System.Text; using Xamarin.Forms; namespace DemoOFOTPVerification.Dependency { public class CommonMessageServices { public static void ListenToSmsRetriever() { DependencyService.Get()?.ListenToMessageRetriever(); } } public interface IListenToMessageRetriever { void ListenToMessageRetriever(); } } Step 5:Messaging center Xamarin.FormsMessagingCenter allows different components to communicate without recognizing each other outside of a simple messaging convention. MessagingCenter may be a static class with subscribe and Send methods that are used throughout the answer. Subscribe: Listen to messages with a specific signature and take certain actions when you receive them. Multiple subscribers can listen to the same message. Send:Post a message for listeners to act. If there are no subscribed listeners, the message will be ignored. File Name:Utils.cs Code: iusing DemoOFOTPVerification.Enum; using System; using System.Collections.Generic; using System.Text; using Xamarin.Forms; namespace DemoOFOTPVerification.Utils { public static class Utils { private static readonly object c1 = new object(); public static void Subscribe(this object subscriber, SmsDataeventSubscriber, ActioncallBack) { MessagingCenter.Subscribe(subscriber, eventSubscriber.ToString(), new Action((e, a) => { callBack(a); })); } public static void Notify(SmsDataeventNotified, TArgs argument) { MessagingCenter.Send(c1, eventNotified.ToString(), argument); } } } Step 6:Create an Enum folder and store the enum class in this folder. File name: Code: using System; using System.Collections.Generic; using System.Text; namespace DemoOFOTPVerification.Enum { public enumSmsData { SmsRecieved, } } Step 7: Write the code in MainPage.xaml.cs file. The code on the back adds the subscriber message listener and if a message is received in a specific format from the mail application, the message is notified and reads and assigns the OTP value to the Entry Control. File name: MainPage.xaml.cs Code: using DemoOFOTPVerification.Dependency; using DemoOFOTPVerification.Enum; using DemoOFOTPVerification.Utils; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using Xamarin.Forms; namespace DemoOFOTPVerification { public partial class MainPage :ContentPage { public MainPage() { InitializeComponent(); this.Subscribe(SmsData.SmsRecieved, => { otpEntry.Text = (string); }); } private void Subscribe(SmsDatasmsRecieved, Action p) { throw new NotImplementedException(); } private void Button_Clicked(object sender, EventArgs e) { CommonMessageServices.ListenToSmsRetriever(); } } } Step 8:How to listen to the message using dependency. Let's start by creating a dependency on the Android project. If you haven't added the Xamarin.GooglePlayServices.AuthNuGet package, try adding it before creating the instance. Get the sample SmsRetrieverClient used to start listening to a corresponding SMS message. SmsRetrieverClient Client = SmsRetriever.GetClient (Application.Context); Starts SmsRetriever waiting for the corresponding SMS until the timeout (5 minutes). The corresponding SMS message will be sent with the intention of a transmission. File Name:ListenToMessage.cs Code: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; using DemoOFOTPVerification.Droid; using Application = Android.App.Application; [assembly: Dependency(typeof(ListenToSms))] namespace DemoOFOTPVerification.Droid.Dependency { public class ListenToMessage: IListenToSmsRetriever { public void ListenToMessageRetriever() { SmsRetrieverClientSMSclient = SmsRetriever.GetClient(Application.Context); var task1 = SMSclient.StartSmsRetriever(); task1.AddOnSuccessListener(new SuccessListener()); task1.AddOnFailureListener(new FailureListener()); } private class SuccessListener : Object, IOnSuccessListener { public void OnSuccess(Object result) { } } private class FailureListener : Object, IOnFailureListener { public void OnFailure(Exception e) { } } } } Planning to Hire Xamarin App Development Company? Your Search ends here. See here Step 9:BrodcastReceiver BroadcastReceivewill listen to API broadcasts from the SmsRetrieverClient.SMS Retriever above, has provided a purpose filter SmsRetriever.SmsRetrivedAction, which we will call SMSBroadcastReceiver and use it to record our BroadcastReceiver, which we will implement below. File name: Code: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; namespace DemoOFOTPVerification.Droid { [BroadcastReceiver(Enabled = true, Exported = true)] [IntentFilter(new[] { SmsRetriever.SmsRetrievedAction })] public class SmsReceiver :BroadcastReceiver { private static readonlystring[] OtpMessageBodyKeywordSet = { "DevEnvExe Generated OTP" }; public override void OnReceive(Context context, Intent intent) { try { if (intent.Action != SmsRetriever.SmsRetrievedAction) return; var bundle = intent.Extras; if (bundle == null) return; var status = (Statuses)bundle.Get(SmsRetriever.ExtraStatus); switch (status.StatusCode) { case CommonStatusCodes.Success: var message = (string)bundle.Get(SmsRetriever.ExtraSmsMessage); varfoundKeyword = OtpMessageBodyKeywordSet.Any(k =>message.Contains(k)); if (!foundKeyword) return; var code = ExtractNumber(message); Utilities.Notify(Events.SmsRecieved, code); break; case CommonStatusCodes.Timeout: break; } } catch (System.Exception) { } } private static string ExtractNumber(string text) { if (string.IsNullOrEmpty(text)) return ""; var number = Regex.Match(text, @"\d+").Value; return number; } } } Step 10:Generate Key using Hash Key Helper The hash chain consists of your application's package name and your application's public key certificate. To generate the hash code, simply run the following C# method to generate a hash that will be included in your SMS message. You need to make sure to create a hash key and add it to the OTP message. Without the correct hash, your application will not receive the message reminder. The hash key will be created and stored once per application. Then you can remove this helper class from your code and create a new class in the native Android project. File name: AppHashKeyHelperForSMSCode: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; namespace DemoOFOTPVerification.Droid.Helper { public class AppHashKeyHelperForSMS { private static string HASH_TYPE = "SHA-256"; private static int NUM_HASHED_BYTES = 9; private static int NUM_BASE64_CHAR = 11; private static string GetPackageSignature(Context context) { PackageManagerpackageManager = context.PackageManager; var signatures = packageManager.GetPackageInfo(context.PackageName, PackageInfoFlags.Signatures).Signatures; return signatures.First().ToCharsString(); } public static string GetAppHashKey(Context context) { string keystoreHexSignature = GetPackageSignature(context); String appInfo = context.PackageName + " " + keystoreHexSignature; try { MessageDigestmessageDigest = MessageDigest.GetInstance(HASH_TYPE); messageDigest.Update(Encoding.UTF8.GetBytes(appInfo)); byte[] hashSignature = messageDigest.Digest(); hashSignature = Arrays.CopyOfRange(hashSignature, 0, NUM_HASHED_BYTES); String base64Hash = Android.Util.Base64.EncodeToString(hashSignature, Base64Flags.NoPadding | Base64Flags.NoWrap); base64Hash = base64Hash.Substring(0, NUM_BASE64_CHAR); return base64Hash; } catch (NoSuchAlgorithmException e) { return null; } } } } Conclusion In this blog, we have explained how to implement code without verifying OTP in android using Xamarin.forms.First of all, you can install the google play services authentication package, install in your project than create the class of dependency services, broadcastreceiver, Key helper and messaging center.By automatically reading the OTP, the users can easily complete verification flows via SMS.
Kapil Panchal

Kapil Panchal

A passionate Technical writer and an SEO freak working as a Content Development Manager at iFour Technolab, USA. With extensive experience in IT, Services, and Product sectors, I relish writing about technology and love sharing exceptional insights on various platforms. I believe in constant learning and am passionate about being better every day.

Build Your Agile Team

Enter your e-mail address Please enter valid e-mail

Categories

Ensure your sustainable growth with our team

Talk to our experts
Sustainable
Sustainable
 
Blog Our insights
10 Executive Dashboard Examples for Consultants and CEOs
10 Executive Dashboard Examples for Consultants and CEOs

There is a principle behind every business. “If you don’t keep track of essentials, you won’t get clear direction, eventually causing your company to stumble.” To manage this scenario,...

How Spatial Data Analysis Improves Healthcare
How Spatial Data Analysis Improves Healthcare

Do you know when geospatial analysis took traction in healthcare? It was when John Snow, a London-based physician, used it to analyze the spread of cholera, which ultimately proved...

4 Types of Power BI Dashboards: Analytical, Strategic, Operational, and Tactical
4 Types of Power BI Dashboards: Analytical, Strategic, Operational, and Tactical

One interesting aspect you truly love about Power BI, as a CTO, is how it lets you step back and see the bigger picture of your business. Isn’t it? Without getting bogged down in minute...