Nar*_*ani 2 xaml xamarin.android xamarin.forms
我用Xamarin Forms编写了一个项目。每个用户都注册后,我会向他/她发送一个激活码进行确认,并且用户必须插入激活码才能进入应用程序。但是我正在寻找插件或用户不需要插入激活码的方式。
我希望无需手动输入即可自动读取激活码。
首先在AndroidManifest中添加所需的权限:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
Run Code Online (Sandbox Code Playgroud)
这是Android项目中的SmsReceiver类:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:为了过滤掉即将到来的SMS并仅检测我们自己的SMS,我们可以应用以下两个过滤器:
1-忽略所有SMS,使其发件人号码不是我们的SMS发件人号码。
2-有时我们的SMS发送者可能会向客户发送不同的SMS,例如,一个SMS发送一个激活码,另一个SMS通知并确认用户已在系统中成功注册。也就是说,我们必须区分它们。为此,我们可以搜索邮件正文以找到一些预定义的关键字。当然,我们的SMS服务器必须遵循定义的正文格式。“激活”,“代码”,“激活代码”可以是英语中的一些示例关键字。当然,应该相应地用每种语言定义关键字。
这是PCL项目中的RegisterSecondPageModel:
public class RegisterSecondPageModel
{
public RegisterSecondPageModel()
{
SubscribeToOtpReceiving();
}
private void SubscribeToOtpReceiving()
{
MessagingCenter.Subscribe<RegisterSecondPageModel, string>(this, "OtpReceived", (sender, code) =>
{
ActivationCode = code;
});
}
}
Run Code Online (Sandbox Code Playgroud)
另一个注意事项是,正如Jason已经说过的,iOS不允许应用读取SMS。
| 归档时间: |
|
| 查看次数: |
2613 次 |
| 最近记录: |