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

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绑定层,完全可以实现该业务场景。

二、当前代码的核心问题

  1. 广播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,同样不匹配,结果无法回传。
  2. 唤醒应用的方式错误:仅通过广播唤醒未运行的应用,即使添加IncludeStoppedPackages标记,也无法保证启动RFID_App的主Activity并触发扫描逻辑,必须直接启动目标应用的入口组件。

三、实现方向提示

  1. 统一广播Action定义
    • 定义两个专属Action:比如com.yourcompany.action.RFID_SCAN_REQUEST(MDE发往RFID的扫描请求)、com.yourcompany.action.RFID_SCAN_RESULT(RFID回传扫描结果),确保发送方与接收方的Action完全一致。
  2. 正确启动未运行的RFID_App
    • MDE_App通过PackageManager获取RFID_App主Activity的Intent,调用StartActivity启动,同时在Intent中携带扫描请求标识(如Extra参数),让RFID_App启动后直接触发扫描流程。
  3. 优化跨应用广播可靠性
    • 优先使用显式广播:指定接收方的包名+Receiver类名,避免Android 8.0+对隐式广播的限制。
    • 若用隐式广播,需在Manifest中为Receiver声明对应的IntentFilter,同时广播需添加IncludeStoppedPackages标记。
  4. RFID_App启动后的逻辑处理
    • RFID_App的入口Activity启动时,检查Intent的Extra参数,判断是否来自MDE_App的扫描请求,若有则直接执行扫描,完成后立即发送结果广播给MDE_App。
  5. 兼容性与权限处理
    • Android 12+需添加QUERY_ALL_PACKAGES权限,或在Manifest中用<queries>标签指定允许交互的应用包名,确保MDE_App能找到RFID_App的组件。
    • 保持BroadcastReceiver的Exported = true配置(当前代码已满足)。

内容的提问来源于stack exchange,提问作者DaveR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 17:12:34