53

サーバーがOTPを送信し、ユーザーがこのOTPをアプリに入力してアプリにサインアップする必要があるAndroidアプリに取り組んでいます。私が欲しいのは、私のアプリがサーバーから送信された OTP を自動的に読み取れるようにすることです。どうすればこれを達成できますか?この点に関するヘルプやガイダンスをいただければ幸いです。

4

9 に答える 9

26

次のような単純なライブラリを使用してみることができます

Gradle 経由でインストールし、アクセス許可を追加した後、onCreate アクティビティのようなメソッドで SmsVerifyCatcher を開始します。

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

また、アクティビティのライフサイクル メソッドをオーバーライドします。

  @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;
}
于 2016-09-15T11:25:13.437 に答える
19

Google は READ_SMS 権限の使用を制限しているため、ここでは READ_SMS 権限のないソリューションを使用します。

SMS レトリーバー API

基本的な機能は、Android のクリティカル パーミッション READ_SMS の使用を避け、このメソッドを使用してタスクを実行することです。ブローは必要な手順です。

OTP送信をユーザーの番号に投稿し、SMSレトリーバーAPIがメッセージを取得できるかどうかを確認します

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

放送受信機コード

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

最終段階。この受信機をマニフェストに登録します

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

SMS は次のようになっている必要があります。

<#> Your OTP code is: 6789
QWsa8754qw2 

ここで QWsa8754qw2 は、独自のアプリケーションの 11 文字のハッシュ コードです。このリンクに従ってください

  • 140バイト以内
  • 接頭辞 <#> で始める
  • アプリを識別する 11 文字のハッシュ文字列で終わります

をインポートcom.google.android.gms.auth.api.phone.SmsRetrieverするには、アプリの build.gradle に次の行を追加することを忘れないでください。

implementation "com.google.android.gms:play-services-auth-api-phone:16.0.0"
于 2019-02-02T09:49:24.003 に答える
5

そのようなものを実装しました。しかし、メッセージが届いたときに私が行ったことは次のとおりです。6 桁のコードのみを取得し、それをインテントにバンドルして、それを必要とするアクティビティまたはフラグメントに送信し、コードを検証します。この例は、すでに SMS を取得する方法を示しています。LocalBrodcastManagerを使用して送信する方法については、以下のコードを参照してください。メッセージにグリーティングなどのテキストが含まれている場合は、より適切に標準化してください。たとえば、「Your validation code is: 84HG73」のように、2 つの int、2 つの [capital] 文字、2 つの int を意味する正規表現パターンを作成できます。([0-9]){2}([A-Z]){2}([0-9]){2}幸運を!

メッセージから不要な情報をすべて破棄した後

 Intent intent = new Intent("AddedItem");
 intent.putExtra("items", code);
 LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent); 

そして、それを受け取るフラグメント/アクティビティ

@Override
public void onResume() {
    LocalBroadcastManager.getInstance(getActivity()).registerReceiver(receiver, new IntentFilter("AddedItem"));
    super.onResume();
}

@Override
public void onPause() {
    super.onDestroy();
    LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(receiver);
}

そして、収集したペイロードを処理するためのコード

 private BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction()) {
            final String message = intent.getStringExtra("message");
            //Do whatever you want with the code here
        }
    }
};

少しは役に立ちますか。コールバックを使用して改善しました

于 2015-08-10T12:07:06.147 に答える
0

遅いことはわかっていますが、他の人にとってこれを簡単にするために、以前に書いた解決策を次に示します。このライブラリリンクを使用します。何もいじる必要はありません。依存関係を追加した後、このメソッドを使用するだけです。

OtpFetcher.getInstance().verifyOtpByMatchingString(this, "OTP", 21000, object : OtpListener {
            override fun onReceived(messageItem: MessageItem) {
                Toast.makeText(this@MainActivity, "" + messageItem, Toast.LENGTH_SHORT).show()
            }

            override fun onTimeOut() {
                Toast.makeText(this@MainActivity, "TimeOut", Toast.LENGTH_SHORT).show()

            }
        })

例として、メッセージのコンテキスト、検索文字列を渡す必要があります

メッセージで OTP を期待していますが、「OTP」を渡し、OTP をリッスンする時間のタイムアウトを指定すると、それだけです。OnRecieved CallBack でメッセージを単純な形式で取得します。

于 2021-05-17T20:10:05.193 に答える