Xamarin双应用广播通信异常:休眠应用无法接收广播求助
我的代码实现
RFID_App的MainActivity
using System; using Android.App; using Android.Content.PM; using Android.Runtime; using Android.OS; using RFID_App.Droid; using Android.Content; using AndroidX.LocalBroadcastManager.Content; [assembly: Xamarin.Forms.Dependency(typeof(MainActivity))] namespace RFID_App.Droid { [Activity(Label = "RFID_App", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize )] public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, IBroadcastService { private static ReceiverRFID receiver; private IntentFilter intentFilter = new IntentFilter("eu.logfox.ReceiverMDE"); protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); receiver = new ReceiverRFID(); Xamarin.Essentials.Platform.Init(this, savedInstanceState); global::Xamarin.Forms.Forms.Init(this, savedInstanceState); LoadApplication(new App()); } public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) { Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); base.OnRequestPermissionsResult(requestCode, permissions, grantResults); } protected override void OnResume() { base.OnResume(); RegisterReceiver(receiver, intentFilter); } protected override void OnPause() { UnregisterReceiver(receiver); base.OnPause(); } public void sendDMC() { try { string dmcCode = "]<!n4lkj3n4j3n4lj3n4kj3n4l3k4nk3j4nlkj34nklj3"; Intent intent = new Intent(); intent.SetAction("eu.logfox.ReceiverMDE"); intent.PutExtra("DMC_CODE", dmcCode); Context context = Android.App.Application.Context; context.SendBroadcast(intent); } catch(Exception ex) { System.Console.WriteLine(ex.Message); } } }
ReceiverRFID
namespace RFID_App.Droid { [BroadcastReceiver(Enabled = true, Exported = true)] [IntentFilter(new[] { "eu.logfox.ReceiverMDE" })] public class ReceiverRFID : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { if(intent.HasExtra("SCAN_REQUEST")) { Toast.MakeText(context, intent.GetStringExtra("SCAN_REQUEST"), ToastLength.Long).Show(); } else { Toast.MakeText(context, "Any intent", ToastLength.Long).Show(); } } } }
MDE_App的MainActivity
namespace MDE_App { [Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)] public class MainActivity : AppCompatActivity { private static ReceiverMDE receiver; private IntentFilter intentFilter = new IntentFilter("eu.logfox.ReceiverRFID"); protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Xamarin.Essentials.Platform.Init(this, savedInstanceState); SetContentView(Resource.Layout.activity_main); receiver = new ReceiverMDE(); Button btnSend = FindViewById<Button>(Resource.Id.btnSend); btnSend.Click += (sender, e) => { Intent intent = new Intent(); intent.SetAction("eu.logfox.ReceiverRFID"); intent.PutExtra("SCAN_REQUEST", "SCAN"); intent.AddFlags(ActivityFlags.IncludeStoppedPackages); Context context = Android.App.Application.Context; context.SendBroadcast(intent); //context.SendOrderedBroadcast(intent, ""); }; } public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) { Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); base.OnRequestPermissionsResult(requestCode, permissions, grantResults); } protected override void OnResume() { base.OnResume(); RegisterReceiver(receiver, intentFilter); } protected override void OnPause() { UnregisterReceiver(receiver); base.OnPause(); } } }
MDE_App的Receiver
namespace MDE_App { [BroadcastReceiver(Enabled = true, Exported = true)] [IntentFilter(new[] { "eu.logfox.ReceiverRFID" })] public class ReceiverMDE : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { Toast.MakeText(context, "Received intent!", ToastLength.Short).Show(); } } }
解答:可行性与实现思路
一、需求可行性
完全可行。Android原生支持跨应用组件启动、广播通信,Xamarin作为Android的.NET绑定层,完全可以实现该业务场景。
二、当前代码的核心问题
- 广播Action不匹配:
- MDE_App发送的广播Action是
eu.logfox.ReceiverRFID,但RFID_App的Receiver监听的是eu.logfox.ReceiverMDE,两者不对应,导致请求无法被接收。 - RFID_App回传结果用的Action是
eu.logfox.ReceiverMDE,但MDE_App的Receiver监听的是eu.logfox.ReceiverRFID,同样不匹配,结果无法回传。
- MDE_App发送的广播Action是
- 唤醒应用的方式错误:仅通过广播唤醒未运行的应用,即使添加
IncludeStoppedPackages标记,也无法保证启动RFID_App的主Activity并触发扫描逻辑,必须直接启动目标应用的入口组件。
三、实现方向提示
- 统一广播Action定义
- 定义两个专属Action:比如
com.yourcompany.action.RFID_SCAN_REQUEST(MDE发往RFID的扫描请求)、com.yourcompany.action.RFID_SCAN_RESULT(RFID回传扫描结果),确保发送方与接收方的Action完全一致。
- 定义两个专属Action:比如
- 正确启动未运行的RFID_App
- MDE_App通过
PackageManager获取RFID_App主Activity的Intent,调用StartActivity启动,同时在Intent中携带扫描请求标识(如Extra参数),让RFID_App启动后直接触发扫描流程。
- MDE_App通过
- 优化跨应用广播可靠性
- 优先使用显式广播:指定接收方的包名+Receiver类名,避免Android 8.0+对隐式广播的限制。
- 若用隐式广播,需在Manifest中为Receiver声明对应的IntentFilter,同时广播需添加
IncludeStoppedPackages标记。
- RFID_App启动后的逻辑处理
- RFID_App的入口Activity启动时,检查Intent的Extra参数,判断是否来自MDE_App的扫描请求,若有则直接执行扫描,完成后立即发送结果广播给MDE_App。
- 兼容性与权限处理
- Android 12+需添加
QUERY_ALL_PACKAGES权限,或在Manifest中用<queries>标签指定允许交互的应用包名,确保MDE_App能找到RFID_App的组件。 - 保持BroadcastReceiver的
Exported = true配置(当前代码已满足)。
- Android 12+需添加
内容的提问来源于stack exchange,提问作者DaveR
相关产品推荐
相关产品推荐

