当应用程序处于后台或被杀死时,BroadcastReceiver不起作用

时间:2018-01-19 17:50:36

标签: xamarin xamarin.android broadcastreceiver

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

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

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

  

当应用程序不在后台或被杀时,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中节省电池等等......"缺点&#34 ;用户必须知道它正在运行,因此需要放在通知栏中,我个人并不认为这是一个问题,并希望它是所有服务的硬性要求。