本文介绍了在Xamarin表单中自动阅读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;
        }

    }
}

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

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

1-忽略所有SMS,其发件人号码不是我们的SMS发件人号码.

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

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

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不允许应用读取SMS.

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

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

11-02 06:08