【问题标题】:BroadcastReceiver does not work when application is in background or killed当应用程序在后台或被杀死时,BroadcastReceiver 不起作用
【发布时间】:2018-01-19 17:50:36
【问题描述】:

我创建了BroadcastReceiver,用于检测设备何时收到来电。 我的代码是

[BroadcastReceiver()]
[IntentFilter(new[] { "android.intent.action.PHONE_STATE" })]
public class MyBroadcastReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
    //My implementation
    }
}

问题是当应用程序没有运行或被强制终止时,BroadcastReceiver 类不会被调用。 有人可以帮忙吗?

【问题讨论】:

    标签: xamarin xamarin.android broadcastreceiver


    【解决方案1】:

    当应用程序不在后台或被终止时,BroadcastReceiver 不起作用

    您可以参考:Android Broadcast Receiver not working when the app is killed,正如 CommonsWare 所说:

    一旦onReceive() 返回,如果您在前台没有活动并且没有正在运行的服务,您的进程重要性将下降到the documentation 所指的“缓存进程”。您的进程有资格随时终止。一旦您的进程终止,您的BroadcastReceiver 就会消失。因此,您编写的代码将不可靠,因为您的进程可能会在 30 秒的窗口内终止。

    解决方案:

    所以你可以使用Service 来实现你的功能,这是我的简单演示:

    [Service]
    [IntentFilter(new String[] { "com.xamarin.DemoService" })]
    public class DemoService : Service
    {
        private static DemoReceiver m_ScreenOffReceiver;
    
        public override IBinder OnBind(Intent intent)
        {
            return null;
        }
    
        public override void OnCreate()
        {
            registerScreenOffReceiver();
            base.OnCreate();
        }
    
        public override void OnDestroy()
        {
            UnregisterReceiver(m_ScreenOffReceiver);
            m_ScreenOffReceiver = null;
            base.OnDestroy();
        }
    
        //From this thread: https://stackoverflow.com/questions/20592366/the-process-of-the-service-is-killed-after-the-application-is-removed-from-the-a
        public override void OnTaskRemoved(Intent rootIntent)
        {
            Intent restartServiceIntent = new Intent(Application.Context, typeof(DemoService));
            restartServiceIntent.SetPackage(PackageName);
    
            PendingIntent restartServicePendingIntent = PendingIntent.GetService(Application.Context, 1, restartServiceIntent, PendingIntentFlags.OneShot);
            AlarmManager alarmService = (AlarmManager)Application.Context.GetSystemService(Context.AlarmService);
            alarmService.Set(AlarmType.ElapsedRealtime, SystemClock.ElapsedRealtime() + 1000, restartServicePendingIntent);
            base.OnTaskRemoved(rootIntent);
        }
    
        private void registerScreenOffReceiver()
        {
            m_ScreenOffReceiver = new DemoReceiver();
            IntentFilter filter = new IntentFilter("com.xamarin.example.TEST");
            RegisterReceiver(m_ScreenOffReceiver, filter);
        }
    }
    

    更新:

    如果您需要服务以更高的优先级运行以避免它被杀死,您可以尝试使用Foreground Service。作为 SushiHangover said:

    作为前台服务,它具有更高的优先级,因此操作系统会认为它最后被杀死,它避免了您的服务自动打瞌睡以节省以后的 API 的电池电量等......“缺点”是用户必须请注意它正在运行,因此需要将其放置在通知栏中,我个人认为这不是问题,并希望这是所有服务的硬性要求。

    【讨论】:

      【解决方案2】:

      应用被杀死时BroadcastReceiver将无法工作,您必须为此使用服务,即使应用未运行,您也可以在服务中使用BroadcastReceiver来运行它。

      【讨论】:

      • 感谢您的回复,如果您有可以分享任何示例吗?我只是移动开发的初学者。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-10
      • 2021-01-01
      相关资源
      最近更新 更多