短信令牌无法响应

2022-01-28 09:27:09 标签 android

我有下面的代码试图与短信令牌,我得到令牌代码,但一旦我发送它在短信,我没有回应!

MainActivity。kt

package com.sms
import android.app.PendingIntent
import android.content.Intent
import android.os.Bundle
import android.telephony.SmsManager
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.google.android.gms.auth.api.phone.SmsRetriever
import com.google.android.gms.auth.api.phone.SmsRetrieverClient
import com.sms.ui.theme.SmsTheme
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // val smsManager: SmsManager = SmsManager.getDefault()
        val smsManager: SmsManager = getSystemService(SmsManager::class.java)
        val appSmsToken = smsManager.createAppSpecificSmsToken(createSmsTokenPendingIntent())
        print(appSmsToken)
        setContent {
            SmsTheme {
                // A surface container using the 'background' color from the theme
                Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
                    Greeting(appSmsToken)
                }
            }
        }
    }
    private fun createSmsTokenPendingIntent(): PendingIntent? {
        return PendingIntent.getActivity(
            this, 1234,
            Intent(this, SmsTokenResultVerificationActivity::class.java), 
 PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT) // setting the mutability flag
    }
}
@Composable
fun Greeting(name: String) {
    Text(text = "Token is: $name")
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    SmsTheme {
        Greeting("Android")
    }
}

和SmsTokenResultVerificationActivity。kt是:

package com.sms
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.sms.ui.theme.SmsTheme
class SmsTokenResultVerificationActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            SmsTheme {
                // A surface container using the 'background' color from the theme
                Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
                    Greeting("Welcome")
                }
            }
        }
    }
    @Composable
    fun Greeting(name: String) {
        Text(text = "hi: $name")
    }
}

###作为另一个选择,我发现使用SMS retriever API in Android could solve it but I still interested但我还是有兴趣用Token as i want my app to depend on the user device因为我想让我的应用依赖于用户device token rather than the app 令牌而不是app token.

令牌。

BaseApplication。kt

package com.shishirthedev.smsretriverapi
import android.app.Application
import android.util.Log
import android.widget.Toast
class BaseApplication : Application() {
    private val TAG = BaseApplication::class.java.simpleName
    override fun onCreate() {
        super.onCreate()
        // Generate Hash Key >>>>>
        val appSignatureHashHelper = AppSignatureHashHelper(this)
        Log.e(TAG, "HashKey: " + appSignatureHashHelper.appSignatures[0])
        var msg = "HashKey: " + appSignatureHashHelper.appSignatures[0]
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
        // Storing data into SharedPreferences
        val sharedPreferences = getSharedPreferences("MySharedPref", MODE_PRIVATE)
        // Creating an Editor object to edit(write to the file)
        val myEdit = sharedPreferences.edit()
        // Storing the key and its value as the data fetched from edittext
        myEdit.putString("token", appSignatureHashHelper.appSignatures[0])
       // myEdit.putInt("age", age.getText().toString().toInt())
        // Once the changes have been made,
        // we need to commit to apply those changes made,
        // otherwise, it will throw an error
        myEdit.commit()
    }
}

AppSignatureHashHelper。kt

package com.shishirthedev.smsretriverapi
import android.annotation.TargetApi
import android.content.Context
import android.content.ContextWrapper
import android.content.pm.PackageManager
import android.util.Base64
import android.util.Log
import java.nio.charset.StandardCharsets
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.*
class AppSignatureHashHelper(context: Context?) :
    ContextWrapper(context) {// Get all package details
    /**
     * Get all the app signatures for the current package
     *
     * @return
     */
    val appSignatures: ArrayList<String>
        get() {
            val appSignaturesHashs = ArrayList<String>()
            try {
                // Get all package details
                val packageName = packageName
                val packageManager = packageManager
                val signatures = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
                    packageManager.getPackageInfo(
                        packageName,
                        PackageManager.GET_SIGNING_CERTIFICATES
                    ).signingInfo.apkContentsSigners
                } else {
                    TODO("VERSION.SDK_INT < P")
                }
                for (signature in signatures) {
                    val hash = hash(packageName, signature.toCharsString())
                    if (hash != null) {
                        appSignaturesHashs.add(String.format("%s", hash))
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "Package not found", e)
            }
            return appSignaturesHashs
        }
    companion object {
        val TAG = AppSignatureHashHelper::class.java.simpleName
        private const val HASH_TYPE = "SHA-256"
        const val NUM_HASHED_BYTES = 9
        const val NUM_BASE64_CHAR = 11
        @TargetApi(19)
        private fun hash(packageName: String, signature: String): String? {
            val appInfo = "$packageName $signature"
            try {
                val messageDigest = MessageDigest.getInstance(HASH_TYPE)
                messageDigest.update(appInfo.toByteArray(StandardCharsets.UTF_8))
                var hashSignature = messageDigest.digest()
                // truncated into NUM_HASHED_BYTES
                hashSignature = Arrays.copyOfRange(hashSignature, 0, NUM_HASHED_BYTES)
                // encode into Base64
                var base64Hash =
                    Base64.encodeToString(hashSignature, Base64.NO_PADDING or Base64.NO_WRAP)
                base64Hash = base64Hash.substring(0, NUM_BASE64_CHAR)
                return base64Hash
            } catch (e: NoSuchAlgorithmException) {
                Log.e(TAG, "No Such Algorithm Exception", e)
            }
            return null
        }
    }
}

