首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >应自动从消息中读取OTP (令牌

应自动从消息中读取OTP (令牌
EN

Stack Overflow用户
提问于 2015-06-16 16:14:39
回答 9查看 130.1K关注 0票数 52

我在一个安卓应用程序上工作,其中服务器发送一个动态口令,用户需要在应用程序中输入这个动态口令,我的应用程序的SignUp。我想要的是,我的应用程序应该能够自动读取服务器发送的动态口令。我如何才能做到这一点?在这方面的任何帮助或指导都将受到高度赞赏。

EN

回答 9

Stack Overflow用户

发布于 2017-05-16 14:34:06

我建议你不要使用任何第三方库从短信收件箱自动获取动态口令。如果你对广播接收器和它的工作原理有基本的了解,这是很容易做到的。只需尝试以下方法:

  1. 创建单一界面,即SmsListner

代码语言:javascript
复制
package com.wnrcorp.reba;
public interface SmsListener {
    public void messageReceived(String messageText);
}

  1. 创建单一广播接收器,即SmsReceiver

代码语言:javascript
复制
package com.wnrcorp.reba;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;

public class SmsReceiver extends BroadcastReceiver {
    private static SmsListener mListener;
    Boolean b;
    String abcd, xyz;
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle data = intent.getExtras();
        Object[] pdus = (Object[]) data.get("pdus");
        for (int i = 0; i < pdus.length; i++) {
            SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
            String sender = smsMessage.getDisplayOriginatingAddress();
            // b=sender.endsWith("WNRCRP");  //Just to fetch otp sent from WNRCRP
            String messageBody = smsMessage.getMessageBody();
            abcd = messageBody.replaceAll("[^0-9]", ""); // here abcd contains otp 
            which is in number format
            //Pass on the text to our listener.
            if (b == true) {
                mListener.messageReceived(abcd); // attach value to interface 
                object
            } else {}
        }
    }
    public static void bindListener(SmsListener listener) {
        mListener = listener;
    }
}

  1. 在android清单文件

中添加侦听器,即广播接收器

代码语言:javascript
复制
<receiver android:name=".SmsReceiver">
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
</receiver>

并添加权限

代码语言:javascript
复制
<uses-permission android:name="android.permission.RECEIVE_SMS"/>

  1. 当收件箱中收到动态口令时,您将在其中自动获取动态口令的活动。在我的示例中,我正在获取动态口令并设置为edittext字段。

代码语言:javascript
复制
public class OtpVerificationActivity extends AppCompatActivity {
    EditText ed;
    TextView tv;
    String otp_generated, contactNo, id1;
    GlobalData gd = new GlobalData();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_otp_verification);
            ed = (EditText) findViewById(R.id.otp);
            tv = (TextView) findViewById(R.id.verify_otp);
            /*This is important because this will be called every time you receive 
             any sms */
            SmsReceiver.bindListener(new SmsListener() {
                @Override
                public void messageReceived(String messageText) {
                    ed.setText(messageText);
                }
            });
            tv.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        try {
                            InputMethodManager imm =
                                (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
                            imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
                        } catch (Exception e) {}
                        if (ed.getText().toString().equals(otp_generated)) {
                            Toast.makeText(OtpVerificationActivity.this, "OTP Verified 
                                Successfully!", Toast.LENGTH_SHORT).show();           
                            }
                        });
                }
            }
}

OtpVerificationActivity的布局文件

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_otp_verification"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.wnrcorp.reba.OtpVerificationActivity">
    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/firstcard"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        card_view:cardCornerRadius="10dp"
        >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:background="@android:color/white">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="OTP Confirmation"
                android:textSize="18sp"
                android:textStyle="bold"
                android:id="@+id/dialogTitle"
                android:layout_margin="5dp"
                android:layout_gravity="center"
                />
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/otp"
                android:layout_margin="5dp"
                android:hint="OTP Here"
                />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Verify"
                android:textSize="18sp"
                android:id="@+id/verify_otp"
                android:gravity="center"
                android:padding="10dp"
                android:layout_gravity="center"
                android:visibility="visible"
                android:layout_margin="5dp"
                android:background="@color/colorPrimary"
                android:textColor="#ffffff"
                />
        </LinearLayout>
    </android.support.v7.widget.CardView>
