Broadcast-receiver which always receives broadcast (even in background) for API Level +26

后端 未结 2 818
情书的邮戳
情书的邮戳 2020-12-18 10:11

I\'m posing this as Q&A style because I found this idea working. And it\'s a fix to the hard problem to crack for beginners with Android.

2条回答
  •  隐瞒了意图╮
    2020-12-18 10:23

    This also applies to Xamarin Android. The Play Store demanded to upgrade my apps's SDK to 8.0 Oreo, and a bunch of stuff stopped working on it.

    Microsoft's documentation on Broadcast Receivers is quite confusing:

    Apps that target Android 8.0 (API level 26) or higher may not statically register for an implicit broadcast. Apps may still statically register for an explicit broadcast. There is a small list of implicit broadcasts that are exempt from this restriction.

    Even Google's official docs are quite inscrutable.

    On Xamarin Android it used to be enough to follow this pattern:

    [BroadcastReceiver]
    [IntentFilter(new string[] {MyReceiver.MyAction})]
    public class MyReceiver : BroadcastReceiver
    {
        public const String MyAction = "com.mytest.services.MyReceiver.MyAction";
    
        public override void OnReceive (Context context, Intent intent)
        {
            // ...
        }
    }
    

    The IntentFilter annotation instructs the compiler to add the receiver and intent filters registrations to the Manifest file during the build process. But from target SDKs v8.0 (Oreo/API 26) and above Android ignores these configurations on Manifest (except some system implicit actions). So this means that the IntentFilter annotations only works for those exceptions, and to make your broadcast receivers receive broadcasts it is required to register them on execution time:

    #if DEBUG
    [Application(Debuggable=true)]
    #else
    [Application(Debuggable=false)]
    #endif
    public class MyApplication: Application
    {
        public override void OnCreate ()
        {
            base.OnCreate ();
    
            Context.RegisterReceiver(new MyReceiver(), new IntentFilter(MyReceiver.MyAciton));
        }
    }
    

    It is also possible to register a receiver only for the lifecycle of an Activity, as explained by @Toaster. You can keep sending broadcasts normally:

    // ...
    
    ApplicationContext.SendBroadcast(new Intent(MyReceiver.MyAction));
    
    // ...
    

提交回复
热议问题