为什么SMS Retriever API在发布模式下不起作用?

时间:2018-12-20 09:42:19

标签: android android-intent android-broadcast android-broadcastreceiver android-sms

我已经像Google教程中一样实现了SMS Retriever API,并且在我的调试版本变体中正常工作。我可以阅读短信,并将代码获取给用户可以进行登录。

我的问题是,当我在Build Variant版本中运行该应用程序时,该短信不起作用。我收到短信了,但是我无法阅读代码来登录。

我在发布模式下更改由AppSignatureHelper 生成的散列,该散列与在调试模式下不同。在调试工作和发行版本中。

一些帮助将不胜感激

代码:

清单:

   <receiver android:name=".app.receivers.SmsReceiver">
        <intent-filter>
            <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
        </intent-filter>
    </receiver>

在我的课堂上:(在发布和调试模式下,代码将引发onSucess方法)。该方法在 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);
        }
    });
}

我的接收者:

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

我的smsReceiver方法:

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

9 个答案:

答案 0 :(得分:3)

请按照以下步骤获取生产密钥:

  1. 转到构建选项。
  2. 在选项中,选择选择构建变体
  3. 然后在左上角打开一个对话框,将Build Variant从 debug 更改为 release
  4. 单击运行,然后将打开以下对话框: Then this dialog will open(point 4 pic.)
  5. 单击运行,然后单击仍然继续,然后单击,然后在对话框In this dialog Click on the **+** in left bottom中。
  6. li>
  7. 然后填写以下详细信息:Then fill these details
  8. 现在转到构建类型并遵循以下图片:Then go to build types and follow the image
  9. 然后单击确定

现在,当您运行命令以通过AppSignatureHelper Class获取哈希时,该密钥将成为您的生产密钥。

答案 1 :(得分:2)

首先下载您的应用程序签名证书.der文件,然后通过此命令将其转换为.jks文件

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

然后创建新的.jks文件

然后使用此命令为您的发行版生成哈希

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

然后创建哈希字符串,它将在Play商店应用中正常工作。

答案 2 :(得分:2)

几天前,我遇到了同样的问题。实际上,您的代码没有错。当您运行应用并创建哈希时,它仅针对特定设备创建哈希。当您生成签名的apk并创建哈希(使用log)时,则此哈希仅用于发布,不适用于生产。如果是量产版,则必须从Play商店安装应用并检查哈希(使用logs),该哈希将用于所有用户。

希望对您有帮助

答案 3 :(得分:0)

您是否生成了相对的哈希值,并通过服务器上的短信发送了该值?

答案 4 :(得分:0)

  1. 首先从您的播放控制台帐户下载应用程序签名的证书der。
  2. 然后使用以下命令将其转换为带有密钥库扩展名的yourkeystore.keystore:

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

  3. 然后使用创建的密钥库创建字符串哈希。
    使用此文件bash创建哈希字符串:
    https://github.com/googlesamples/android-credentials/tree/master/sms-verification/bin

答案 5 :(得分:0)

您必须在服务器发送的消息中添加发布应用程序字符串哈希,因为发布哈希与调试哈希不同 SMS retriever verify

答案 6 :(得分:0)

我使用

遇到了同样的问题
  

SMSRETRIEVERAPI

我获得了用于调试构建的otp,但是当我将其推送到playstore时,我不会自动读取otp。实际上,它将根据您的应用程序构建变体类型生成哈希键。So Inorder to auto read your otp you will change the your hashkey in your server that will be generated in release mode.

因此在发布模式下找到Hashkey并在服务器中对其进行更新。这样您就可以获取它。

答案 7 :(得分:0)

我建议您在发布 -> 设置 -> 应用签名下复制生产中应用的 SHA-1 和 SHA-256。

然后转到您的 firebase 控制台,选择您的项目 -> 项目设置,只需将 SHA-1 和 SHA-256 粘贴到“SHA 证书指纹”下

给你,,,,

答案 8 :(得分:0)

我在生产应用程序中遇到了同样的问题,不应该怪哈希码本身。确保其 11 个字符 长。我在哈希码中有一个斜线,这让我很困惑。

例如:P/adbDKExdk