Why SMS Retriever API don't work in release mo

2020-02-28 04:21发布

问题:

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

回答1:

Follow these steps to get the key for production:

  1. Go to the Build option.
  2. In the options, choose Select Build Variant.
  3. Then in the left corner, a dialog will open, from there Change Build Variant from debug to release.
  4. Click on run, then this dialog will open:
  5. Click on Run, next click on Continue Anyway, then click on Yes then in the dialog .
  6. Then fill these details:
  7. Now go to Build Types and follow this image:
  8. And click ok.

Now when you run the commands to get the hash through AppSignatureHelper Class, that key will be your production key.



回答2:

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.



回答3:

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



回答4:

  1. First download app signed certificate der from your play console account.
  2. 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

  3. 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



回答5:

You must add release app string hash to message sent from server because release hash different from debug hash SMS retriever verify



回答6:

I had the same problem by using

SMSRETRIEVERAPI

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.