Why SMS Retriever API don't work in release mode?

S.P. picture S.P. · Dec 20, 2018 · Viewed 8.7k times · Source

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);
                }
            }
        });
    }

Answer

Pankaj Jain picture Pankaj Jain · Jan 11, 2019

First download your app signing certificate .der file then convert to .jks file by this command

keytool -import -alias your_alias -keystore file_name_created -file certificate.der

then new .jks file created

then use this command for generate hash for your release

keytool -exportcert -alias your_alias -keystore certificate.jks | xxd -p | tr -d "[:space:]" | echo -n  app_package_name `cat` | sha256sum | tr -d "[:space:]-" | xxd -r -p | base64 | cut -c1-11

then create hash string and it will work on play store app.