티스토리 뷰
Android에서는 몇 줄의 코드만으로 SMS를 보내고받을 수 있습니다.
BroadcastReceiver를 구현하고 AndroidManifest.xml에서 권한을 얻어야합니다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="SendAndReceiveSMS.Android" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
<uses-sdk />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.BROADCAST_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<application android:label="SendAndReceiveSMS.Android"></application>
</manifest>
using System;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Telephony;
using SendAndReceiveSMS.Events;
namespace SendAndReceiveSMS.Droid.Receivers
{
[BroadcastReceiver]
[IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED" }, Priority = (int)IntentFilterPriority.HighPriority)]
public class SmsListener : BroadcastReceiver
{
protected string message, address = string.Empty;
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action.Equals("android.provider.Telephony.SMS_RECEIVED"))
{
Bundle bundle = intent.Extras;
if (bundle != null)
{
try
{
var smsArray = (Java.Lang.Object[])bundle.Get("pdus");
foreach (var item in smsArray)
{
#pragma warning disable CS0618
var sms = SmsMessage.CreateFromPdu((byte[])item);
#pragma warning restore CS0618
address = sms.OriginatingAddress;
message = sms.MessageBody;
GlobalEvents.OnSMSReceived_Event(this, new SMSEventArgs() { PhoneNumber = address, Message = message });
}
}
catch (Exception)
{
//Something went wrong.
}
}
}
}
}
}
Android SmsListener BroadcastReceiver에서 호출
lobalEvents.OnSMSReceived_Event(this, new SMSEventArgs() { PhoneNumber = address, Message = message }); -> this line will call, when an SMS received.
using System;
namespace SendAndReceiveSMS.Events
{
public class GlobalEvents
{
public static event EventHandler<SMSEventArgs> OnSMSReceived;
public static void OnSMSReceived_Event(object sender, SMSEventArgs sms)
{
OnSMSReceived?.Invoke(sender, sms);
}
}
public class SMSEventArgs : EventArgs
{
public string PhoneNumber { get; set; }
public string Message { get; set; }
}
}
1. We have to create in the Standard Library an Interface (I created an Interfaces folder)
(https://github.com/officialdoniald/Xamarin.Forms.SendAndReceiveSMS/blob/master/SendAndReceiveSMS/SendAndReceiveSMS/Interfaces/ISendSms.cs)
namespace SendAndReceiveSMS.Interfaces
{
public interface ISendSms
{
void Send(string address, string message);
}
}
2. We have to implement in Android
(https://github.com/officialdoniald/Xamarin.Forms.SendAndReceiveSMS/blob/master/SendAndReceiveSMS/SendAndReceiveSMS.Android/Receivers/SendSms.cs)
using Android.App;
using Android.Content;
using Android.Telephony;
using SendAndReceiveSMS.Droid.Receivers;
using SendAndReceiveSMS.Interfaces;
using Xamarin.Forms;
[assembly: Dependency(typeof(SendSms))]
namespace SendAndReceiveSMS.Droid.Receivers
{
public class SendSms : ISendSms
{
public void Send(string address, string message)
{
var pendingIntent = PendingIntent.GetActivity(Android.App.Application.Context, 0, new Intent(Android.App.Application.Context, typeof(MainActivity)).AddFlags(ActivityFlags.ClearTop | ActivityFlags.NewTask), PendingIntentFlags.NoCreate);
SmsManager smsM = SmsManager.Default;
smsM.SendTextMessage(address, null, message, pendingIntent, null);
}
}
}
And that’s it. We can send and receive SMSs in Android.
iOS
Because of the privcy we can’t read SMSs(Messages) in iOS, just extract from OTP(One Time Password) Messages the OTP.
What is OTP Message?
This Messages contain “code” or “password” and a number.
“Your password is: 012784.” or “You verification code is: 873274.”.
Theese numbers are detected by the operation system and show they above the keyboard.
Receive SMS (OTP Message)
First we have to do a custom Entry in the .NET Standard Library
using Xamarin.Forms;
namespace SendAndReceiveSMS.CustomRenderer
{
public class OTPAutoFillControl : Entry
{
}
}
And implement it in the iOS Project
using SendAndReceiveSMS.CustomRenderer;
using SendAndReceiveSMS.iOS.CustomRenderer;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(OTPAutoFillControl), typeof(OTPAutoFillControlRenderer))]
namespace SendAndReceiveSMS.iOS.CustomRenderer
{
public class OTPAutoFillControlRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
Control.TextContentType = UITextContentType.OneTimeCode;
}
}
}
}
Send SMS
There is two methods: throught Xamarin.Forms.Essentials NuGet Package and throught Dependency Service, some platform specific implementation. We will see just throught Dependency Service.
0. You can skip the 1. step if you are already done with the Android part.
1. We have to create in the Standard Library an Interface (I created an Interfaces folder)
(https://github.com/officialdoniald/Xamarin.Forms.SendAndReceiveSMS/blob/master/SendAndReceiveSMS/SendAndReceiveSMS/Interfaces/ISendSms.cs)
namespace SendAndReceiveSMS.Interfaces
{
public interface ISendSms
{
void Send(string address, string message);
}
}
2. We have to implement in iOS
using System;
using MessageUI;
using SendAndReceiveSMS.Interfaces;
using UIKit;
namespace SendAndReceiveSMS.iOS.Receivers
{
public class SendSms : ISendSms
{
public void Send(string body, string phoneNumber)
{
if (!MFMailComposeViewController.CanSendMail)
return;
MFMessageComposeViewController smsController = new MFMessageComposeViewController();
smsController.Recipients = new[] { phoneNumber };
smsController.Body = body;
EventHandler<MFMessageComposeResultEventArgs> handler = null;
handler = (sender, args) =>
{
smsController.Finished -= handler;
var uiViewController = sender as UIViewController;
if (uiViewController == null)
{
throw new ArgumentException("sender");
}
uiViewController.DismissViewControllerAsync(true);
};
smsController.Finished += handler;
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewControllerAsync(smsController, true);
}
}
}
Call the Send and Receive SMS from the StandardLibrary
(https://github.com/officialdoniald/Xamarin.Forms.SendAndReceiveSMS/blob/master/SendAndReceiveSMS/SendAndReceiveSMS/MainPage.xaml.cs)
using SendAndReceiveSMS.Events;
using SendAndReceiveSMS.Interfaces;
using System;
using Xamarin.Forms;
namespace SendAndReceiveSMS
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
GlobalEvents.OnSMSReceived += GlobalEvents_OnSMSReceived;
}
private void GlobalEvents_OnSMSReceived(object sender, SMSEventArgs e)
{
EntryMessage.Text = e.Message;
}
/// <summary>
/// SMS Send.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button_Clicked(object sender, EventArgs e)
{
DependencyService.Get<ISendSms>().Send(EntryNumber.Text, EntryMessage.Text);
}
}
}
And some UI in the .NET Standard Library
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SendAndReceiveSMS.CustomRenderer"
x:Class="SendAndReceiveSMS.MainPage">
<StackLayout>
<Entry Keyboard="Numeric" Text="" Placeholder="Phone Number" x:Name="EntryNumber"/>
<Entry Text="" Placeholder="Android Message" x:Name="EntryMessage"/>
<local:OTPAutoFillControl Keyboard="Numeric" Text="" Placeholder="iOS OTP Message" x:Name="OTPEntryMessage"/>
<Button Text="Send" Clicked="Button_Clicked"/>
<!--Placeholder="XXXXXX"-->
</StackLayout>
</ContentPage>
'[모바일 앱] > Xamarin(자마린)' 카테고리의 다른 글
[Xamarin] Xamarin.Essentials1.6버전 File Picker, Media Picker 사용 시 HotReload가 동작하지 않을경우 (0) | 2020.11.30 |
---|
- Total
- Today
- Yesterday