Android Snippet

When you need a real-time response to a Missed-call OTP, you can set the listener on your Android code. The code format is available on Kotlin and Java.

Kotlin

The files consist of AndroidManifest.xml, Helper.kt, MainActivity.kt and PhoneStateReceiver.kt

AndroidManifest.xml

                            
                            <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
                            <uses-permission android:name="android.permission.READ_CALL_LOG"/>
                            
                        

Helper.kt

                            
                            private fun isAirplaneModeOn(): Boolean {
                                return Settings.System.getInt(contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0) != 0
                            }
                            
                        

MainActivity.kt

                            
                            import android.Manifest
                            import android.content.BroadcastReceiver
                            import android.content.Context
                            import android.content.Intent
                            import android.content.IntentFilter
                            import android.content.pm.PackageManager
                            import android.os.Bundle
                            import androidx.appcompat.app.AppCompatActivity
                            import androidx.core.app.ActivityCompat
                            import androidx.core.content.ContextCompat
                            
                            
                            class MainActivity : AppCompatActivity() {
                                var key: String? = null //OTP
                                val digits: Int = 4 // 4 or 6 digits to pass verification
                            
                                private val phoneStateReceiver = PhoneStateReceiver()
                            
                                override fun onCreate(savedInstanceState: Bundle?) {
                                    super.onCreate(savedInstanceState)
                                    setContentView(R.layout.activity_main)
                            
                                    //check READ_PHONE_STATE and READ_CALL_LOG permission
                                    val permissions: MutableList = mutableListOf()
                                    if (ContextCompat.checkSelfPermission(
                                            this,
                                            Manifest.permission.READ_PHONE_STATE
                                        ) != PackageManager.PERMISSION_GRANTED
                                    ) {
                                        permissions.add(Manifest.permission.READ_PHONE_STATE)
                                    }
                                    if (ContextCompat.checkSelfPermission(
                                            this,
                                            Manifest.permission.READ_CALL_LOG
                                        ) != PackageManager.PERMISSION_GRANTED
                                    ) {
                                        permissions.add((Manifest.permission.READ_CALL_LOG))
                                    }
                            
                                    if (permissions.isEmpty()) {
                                        //register receivers if all permissions have been granted
                                        registerReceiver(phoneStateReceiver, IntentFilter("android.intent.action.PHONE_STATE"))
                                        registerReceiver(keyReceiver, IntentFilter(PhoneStateReceiver.KEY_RECEIVER))
                                    } else {
                                        //request permission(s) that has not been granted
                                        ActivityCompat.requestPermissions(this, permissions.toTypedArray(), 100)
                                    }
                                }
                            
                                //receiver to get the key
                                private var keyReceiver: BroadcastReceiver = object : BroadcastReceiver() {
                                    override fun onReceive(context: Context?, intent: Intent) {
                                        val phoneNumber = intent.extras?.getString(PhoneStateReceiver.PHONE_NUMBER)
                                        key = phoneNumber?.takeLast(digits)
                                    }
                                }
                            
                            
                                override fun onRequestPermissionsResult(
                                    requestCode: Int,
                                    permissions: Array,
                                    grantResults: IntArray
                                ) {
                                    var allGranted = true
                                    if (requestCode == 100) {
                                        grantResults.forEach {
                                            if (it != PackageManager.PERMISSION_GRANTED) allGranted = false
                                        }
                                        if (allGranted) {
                                            registerReceiver(
                                                phoneStateReceiver,
                                                IntentFilter("android.intent.action.PHONE_STATE")
                                            )
                                        }
                                    }
                                }
                            
                                override fun onDestroy() {
                                    super.onDestroy()
                                    //unregister receivers
                                    unregisterReceiver(keyReceiver)
                                    unregisterReceiver(phoneStateReceiver)
                                }
                            }
                            
                        

PhoneStateReceiver.kt

                            
                            import android.content.BroadcastReceiver
                            import android.content.Context
                            import android.content.Intent
                            import android.telephony.PhoneStateListener
                            import android.telephony.TelephonyManager
                            
                            
                            class PhoneStateReceiver : BroadcastReceiver() {
                                companion object {
                                    var phoneStateListener: CustomPhoneStateListener? = null
                                    const val PHONE_NUMBER = "PHONE_NUMBER"
                                    const val KEY_RECEIVER = "KeyReceiver"
                                }
                            
                                override fun onReceive(context: Context, intent: Intent) {
                                    val telephonyManager =
                                        context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
                            
                                    //onReceive will called multiple time, so we have to make sure the listener is only made once
                                    if (phoneStateListener == null) {
                                        phoneStateListener = CustomPhoneStateListener(context)
                                        telephonyManager.listen(
                                            phoneStateListener,
                                            PhoneStateListener.LISTEN_CALL_STATE
                                        )
                                    }
                                }
                            
                            
                                inner class CustomPhoneStateListener(private val context: Context) : PhoneStateListener() {
                                    private var incomingNumber: String = ""
                            
                                    override fun onCallStateChanged(state: Int, phoneNumber: String) {
                                        if (phoneNumber.isNotEmpty()) incomingNumber = phoneNumber
                                        when (state) {
                                            //ringing
                                            TelephonyManager.CALL_STATE_RINGING -> {
                                                val intent = Intent(KEY_RECEIVER)
                                                intent.putExtra(PHONE_NUMBER, incomingNumber)
                                                context.sendBroadcast(intent)
                                            }
                                        }
                                    }
                                }
                            }
                            
                        

