Reputation: 299
I get messages in Xamarin.Android and I need pass it to Xamarin.Forms app. What I came up with at the moment is dependency injection. I has defined the interface:
public interface IReceived
{
event OnReceived Received;
}
And its implementation inside IncomingSms class inherited from BroadcastReceiver for messages listening
[assembly: Dependency(typeof(XxmsApp.Api.IncomingSms))]
namespace XxmsApp.Api
{
// [BroadcastReceiver(Enabled = true, Exported = true)]
[BroadcastReceiver(Enabled = true, Label = "SMS Receiver")]
[IntentFilter(new string [] { Telephony.Sms.Intents.SmsReceivedAction })] // "android.provider.Telephony.SMS_RECEIVED"
public class IncomingSms : BroadcastReceiver, IReceived
{
public event OnReceived Received;
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action != Telephony.Sms.Intents.SmsReceivedAction) return;
SmsMessage[] messages = Telephony.Sms.Intents.GetMessagesFromIntent(intent);
OnMessagesReiceved(messages);
}
private void OnMessagesReiceved(SmsMessage[] messages)
{
var smsMesages = new List<(string Address, string Message)>();
var XMessages = new List<XxmsApp.Model.Message>();
for (var i = 0; i < messages.Length; i++)
{
smsMesages.Add((messages[i].OriginatingAddress, messages[i].MessageBody));
XMessages.Add(new XxmsApp.Model.Message
{
Address = messages[i].OriginatingAddress,
Value = messages[i].MessageBody
});
}
Received?.Invoke(XMessages);
}
}
}
And I have subscribed to the event Received
public App()
{
DBUpdates();
MainPage = (new MasterDetailPage()
{
Master = new MenuPage { Title = "Title" },
Detail = new NavigationPage(new XxmsApp.MainPage()) { BarBackgroundColor = Color.Black }
});
xMessages = DependencyService.Get<XxmsApp.Api.IReceived>();
xMessages.Received += XMessages_Received;//*/
}
private void XMessages_Received(IEnumerable<Model.Message> message)
{
// ...
}
It's work without some errors. But when raised the line Received?.Invoke(XMessages);
Received always is null
. And I can't catch the event (moment of message coming) in my main app Xamarin.Forms
How can do this?
Upvotes: 0
Views: 915
Reputation: 9274
Agree with Jason, you can use the MessagingCenter
to achieve it. Here is code in the SmsBroadcastRceiver
[BroadcastReceiver(Enabled = true, Exported = true)]
[IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED" })]
public class SmsBroadcastRceiver : BroadcastReceiver
{
public SmsBroadcastRceiver()
{
}
public override void OnReceive(Context context, Intent intent)
{
var msgs = Telephony.Sms.Intents.GetMessagesFromIntent(intent);
List<string> msgList = new List<string>();
foreach (var msg in msgs)
{
msgList.Add(msg.DisplayMessageBody);
}
MessagingCenter.Send<List<string>>(msgList, "MyMessage");
}
}
You can receive the message in PCL background code.
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
MessagingCenter.Subscribe<List<string>>(this, "MyMessage", (expense) =>
{
List<string> mylist= expense as List<string>;
string allText= "";
foreach (string item in mylist)
{
allText += item+" ";
}
editorSms.Text = allText;
});
}
private void Button_Clicked(object sender, EventArgs e)
{
Xamarin.Forms.DependencyService.Get<ISmsReader>().GetSmsInbox();
}
}
Here is my running gif.
Here is code demo code(Note:I do not achieve the runtime permission, you should add the permission manually).
https://github.com/851265601/BroadcastReceSMS
Upvotes: 1