You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Android短信接收事件无法传递至Xamarin.Forms的问题求助

解决Xamarin.Android短信接收器事件在Forms中无法触发的问题

我之前也踩过这个坑!你遇到的Received事件始终为null的核心原因是:Android系统在收到短信时会自动实例化一个新的IncomingSms对象来处理广播,而你通过DependencyService.Get<IReceived>()获取的是另一个完全独立的实例。这两个实例的事件是各自独立的,系统触发的那个实例根本没有订阅者,自然Received就是null了。

下面给你两种靠谱的解决方法,推荐第一种,更符合Xamarin.Forms的跨平台设计:

方法一:使用Xamarin.Forms自带的MessagingCenter(推荐)

MessagingCenter是Xamarin官方提供的跨平台消息传递机制,不需要依赖实例,直接在Android端发送消息,Forms端订阅即可,完美避开实例不匹配的问题。

步骤1:修改Android端的短信接收器

把原来触发Received事件的代码,换成发送MessagingCenter消息:

private void OnMessagesReiceved(SmsMessage[] messages) {
    var XMessages = new List<XxmsApp.Model.Message>();
    for (var i = 0; i < messages.Length; i++) {
        XMessages.Add(new XxmsApp.Model.Message { 
            Address = messages[i].OriginatingAddress, 
            Value = messages[i].MessageBody 
        });
    }
    // 发送短信接收消息,"SmsReceived"是自定义的消息标识,要和订阅端一致
    MessagingCenter.Send<object, List<XxmsApp.Model.Message>>(this, "SmsReceived", XMessages);
}

步骤2:在Forms端订阅消息

修改你的App类,去掉原来的DependencyService事件订阅,换成MessagingCenter订阅:

public App() {
    DBUpdates();
    MainPage = new MasterDetailPage() {
        Master = new MenuPage { Title = "Title" },
        Detail = new NavigationPage(new XxmsApp.MainPage()) { BarBackgroundColor = Color.Black }
    };

    // 订阅短信接收消息
    MessagingCenter.Subscribe<object, List<XxmsApp.Model.Message>>(
        this, 
        "SmsReceived", 
        (sender, messages) => {
            // 调用原来的处理逻辑
            XMessages_Received(messages);
        });
}

private void XMessages_Received(IEnumerable<Model.Message> message) {
    // 你的短信处理代码
}

方法二:使用静态事件(备选)

如果不想用MessagingCenter,可以把事件改成静态的,这样所有实例共享同一个事件订阅:

步骤1:修改Android端的IncomingSms类

把实例事件改成静态事件:

public class IncomingSms : BroadcastReceiver, IReceived {
    // 把事件改成静态的
    public static 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 XMessages = new List<XxmsApp.Model.Message>();
        for (var i = 0; i < messages.Length; i++) {
            XMessages.Add(new XxmsApp.Model.Message { 
                Address = messages[i].OriginatingAddress, 
                Value = messages[i].MessageBody 
            });
        }
        // 触发静态事件
        Received?.Invoke(XMessages);
    }
}

步骤2:在Forms端订阅静态事件

直接订阅静态事件,不需要通过DependencyService:

public App() {
    DBUpdates();
    MainPage = new MasterDetailPage() {
        Master = new MenuPage { Title = "Title" },
        Detail = new NavigationPage(new XxmsApp.MainPage()) { BarBackgroundColor = Color.Black }
    };

    // 订阅静态事件
    XxmsApp.Api.IncomingSms.Received += XMessages_Received;
}

⚠️ 注意:静态事件容易导致内存泄漏,记得在App退出时取消订阅:

protected override void OnSleep() {
    XxmsApp.Api.IncomingSms.Received -= XMessages_Received;
}

protected override void OnResume() {
    XxmsApp.Api.IncomingSms.Received += XMessages_Received;
}

额外需要检查的配置

除了上面的代码修改,还要确保以下配置正确,不然接收器可能根本不触发:

  1. 添加权限:在Android项目的AndroidManifest.xml里添加短信相关权限:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
  1. 动态申请权限:Android 6.0(API 23)及以上,RECEIVE_SMS是危险权限,需要在运行时申请。可以在Forms启动时或者Android项目的MainActivity里申请:
// 在MainActivity的OnCreate方法中
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReceiveSms) != Permission.Granted) {
    ActivityCompat.RequestPermissions(this, new string[] { Manifest.Permission.ReceiveSms }, 100);
}
  1. BroadcastReceiver属性配置:确保你的BroadcastReceiver属性里的Exported设置为true(Android 12及以上要求接收系统广播的接收器必须显式设置Exported):
[BroadcastReceiver(Enabled = true, Label = "SMS Receiver", Exported = true)]
[IntentFilter(new string[] { Telephony.Sms.Intents.SmsReceivedAction })]
public class IncomingSms : BroadcastReceiver, IReceived {
    // ...
}

按照上面的步骤修改后,应该就能正常在Forms中接收到短信事件了!

内容的提问来源于stack exchange,提问作者Александр

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 07:08:14