</RelativeLayout>

OTP验证活动的屏幕截图,在该活动中,您可以在收到消息后立即获取OTP

票数 35
EN

Stack Overflow用户

发布于 2016-09-15 19:25:13

您可以尝试使用简单的库like

通过gradle安装并添加权限后,使用类似onCreate activity的方法启动SmsVerifyCatcher:

代码语言:javascript
复制
    smsVerifyCatcher = new SmsVerifyCatcher(this, new OnSmsCatchListener<String>() {
    @Override
    public void onSmsCatch(String message) {
        String code = parseCode(message);//Parse verification code
        etCode.setText(code);//set code in edit text
        //then you can send verification code to server
    }
});

另外,覆盖活动生命周期方法:

代码语言:javascript
复制
  @Override
protected void onStart() {
    super.onStart();
    smsVerifyCatcher.onStart();
}

@Override
protected void onStop() {
    super.onStop();
    smsVerifyCatcher.onStop();
}

/**
 * need for Android 6 real time permissions
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    smsVerifyCatcher.onRequestPermissionsResult(requestCode, permissions, grantResults);
}


public String parseCode(String message) {
    Pattern p = Pattern.compile("\\b\\d{4}\\b");
    Matcher m = p.matcher(message);
    String code = "";
    while (m.find()) {
        code = m.group(0);
    }
    return code;
}
票数 26
EN

Stack Overflow用户

发布于 2019-02-02 17:49:24

因为谷歌已经限制了READ_SMS权限的使用,这里是没有READ_SMS权限的解决方案。

SMS Retriever API

基本功能是避免使用Android critical permission READ_SMS,使用该方法完成任务。吹气是你需要的步骤。

向用户号码发送动态口令后,检查短信检索器接口是否能收到消息或不是

代码语言:javascript
复制
SmsRetrieverClient client = SmsRetriever.getClient(SignupSetResetPasswordActivity.this);
Task<Void> task = client.startSmsRetriever();
task.addOnSuccessListener(new OnSuccessListener<Void>() {
    @Override
    public void onSuccess(Void aVoid) {
        // Android will provide message once receive. Start your broadcast receiver.
        IntentFilter filter = new IntentFilter();
        filter.addAction(SmsRetriever.SMS_RETRIEVED_ACTION);
        registerReceiver(new SmsReceiver(), filter);
    }
});
task.addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        // Failed to start retriever, inspect Exception for more details
    }
});

广播接收器代码

代码语言:javascript
复制
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;

import com.google.android.gms.auth.api.phone.SmsRetriever;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.common.api.Status;

public class SmsReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
            Bundle extras = intent.getExtras();
            Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);

            switch (status.getStatusCode()) {
                case CommonStatusCodes.SUCCESS:
                    // Get SMS message contents
                    String otp;
                    String msgs = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);

                    // Extract one-time code from the message and complete verification
                    break;
                case CommonStatusCodes.TIMEOUT:
                    // Waiting for SMS timed out (5 minutes)
                    // Handle the error ...
                    break;
            }
        }
    }
}

最后一步。将此接收器注册到您的清单

代码语言:javascript
复制
<receiver android:name=".service.SmsReceiver" android:exported="true">
    <intent-filter>
        <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
    </intent-filter>
</receiver>

你的短信必须如下所示。

代码语言:javascript
复制
<#> Your OTP code is: 6789
QWsa8754qw2 

这里的QWsa8754qw2是你自己的应用程序的11个字符的哈希码。遵循此link

  • 不得超过140字节
  • 以前缀<#>
  • 开头,以标识应用程序

的11个字符的哈希字符串结尾

要导入com.google.android.gms.auth.api.phone.SmsRetriever,请不要忘记在您的应用程序build.gradle中添加以下行:

代码语言:javascript
复制
implementation "com.google.android.gms:play-services-auth-api-phone:16.0.0"
票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30862162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档