在 Xamarin Forms 中自动读取 SMS 激活码,而不是由用户手动输入 [英] Read the SMS activation code automatically in Xamarin Forms instead of manually typing it by user

查看:30
本文介绍了在 Xamarin Forms 中自动读取 SMS 激活码,而不是由用户手动输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用 Xamarin Forms 编写了一个项目.当每个用户都注册后,我会向他/她发送一个激活码以进行确认,用户必须插入它才能进入应用程序.但是我在找插件或者用户不需要插入激活码的方式.

I wrote a project with Xamarin Forms. When every user has signed up, I send him/her an activation Code to confirm it and the user has to insert it to enter the app. But I am looking for a plugin or a way that the user does not need to insert the activation Code.

我想自动读取激活码,无需手动输入.

I want the activation Code to be read automatically without the need to enter it manually.

推荐答案

首先在AndroidManifest中添加需要的权限:

First add the required permissions in AndroidManifest:

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

Android 项目中的 SmsReceiver 类:

Here is SmsReceiver class in Android project:

using System.Linq;
using System.Text.RegularExpressions;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Telephony;
using Java.Lang;
using Xamarin.Forms;
namespace MyProject.Android
{
    [BroadcastReceiver(Enabled = true, Label = "SMS Receiver")]
    [IntentFilter(new string[] { "android.provider.Telephony.SMS_RECEIVED", Intent.CategoryDefault })]
    public class SmsReceiver : BroadcastReceiver
    {
        private const string IntentAction = "android.provider.Telephony.SMS_RECEIVED";
        private static readonly string Sender = "SMS Sender number here";
        private static readonly string[] OtpMessageBodyKeywordSet = {"Keyword1", "Keyword2"}; //You must define your own Keywords
        public override void OnReceive(Context context, Intent intent)
        {
            try
            {
                if (intent.Action != IntentAction) return;
                var bundle = intent.Extras;
                if (bundle == null) return;
                var pdus = bundle.Get("pdus");
                // var castedPdus = JNIEnv.GetArray(pdus.Handle);
                var castedPdus = JNIEnv.GetArray<Object>(pdus.Handle);
                var msgs = new SmsMessage[castedPdus.Length];
                var sb = new StringBuilder();
                string sender = null;
                for (var i = 0; i < msgs.Length; i++)
                {
                    var bytes = new byte[JNIEnv.GetArrayLength(castedPdus[i].Handle)];
                    JNIEnv.CopyArray(castedPdus[i].Handle, bytes);
                    string format = bundle.GetString("format");
                    msgs[i] = SmsMessage.CreateFromPdu(bytes, format);
                    if (sender == null)
                        sender = msgs[i].OriginatingAddress;
                    sb.Append(string.Format("SMS From: {0}{1}Body: {2}{1}", msgs[i].OriginatingAddress,
                        System.Environment.NewLine, msgs[i].MessageBody));
                    //Toast.MakeText(context, sb.ToString(), ToastLength.Long).Show();
                    //Log.Error("Vahid", sb.ToString());

                    var msgBody = msgs[i].MessageBody;
                    if(!sender.Contains(Sender)) return;
                    bool foundKeyword = OtpMessageBodyKeywordSet.Any(k => msgBody.Contains(k));

                    if (!foundKeyword) return;
                    var code = ExtractNumber(msgBody);
                    MessagingCenter.Send<RegisterSecondPageModel, string>(new RegisterSecondPageModel(), "OtpReceived", code);

                }
            }
            catch (System.Exception ex)
            {
                //Toast.MakeText(context, ex.Message, ToastLength.Long).Show();
            }
        }

        private static string ExtractNumber(string text)
        {
            if (string.IsNullOrEmpty(text)) return "";
            var regPattern = @"d+";
            var number = Regex.Match(text, regPattern).Value;
            return number;
        }

    }
}

注意:为了过滤掉即将到来的短信并仅检测我们自己的短信,我们可以应用这两个过滤器:

Note: In order to filter out the coming SMSes and detect only our own SMS we can apply these two filters:

1- 忽略所有发件人号码不是我们的短信发件人号码的短信.

1- Ignoring all SMSes that their sender numbers are not our SMS sender number.

2- 有时我们的短信发送器可能会向我们的客户发送不同的短信,例如一条短信发送激活码,另一条短信通知并确认用户在系统中成功注册.也就是说,我们必须区分它们.为此,我们可以搜索消息正文以找到一些预定义的关键字.当然,我们的 SMS 服务器必须坚持定义的正文格式.Activation"、Code"、Activation code"可以是英文中的一些示例关键字.当然,关键字应该在每种语言中相应地定义.

2- Sometimes our SMS sender might send different SMSes to our clients, for example one SMS to send an activation code, and another to inform and confirm user's successfully registration in system. That said, we gotta distinguish them. For that we can search message body in order to find some pre-defined keywords. Of course our SMS server has to stick to a defined body format. "Activation", "Code", "Activation code" could be some example keywords in English language. Of course keywords should be defined in each language accordingly.

这是PCL项目中的RegisterSecondPageModel:

Here is RegisterSecondPageModel inside PCL project:

public class RegisterSecondPageModel
{
  public RegisterSecondPageModel()
   {
     SubscribeToOtpReceiving();
   }

  private void SubscribeToOtpReceiving()
  {
     MessagingCenter.Subscribe<RegisterSecondPageModel, string>(this, "OtpReceived", (sender, code) =>
                    {
                        ActivationCode = code;
                    });
  }
}

另一个注意事项是,正如 Jason 已经说过的,iOS 不允许应用读取短信.

Another note is that as Jason already said, iOS doesn't allow apps to read SMSes.

这篇关于在 Xamarin Forms 中自动读取 SMS 激活码,而不是由用户手动输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