在 Xamarin.Android 中以短信形式接收验证令牌

Receive verification token as sms in Xamarin.Android

我需要为我的应用程序创建注册。我已经创建了短信发送服务器,所以我可以:

  1. 单击按钮 "Send SMS"
  2. 之后,我收到了带有令牌的短信。
  3. 我可以将此标记输入到 EditText 元素中。
  4. 单击按钮 "Verify"。
  5. 并且令牌将被验证。

但现在我需要这个令牌自动从 SMS 放入应用程序的文本框中。

  1. 单击按钮 "Send SMS"
  2. 之后,我收到了带有令牌的短信。
  3. 令牌自动放入 EditText
  4. 令牌也会自动验证。

我尝试使用 BroadcastReceiver,它适用于 SMS。我可以显示如下文字:

using Android.App;
using Android.Content;
using Android.Telephony;
using Android.Widget;

namespace ReceiveMsg
{
    [BroadcastReceiver]
    [IntentFilter(
    new[] { "android.provider.Telephony.SMS_RECEIVED" }, Priority =(int)IntentFilterPriority.HighPriority)]
public class SmsReceiver : BroadcastReceiver
{

    public static readonly string INTENT_ACTION = "android.provider.Telephony.SMS_RECEIVED";
    protected string message, address = "";

    public override void OnReceive(Context context, Intent intent)
    {
        if(intent.HasExtra("pdus"))
        {
            var smsArray = (Java.Lang.Object[])intent.Extras.Get("pdus");
            foreach(var item in smsArray)
            {
                var sms = SmsMessage.CreateFromPdu((byte[])item);
                address = sms.OriginatingAddress;
                message = sms.MessageBody;
                Toast.MakeText(context, "Number: " + address + "Message: " + message, ToastLength.Short).Show();

            }
        }
    }
}

}

但是如何将短信中的令牌自动放入令牌位置?

我需要首​​先向用户显示权限管理器 window 进行确认,对吗?

所以我在我的 AndroidManifest 中添加了这个:

<uses-permission android:name="android.permission.RECEIVE_SMS"/>

用户允许使用此短信。
从 SMS 中解析出来的令牌将存储在变量中,并将显示在文本框中。

viewmodel.cs中有一个token变量。
所以我在这里添加public interface SmsListener

    private string _token;
    private bool _isSuccessed, _isInvalid;
    private readonly IMvxNavigationService _navigationService;

    public bool IsSucceeded
    {
        get
        {
            return _isSuccessed;
        }
        set
        {
            _isSuccessed = value;
            RaisePropertyChanged(() => IsSucceeded);
        }
    }
    public bool IsInvalid
    {
        get
        {
            return _isInvalid;
        }
        set
        {
            _isInvalid = value;
            RaisePropertyChanged(() => IsInvalid);
        }
    }

    public string Token
    {
        get
        {
            return _token;
        }
        set
        {
            _token = value;
            RaisePropertyChanged(() => Token);
        }
    }

    public VerificationViewModel(IMvxNavigationService navigationService)
    {
        _navigationService = navigationService;

        VerifyCommand = new MvxAsyncCommand(async () => {
            IsSucceeded = await RegistrationService.VerifyToken(Token);
            IsInvalid = !IsSucceeded;
        });

    }

    public IMvxAsyncCommand VerifyCommand { get; private set; }

    public interface SmsListener
        {
        void MessageReceived(string messageText);
        }

但是我仍然不明白如何在 SmsReceiver 中使用监听器

如何总结呢?为了,用户将能够允许使用此 SMS 并信任自动化过程?

I need at first place to show the user Permission manager window for the confirmation, right?

是的,如果你的目标版本>6.0,你需要Request App Permissions

how can I put the token from SMS into the token place automatically?

可以使用接口[=52​​=]来实现。请参考this article.


1) 你需要定义一个接口,比如SmsListener:

public interface SmsListener {
        public void messageReceived(string messageText);
}

2) 在您的 SmsReceiver 中,您需要在获得 MessageBody;

时调用它

3) 在包含 EditText 的 Activity 中实现接口,并在接口的 messageReceived 方法中实现更新 EditText 的文本。

注:

不要忘记使用 bindListener 方法或其他方法来实例化您的界面。

更新

SmsReceiver:

namespace ReceiveMsg
{
    [BroadcastReceiver]
    [IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED" }, Priority =(int) IntentFilterPriority.HighPriority)] 
    public class SmsReceiver : BroadcastReceiver
    {

        public static readonly string INTENT_ACTION = "android.provider.Telephony.SMS_RECEIVED";
        protected string message, address = "";
        private OnReceiveSMSListener mOnReceiveSMSListener;//add interface
        public override void OnReceive(Context context, Intent intent)
        {
            if (intent.HasExtra("pdus"))
            {
                var smsArray = (Java.Lang.Object[])intent.Extras.Get("pdus");
                foreach (var item in smsArray)
                {
                    var sms = SmsMessage.CreateFromPdu((byte[])item);
                    address = sms.OriginatingAddress;
                    message = sms.MessageBody;
                    Toast.MakeText(context, "Number: " + address + "Message: " + message, ToastLength.Short).Show();
                    // call the interface if you get the message
                    mOnReceiveSMSListener.onReceived(message);
                }
            }
        }

        // interface
        public interface OnReceiveSMSListener
        {
            void onReceived(String message);
        }
        //used in activity
        public void setOnReceiveSMSListener(OnReceiveSMSListener onReceiveSMSListener)
        {
            mOnReceiveSMSListener = onReceiveSMSListener;
        }
    }
}

Activity:

   public class MainActivity : Activity,SmsReceiver.OnReceiveSMSListener
    {
        private SmsReceiver mSMSBroadcastReceiver = new SmsReceiver();
        private EditText mEt_code;
        public void onReceived(string message)
        {
            mEt_code.Text=message + "";
        }

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);
            mEt_code = (EditText)FindViewById(Resource.Id.et_code);
            mSMSBroadcastReceiver.setOnReceiveSMSListener(this);
        }
    }

Manifest:

  <uses-permission android:name="android.permission.RECEIVE_SMS"/>
  <uses-permission android:name="android.permission.READ_SMS"/>