How to Autofill OTP Code from SMS in Flutter

In this example, we are going to show you how to listen to incoming SMS and obtain OTP code, and autofill to the OTP code input boxes. OTP verification is an important factor for user registration in your mobile app. See the example below:

[IMPORTANT] First, look at this tutorial: How to Listen to Incoming SMS in Flutter

Now, add telephony and otp_text_field packages to your project by adding the following lines on pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter
  telephony: ^0.2.0
  otp_text_field: ^1.1.3

Here, telephony is to listen to incoming OTP message and otp_text_field packages is for OTP input boxes.

Add this permission and tags on AndroidManifest.xml file at android/app/src/main folder:

<manifest>
	<uses-permission android:name="android.permission.RECEIVE_SMS"/>

	<application>
		...
		...

		<receiver android:name="com.shounakmulay.telephony.sms.IncomingSmsReceiver"
		    android:permission="android.permission.BROADCAST_SMS" android:exported="true">
		    <intent-filter>
			<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
		    </intent-filter>
		</receiver>

	</application>
</manifest>

Now, import the packages to your script:

import 'package:otp_text_field/otp_text_field.dart';
import 'package:otp_text_field/style.dart';
import 'package:telephony/telephony.dart';

Declare the required variables:

Telephony telephony = Telephony.instance;
OtpFieldController otpbox = OtpFieldController();

Listen to the incoming OTP SMS text:

telephony.listenIncomingSms(
    onNewMessage: (SmsMessage message) {
        print(message.address); //+977981******67, sender nubmer
        print(message.body); //Your OTP code is 34567
        print(message.date); //1659690242000, timestamp
        
        String sms = message.body.toString(); //get the message

        if(message.address == "+977981******67"){
              //verify SMS is sent for OTP with sender number
              String otpcode = sms.replaceAll(new RegExp(r'[^0-9]'),'');
              //prase code from the OTP sms
              otpbox.set(otpcode.split("")); 
              //split otp code to list of number
              //and populate to otb boxes

              setState(() {
                  //refresh UI
              });

        }else{
            print("Normal message.");
        }
    },
    listenInBackground: false,
);

Set OTP boxes input on your widget tree:

OTPTextField(
    controller: otpbox,
    length: 5,
    width: MediaQuery.of(context).size.width,
    fieldWidth: 50,
    style: TextStyle(
      fontSize: 17
    ),
    textFieldAlignment: MainAxisAlignment.spaceAround,
    fieldStyle: FieldStyle.box,
    onCompleted: (pin) {
          print("Entered OTP Code: $pin");
    },
)

Full App Example Code:

import 'package:flutter/material.dart';
import 'package:otp_text_field/otp_text_field.dart';
import 'package:otp_text_field/style.dart';
import 'package:telephony/telephony.dart';

void main(){
  runApp(MyApp());
}

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Home(),
    );
  }
}

class Home extends StatefulWidget{
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {  

  Telephony telephony = Telephony.instance;
  OtpFieldController otpbox = OtpFieldController();

  @override
  void initState() {
      telephony.listenIncomingSms(
          onNewMessage: (SmsMessage message) {
              print(message.address); //+977981******67, sender nubmer
              print(message.body); //Your OTP code is 34567
              print(message.date); //1659690242000, timestamp
              
              String sms = message.body.toString(); //get the message

              if(message.address == "+977981******67"){
                   //verify SMS is sent for OTP with sender number
                   String otpcode = sms.replaceAll(new RegExp(r'[^0-9]'),'');
                   //prase code from the OTP sms
                   otpbox.set(otpcode.split("")); 
                   //split otp code to list of number
                   //and populate to otb boxes

                   setState(() {
                       //refresh UI
                   });

              }else{
                 print("Normal message.");
              }
          },
          listenInBackground: false,
      );
      super.initState();
  }

  @override
  Widget build(BuildContext context) { 
    return  Scaffold(
          appBar: AppBar(
            title: Text("Autofill OTP From SMS"),
            backgroundColor: Colors.redAccent
          ),
          body: Container(
            padding: EdgeInsets.only(top:50, left:20, right:20),
            alignment: Alignment.topLeft,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [ 
                
                  Center( 
                     child: Text("Enter OTP Code", style: TextStyle(fontSize: 20),),
                  ),

                  Padding(padding: EdgeInsets.all(20)),

                  OTPTextField(
                      controller: otpbox,
                      length: 5,
                      width: MediaQuery.of(context).size.width,
                      fieldWidth: 50,
                      style: TextStyle(
                        fontSize: 17
                      ),
                      textFieldAlignment: MainAxisAlignment.spaceAround,
                      fieldStyle: FieldStyle.box,
                      onCompleted: (pin) {
                           print("Entered OTP Code: $pin");
                      },
                  ),

            ],)
          )
       );
  }
}

In this way, you can listen to incoming OTP SMS, and obtain OTP code from SMS with autofill OTP input in Flutter.

No any Comments on this Article


Please Wait...