Java

The files consist of Helper.java, MainActivity.java and PhoneStateReceiver.java

Helper.java

                            
                            private boolean isAirplaneModeOn() {
                                return Settings.System.getInt(getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
                            }
                            
                        

MainActivity.java

                            
                            import android.Manifest;
                            import android.content.BroadcastReceiver;
                            import android.content.Context;
                            import android.content.Intent;
                            import android.content.IntentFilter;
                            import android.content.pm.PackageManager;
                            import android.os.Bundle;
                            import android.provider.Settings;
                            
                            import androidx.annotation.NonNull;
                            import androidx.annotation.Nullable;
                            import androidx.appcompat.app.AppCompatActivity;
                            import androidx.core.app.ActivityCompat;
                            import androidx.core.content.ContextCompat;
                            
                            import java.util.ArrayList;
                            import java.util.List;
                            
                            public class MainActivity extends AppCompatActivity {
                                String key; //OTP
                                int digits = 6; // 4 or 6 digits to pass verification
                            
                                private PhoneStateReceiver phoneStateReceiver = new PhoneStateReceiver();
                            
                                @Override
                                protected void onCreate(@Nullable Bundle savedInstanceState) {
                                    super.onCreate(savedInstanceState);
                                    setContentView(R.layout.activity_main);
                            
                                    //check READ_PHONE_STATE and READ_CALL_LOG permission
                                    List permissions = new ArrayList<>();
                                    if (ContextCompat.checkSelfPermission(
                                            this,
                                            Manifest.permission.READ_PHONE_STATE
                                    ) != PackageManager.PERMISSION_GRANTED
                                    ) {
                                        permissions.add(Manifest.permission.READ_PHONE_STATE);
                                    }
                                    if (ContextCompat.checkSelfPermission(
                                            this,
                                            Manifest.permission.READ_CALL_LOG
                                    ) != PackageManager.PERMISSION_GRANTED
                                    ) {
                                        permissions.add((Manifest.permission.READ_CALL_LOG));
                                    }
                            
                                    if (permissions.isEmpty()) {
                                        //register receivers if all permissions have been granted
                                        registerReceiver(phoneStateReceiver, new IntentFilter("android.intent.action.PHONE_STATE"));
                                        registerReceiver(keyReceiver, new IntentFilter(PhoneStateReceiver.KEY_RECEIVER));
                                    } else {
                                        //request permission(s) that has not been granted
                                        ActivityCompat.requestPermissions(this, permissions.toArray(new String[0]), 100);
                                    }
                                }
                            
                                //receiver to get the key
                                private BroadcastReceiver keyReceiver = new BroadcastReceiver() {
                                    @Override
                                    public void onReceive(Context context, Intent intent) {
                                        String phoneNumber = intent.getExtras().getString(PhoneStateReceiver.PHONE_NUMBER);
                                        key = phoneNumber.substring(phoneNumber.length()-digits);
                                    }
                                };
                            
                                @Override
                                public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
                                    boolean allGranted = true;
                                    if (requestCode == 100) {
                                        for (int result : grantResults) {
                                            if (result != PackageManager.PERMISSION_GRANTED) {
                                                allGranted = false;
                                                break;
                                            }
                                        }
                                        if (allGranted) {
                                            registerReceiver(
                                                    phoneStateReceiver,
                                                    new IntentFilter("android.intent.action.PHONE_STATE")
                                            );
                                        }
                                    }
                                }
                            
                                private boolean isAirplaneModeOn() {
                                    return Settings.System.getInt(getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
                                }
                            
                                @Override
                                protected void onDestroy() {
                                    super.onDestroy();
                                    //unregister receivers
                                    unregisterReceiver(keyReceiver);
                                    unregisterReceiver(phoneStateReceiver);
                                }
                            }
                            
                        

PhoneStateReceiver.java

                            
                            import android.content.BroadcastReceiver;
                            import android.content.Context;
                            import android.content.Intent;
                            import android.telephony.PhoneStateListener;
                            import android.telephony.TelephonyManager;
                            
                            public class PhoneStateReceiver extends BroadcastReceiver {
                                static CustomPhoneStateListener phoneStateListener;
                                static String PHONE_NUMBER = "PHONE_NUMBER";
                                static String KEY_RECEIVER = "KeyReceiver";
                            
                                @Override
                                public void onReceive(Context context, Intent intent) {
                                    TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
                            
                                    //onReceive will called multiple time, so we have to make sure the listener is only made once
                                    if (phoneStateListener == null) {
                                        phoneStateListener = new CustomPhoneStateListener(context);
                                        telephonyManager.listen(
                                                phoneStateListener,
                                                PhoneStateListener.LISTEN_CALL_STATE
                                        );
                                    }
                                }
                            
                                class CustomPhoneStateListener extends PhoneStateListener {
                                    Context context;
                                    private String incomingNumber;
                            
                                    public CustomPhoneStateListener(Context context) {
                                        this.context = context;
                                    }
                            
                                    @Override
                                    public void onCallStateChanged(int state, String phoneNumber) {
                                        if (!phoneNumber.isEmpty()) incomingNumber = phoneNumber;
                                        //ringing
                                        if (state == TelephonyManager.CALL_STATE_RINGING) {
                                            Intent intent = new Intent(KEY_RECEIVER);
                                            intent.putExtra(PHONE_NUMBER, incomingNumber);
                                            context.sendBroadcast(intent);
                                        }
                                    }
                                }
                            }