SMSReceiver。kt”

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.google.android.gms.auth.api.phone.SmsRetriever
import com.google.android.gms.common.api.CommonStatusCodes
import com.google.android.gms.common.api.Status
import java.util.regex.Pattern
class SMSReceiver : BroadcastReceiver() {
    private var otpListener: OTPReceiveListener? = null
    fun setOTPListener(otpListener: OTPReceiveListener?) {
        this.otpListener = otpListener
    }
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == SmsRetriever.SMS_RETRIEVED_ACTION) {
            val extras = intent.extras
            val status = extras!![SmsRetriever.EXTRA_STATUS] as Status?
            when (status!!.statusCode) {
                CommonStatusCodes.SUCCESS -> {
                    val sms = extras[SmsRetriever.EXTRA_SMS_MESSAGE] as String?
                    sms?.let {
                        // val p = Pattern.compile("[0-9]+") check a pattern with only digit
                        val p = Pattern.compile("\\d+")
                        val m = p.matcher(it)
                        if (m.find()) {
                            val otp = m.group()
                            if (otpListener != null) {
                                otpListener!!.onOTPReceived(otp)
                            }
                        }
                    }
                }
            }
        }
    }
    interface OTPReceiveListener {
        fun onOTPReceived(otp: String?)
    }
}

MainActivity。kt

package com.shishirthedev.smsretriverapi
import android.content.IntentFilter
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.auth.api.phone.SmsRetriever
import com.shishirthedev.smsretriverapi.SMSReceiver.OTPReceiveListener
class MainActivity : AppCompatActivity() {
    private var intentFilter: IntentFilter? = null
    private var smsReceiver: SMSReceiver? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var token = findViewById<TextView>(R.id.textView)
        // Retrieving the value using its keys the file name
        // must be same in both saving and retrieving the data
        val sh = getSharedPreferences("MySharedPref", MODE_PRIVATE)
        // The value will be default as empty string because for
        // the very first time when the app is opened, there is nothing to show
        val t = sh.getString("token", "")
        //  val a = sh.getInt("age", 0)
        // We can then use the data
        token.text = t
       // age.setText(a.toString())
        // Init Sms Retriever >>>>
        initSmsListener()
        initBroadCast()
    }
    private fun initBroadCast() {
        intentFilter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION)
        smsReceiver = SMSReceiver()
        smsReceiver?.setOTPListener(object : OTPReceiveListener {
            override fun onOTPReceived(otp: String?) {
                showToast("OTP Received: $otp")
            }
        })
    }
    private fun initSmsListener() {
        val client = SmsRetriever.getClient(this)
        client.startSmsRetriever()
    }
    override fun onResume() {
        super.onResume()
        registerReceiver(smsReceiver, intentFilter)
    }
    override fun onPause() {
        super.onPause()
        unregisterReceiver(smsReceiver)
    }
    override fun onDestroy() {
        super.onDestroy()
        smsReceiver = null
    }
    private fun showToast(msg: String?) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
    }
}

清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.shishirthedev.smsretriverapi">
    <application
        android:name=".BaseApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.SmsRetriverAPi">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

构建。gradle(模块)

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}
android {
    compileSdkVersion 30
    buildToolsVersion "29.0.3"
    defaultConfig {
        applicationId "com.shishirthedev.smsretriverapi"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}
dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    implementation 'com.google.android.gms:play-services-auth:19.0.0'
    implementation 'com.google.android.gms:play-services-auth-api-phone:17.5.0'
}

“构建。gradle(项目)

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.4.10"
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.1.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
allprojects {
    repositories {
        google()
        jcenter()
    }
}
task clean(type: Delete) {
    delete rootProject.buildDir
}

信贷去

SHISHIR

阅读全文

▼ 版权说明

相关文章也很精彩
推荐内容
更多标签
相关热门
全站排行
随便看看

错说 cuoshuo.com —— 程序员的报错记录

部分内容根据CC版权协议转载;网站内容仅供参考,生产环境使用务必查阅官方文档

辽ICP备19011660号-5

×

扫码关注公众号:职场神器
发送: 1
获取永久解锁本站全部文章的验证码