I've implemented the SMS Retriever API
like in the google tutorials and in my debug Build Variant work fine. I can read the sms and get the code to the user can do the login.
My problem is when I run the app in release Build Variant the sms it doesn't work. I receive the sms but I can't read the code to do the login.
I change the hash generated with AppSignatureHelper in release mode that is differente than in the debug mode. In debug work and in release no.
Some help will be appreciate
The code:
Manifest:
<receiver android:name=".app.receivers.SmsReceiver">
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
</intent-filter>
</receiver>
In my class: (In release and in debug mode the code go throw the onSucess method) This method is called in onCreate.
private void startSMSListening(){
SmsRetrieverClient client = SmsRetriever.getClient(this);
Task<Void> task = client.startSmsRetriever();
task.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
// Successfully started retriever, expect broadcast intent
Log.e("startSMSListening", "listening sms");
sendCode();
showHideLoadingView(false);
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// Failed to start retriever, inspect Exception for more details
Log.e("startSMSListening", "failure listening sms");
showHideLoadingView(false);
}
});
}
My receiver:
public class SmsReceiver extends BroadcastReceiver {
//interface
private static SmsListener mListener;
@Override
public void onReceive(Context context, Intent intent) {
if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
Bundle extras = intent.getExtras();
if(extras != null) {
Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
if(status != null) {
switch (status.getStatusCode()) {
case CommonStatusCodes.SUCCESS:
// Get SMS message contents
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
//Pass the message text to interface
if (mListener != null && !StringUtil.isNull(message)) {
mListener.messageReceived(message);
}
break;
case CommonStatusCodes.TIMEOUT:
Log.d("SMSReceiver", "timed out (5 minutes)");
break;
}
}
}
}
}
public static void bindListener(SmsListener listener) {
mListener = listener;
}
}
My smsReceiver method:
private void smsReceiver(){
SmsReceiver.bindListener(new SmsListener() {
@Override
public void messageReceived(String messageText) {
//From the received text string you may do string operations to get the required OTP
//It depends on your SMS format
Log.e("Message",messageText);
// If your OTP is six digits number, you may use the below code
Pattern pattern = Pattern.compile(OTP_REGEX);
Matcher matcher = pattern.matcher(messageText);
String otp = null;
while (matcher.find()) {
otp = matcher.group();
}
if(otp != null && et_code != null) {
et_code.setText(otp);
}
}
});
}
You must add release app string hash to message sent from server because release hash different from debug hash SMS retriever verify
I had the same problem by using
I got the otp for debug build but when I pushed that to playstore I would not auto read the otp.Actually it will generate the hashkey based on your application build variants type.
So Inorder to auto read your otp you will change the your hashkey in your server that will be generated in release mode.
So find the Hashkey in release mode and update it in your server.Thats it you will get It.
Then convert it to yourkeystore.keystore with keystore extension using this command:
keytool -import -alias your_alias -keystore file_name_created.keystore -file certificate.der
Then create string hash using the created keystore.
Use this file bash to create hash string:
https://github.com/googlesamples/android-credentials/tree/master/sms-verification/bin
First download your app signing certificate .der file then convert to .jks file by this command
then new .jks file created
then use this command for generate hash for your release
then create hash string and it will work on play store app.
Follow these steps to get the key for production:
Now when you run the commands to get the hash through AppSignatureHelper Class, that key will be your production key.
Few days ago, I had the same problem. Actually there is nothing wrong in your code. When you run your app and create hash, it create hash only for device specific. When your generate signed apk and create hash ( using log ), then this hash is only for release but not for production. In case of production, you have to install app from play store and check hash ( using logs ) and that hash will use for all users.
Hope it will help you