You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Android注册流程中实现短信验证码自动填充至EditText的需求

Alright, let's figure out how to implement auto-filling the SMS verification code into your EditText after the user taps "Send SMS" — this will make the flow way smoother for your users. Below are the two most practical approaches, tailored for different Android version targets:

This is the go-to method now because it doesn't require the RECEIVE_SMS permission, making your app more secure and compliant with modern Android policies. Here's how to set it up:

  • Add the required dependency
    In your app-level build.gradle (Module level), add this line to the dependencies block:

    implementation "com.google.android.gms:play-services-auth-api-phone:18.0.1"
    

    (You can check for the latest version in Google's Maven repo if needed.)

  • Initialize the SMS Retriever client in your Activity
    In the Activity where you handle verification, set up the client and a callback to listen for incoming SMS:

    // Kotlin example
    val client = SmsRetriever.getClient(this /* context */)
    val task = client.startSmsRetriever()
    
    task.addOnSuccessListener {
        // Successfully started retriever, wait for SMS
        Toast.makeText(this, "Waiting for verification SMS...", Toast.LENGTH_SHORT).show()
    }
    
    task.addOnFailureListener {
        // Failed to start retriever, show error message
        Toast.makeText(this, "Failed to start SMS retriever", Toast.LENGTH_SHORT).show()
    }
    
  • Ensure your SMS follows the required format
    The SMS sent from your server must start with <#> and end with your app's unique hash string. For example:

    <#> Your verification code is 123456 FA+9qCX9VSu

    To get your app's hash string, you can use this small code snippet (only needed once to get the hash for your production keystore):

    // Kotlin code to generate app hash
    fun getAppHash(context: Context): String {
        val packageName = context.packageName
        val signature = context.packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures[0]
        val message = signature.toByteArray() + "com.google.android.gms.auth.api.phone.SmsRetrieverApi"
        val md = MessageDigest.getInstance("SHA-256")
        md.update(message.toByteArray(Charsets.UTF_8))
        return Base64.encodeToString(md.digest(), Base64.NO_WRAP)
    }
    
  • Handle the retrieved SMS and fill the code
    Create a broadcast receiver to catch the SMS Retriever intent, extract the code, and populate your EditText:

    class SmsVerificationReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (SmsRetriever.SMS_RETRIEVED_ACTION == intent?.action) {
                val extras = intent.extras
                val status = extras?.get(SmsRetriever.EXTRA_STATUS) as Status
    
                when (status.statusCode) {
                    CommonStatusCodes.SUCCESS -> {
                        // Get SMS message contents
                        val message = extras.get(SmsRetriever.EXTRA_SMS_MESSAGE) as String
                        // Extract verification code (adjust regex to match your code length)
                        val codePattern = Pattern.compile("\\d{6}") // Matches 6-digit codes
                        val matcher = codePattern.matcher(message)
                        if (matcher.find()) {
                            val verificationCode = matcher.group(0)
                            // Update EditText on UI thread
                            (context as? YourVerificationActivity)?.runOnUiThread {
                                context.yourEditText.setText(verificationCode)
                                // Optional: Auto-trigger the "Verify" button click
                                context.verifyButton.performClick()
                            }
                        }
                    }
                    CommonStatusCodes.TIMEOUT -> {
                        // SMS not received within 5 minutes, show error
                        Toast.makeText(context, "SMS verification timed out", Toast.LENGTH_SHORT).show()
                    }
                }
            }
        }
    }
    

    Don't forget to register this receiver dynamically in your Activity's onCreate method:

    val receiver = SmsVerificationReceiver()
    registerReceiver(receiver, IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION))
    

    And unregister it in onDestroy:

    unregisterReceiver(receiver)
    
2. Traditional SMS Broadcast Receiver (For Android < 8.0 Compatibility)

If you need to support older Android versions (before 8.0), you can use a broadcast receiver, but note that this requires the RECEIVE_SMS permission and has restrictions on Android 10+.

  • Declare permissions
    Add this to your AndroidManifest.xml:

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

    For Android 6.0+, you'll need to request this permission dynamically from the user before registering the receiver.

  • Create the SMS Broadcast Receiver

    class SmsReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION == intent?.action) {
                val smsMessages = Telephony.Sms.Intents.getMessagesFromIntent(intent)
                for (message in smsMessages) {
                    val smsBody = message.messageBody
                    // Extract verification code
                    val codePattern = Pattern.compile("\\d{6}")
                    val matcher = codePattern.matcher(smsBody)
                    if (matcher.find()) {
                        val code = matcher.group(0)
                        (context as? YourVerificationActivity)?.runOnUiThread {
                            context.yourEditText.setText(code)
                            // Auto-click verify button if needed
                            context.verifyButton.performClick()
                        }
                        abortBroadcast() // Prevent other apps from receiving this SMS
                        break
                    }
                }
            }
        }
    }
    
  • Register the receiver dynamically
    Dynamic registration is better than static to avoid being blocked by Android's background restrictions:

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) == PackageManager.PERMISSION_GRANTED) {
        val smsReceiver = SmsReceiver()
        registerReceiver(smsReceiver, IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION))
    } else {
        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.RECEIVE_SMS), REQUEST_CODE_SMS_PERMISSION)
    }
    

Pro Tips:

  • Adjust the regex pattern (\\d{6}) to match your verification code's length (e.g., \\d{4} for 4-digit codes).
  • For the SMS Retriever API, make sure your server sends the exact hash string — using the wrong hash will prevent the API from detecting the SMS.
  • Always handle cases where the user doesn't receive the SMS (timeouts, permission denials) with clear error messages.

内容的提问来源于stack exchange,提问作者NaSt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:29:42