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

Posted

技术标签:

【中文标题】为啥 SMS Retriever API 在发布模式下不起作用?【英文标题】:Why SMS Retriever API don't work in release mode?为什么 SMS Retriever API 在发布模式下不起作用? 【发布时间】:2019-05-20 19:34:56 【问题描述】:

我已经实现了SMS Retriever API,就像在 google 教程中一样,并且在我的调试 Build Variant 中工作正常。我可以阅读短信并将代码发送给用户可以登录。

我的问题是,当我在 release 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);
                
            
        );
    

【问题讨论】:

确保您使用了正确的别名和密钥库文件,用于签署您的 apk。 我已经在发布模式下测试了我的应用,它运行良好。 @taranjeetsapra 我的应用程序仅在调试模式下工作。一旦签署了 APK,则不会检测到消息。我也成功创建了哈希。 嘿,你找到解决办法了吗?我也面临同样的问题。 是的,问题出在后面,短信的语法正确 【参考方案1】:

首先下载您的应用签名证书 .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 商店应用程序上运行。

【讨论】:

'xxd' 不是内部或外部命令、可运行程序或批处理文件。 谢谢@Pankaj....@Mohsin 你应该在你的项目目录中使用 Git bash 然后它会工作。【参考方案2】:

几天前,我遇到了同样的问题。实际上,您的代码没有任何问题。当您运行您的应用程序并创建哈希时,它仅为特定设备创建哈希。当您生成签名的 apk 并创建哈希(使用 log )时,此哈希仅用于发布而不用于生产。在生产的情况下,您必须从 Play 商店安装应用并检查哈希(使用日志),该哈希将用于所有用户。

希望对你有帮助

您可以使用此链接创建 hashkey:

https://github.com/arsalankhan994/AppSignatureHelper/tree/main

【讨论】:

它对我有用。要获取 hashkey,请使用此链接 ***.com/a/54052163/7301510【参考方案3】:
    首先从您的 Play 控制台帐户下载应用签名证书。

    然后使用以下命令将其转换为带有密钥库扩展名的 yourkeystore.keystore:

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

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

【讨论】:

【参考方案4】:

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

    转到构建选项。 在选项中,选择选择构建变体。 然后会在左下角打开一个对话框,从那里将 Build Variant 从 debug 更改为 release。 单击运行,然后将打开此对话框: 点击Run,然后点击Continue Anyway,然后点击Yes,然后在对话框中。 然后填写这些详细信息: 现在转到 Build Types 并按照此图片操作: 然后点击确定

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

【讨论】:

【参考方案5】:

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

【讨论】:

【参考方案6】:

我在使用

时遇到了同样的问题

SMSRETRIEVERAPI

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

所以在发布模式下找到哈希键并在你的服务器中更新它。这样你就会得到它。

【讨论】:

【参考方案7】:

我建议您在生产环境中复制应用的 SHA-1 和 SHA-256,在 Release -> Setup -> App Signing 下。

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

给你,,,

【讨论】:

【参考方案8】:

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

例如:P/adbDKExdk

【讨论】:

以上是关于为啥 SMS Retriever API 在发布模式下不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

SMS Retriever API - 如何以编程方式获取 SMS?

SMS Retriever API - 永久监听器

使用 SMS Retriever API Android 的 OTP/SMS 自动获取问题

如何使用 Google App 签名为 Sms Retriever 生成 11 个字符的哈希密钥

每次获取不同App的Hash String |短信检索 API

retriever.getFrameAtTime 不准确,如何获取视频截图?