我正在使用 SMS Retriever API,我遵循了本教程Tutorial_Link。我正确地遵循了所有步骤。只是我使用的作弊码:我从客户端而不是服务器发送和验证 OTP SMS。我正在接收短信,但我的广播接收器无法检测到短信。为什么?
一次性密码:
String message = "<#> otp code: "+otp+" XkvuQVe6yfP";
请帮助我,我从过去三天就卡在这里......这是我的代码:
Forgot_Password.kt :
class Forgot_Password : AppCompatActivity(), MySMSBroadcastReceiver.OTPReceiveListener {
private var otpReceiver: MySMSBroadcastReceiver.OTPReceiveListener = this
val smsBroadcast = MySMSBroadcastReceiver()
@RequiresApi(Build.VERSION_CODES.KITKAT)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_forgot__password)
btn_submit_mobile.setOnClickListener { v ->
verify_mobile_number()
}
}
override fun onOTPReceived(otp: String) {
LocalBroadcastManager.getInstance(this).unregisterReceiver(smsBroadcast)
ed_otp.setText("Your OTP is: $otp")
}
override fun onOTPTimeOut() {
ed_otp.setText("Timeout")
Toast.makeText(this, " SMS retriever API Timeout", Toast.LENGTH_SHORT).show()
}
private fun startSMSListener() {
SmsRetriever.getClient(this).startSmsRetriever()
.addOnSuccessListener {
ed_otp.setText("Waiting for OTP")
Toast.makeText(this, "SMS Retriever starts", Toast.LENGTH_LONG).show()
}.addOnFailureListener {
ed_otp.setText("Cannot Start SMS Retriever")
Toast.makeText(this, "Error", Toast.LENGTH_LONG).show()
}
smsBroadcast.initOTPListener(this)
val intentFilter = IntentFilter()
intentFilter.addAction(SmsRetriever.SMS_RETRIEVED_ACTION)
applicationContext.registerReceiver(smsBroadcast, intentFilter)
}
public override fun onResume() {
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, IntentFilter("otp"))
super.onResume()
}
public override fun onPause() {
super.onPause()
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver)
}
private fun verify_mobile_number() {
mobile_num = ed_mobile_num.text.toString()
//if it passes all the validations
class Verify_mobile : AsyncTask<Void, Void, String>() {
private val progressBar: ProgressBar? = null
override fun doInBackground(vararg voids: Void): String {
//creating request handler object
val requestHandler = RequestHandler()
val params = HashMap<String, String>()
params["U_Mobile_Number"] = mobile_num + ""
//returing the response
return requestHandler.sendPostRequest(URLs.URL_VERIFY_MOBILE_NUMBER, params)
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@RequiresApi(Build.VERSION_CODES.KITKAT)
override fun onPostExecute(s: String?) {
super.onPostExecute(s)
try {
Log.i("result", "123" + s!!)
if (s == "") {
val snackbar = Snackbar
.make(top_layout, "Problem connecting server,try again!", Snackbar.LENGTH_LONG)
snackbar.show()
} else {
val obj = JSONObject(s)
if (!obj.getBoolean("error")) {
startSMSListener()
var signs = AppSignatureHelper(applicationContext).appSignatures
Log.i("hash___", (AppSignatureHelper(applicationContext).appSignatures+"").toString())
for (item in signs) {
Log.i("hash",item)
val sm = sendSMS()
sm.sendSms(mobile_num,item+"")
}
} else {
val snackbar = Snackbar
.make(top_layout, "Some error occurred!" + obj.getString("message"), Snackbar.LENGTH_LONG)
snackbar.show()
}
}
} catch (e: Exception) {
e.printStackTrace()
val snackbar = Snackbar
.make(top_layout, "Problem connecting server,try again!", Snackbar.LENGTH_LONG)
snackbar.show()
}
}
}
//executing the async task
val ru = Verify_mobile()
ru.execute()
}
}
MySMSBroadcastReceiver.kt:
class MySMSBroadcastReceiver : BroadcastReceiver() {
private var otpReceiver: OTPReceiveListener? = null
fun initOTPListener(receiver: OTPReceiveListener) {
this.otpReceiver = receiver
}
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
var otp: String = extras.get(SmsRetriever.EXTRA_SMS_MESSAGE) as String
val pattern = Pattern.compile("(\\d{4})")
val matcher = pattern.matcher(otp)
// Extract one-time code from the message and complete verification
var value = ""
if (matcher.find()) {
System.out.println(matcher.group(1))
value = matcher.group(1)
}
println("message : $value")
otpReceiver?.onOTPReceived(value)
}
CommonStatusCodes.TIMEOUT ->
// Waiting for SMS timed out (5 minutes)
otpReceiver?.onOTPTimeOut()
}
}
}
interface OTPReceiveListener {
fun onOTPReceived(otp: String)
fun onOTPTimeOut()
}
}
AppSignatureHelper.java:
public class AppSignatureHelper extends ContextWrapper {
public static final String TAG = AppSignatureHelper.class.getSimpleName();
private static final String HASH_TYPE = "SHA-256";
public static final int NUM_HASHED_BYTES = 9;
public static final int NUM_BASE64_CHAR = 11;
public AppSignatureHelper(Context context) {
super(context);
}
/**
* Get all the app signatures for the current package
*
* @return
*/
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public ArrayList<String> getAppSignatures() {
ArrayList<String> appCodes = new ArrayList<>();
try {
// Get all package signatures for the current package
String packageName = getPackageName();
PackageManager packageManager = getPackageManager();
Signature[] signatures = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures;
// For each signature create a compatible hash
for (Signature signature : signatures) {
String hash = hash(packageName, signature.toCharsString());
if (hash != null) appCodes.add(String.format("%s", hash));
}
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Unable to find package to obtain hash.", e);
}
return appCodes;
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private static String hash(String packageName, String signature) {
String appInfo = packageName + " " + signature;
try {
MessageDigest messageDigest = MessageDigest.getInstance(HASH_TYPE);
messageDigest.update(appInfo.getBytes(StandardCharsets.UTF_8));
byte[] hashSignature = messageDigest.digest();
// truncated into NUM_HASHED_BYTES
hashSignature = Arrays.copyOfRange(hashSignature, 0, NUM_HASHED_BYTES);
// encode into Base64
String base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING | Base64.NO_WRAP);
base64Hash = base64Hash.substring(0, NUM_BASE64_CHAR);
Log.e(TAG, String.format("pkg: %s -- hash: %s", packageName, base64Hash));
return base64Hash;
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, "hash:NoSuchAlgorithm", e);
}
return null;
}
}
Androidmanifest.xml:
<receiver android:name="threedpower.com.babynamesapp.SMS_Retrival_API.SMS_Broadcast" android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
</intent-filter>
</receiver>