广播接收器在 Android 10 中不起作用

Broadcast Receiver doesn't work in Android 10

我的 Xamarin 项目中的 BroadcastReceiver 实现有一些问题。我想在用户重启设备时重启我的服务。特别是它在 OxygenOS (OnePlus 6T) 中运行良好,但在 Android 10 "Vanilla" (Samsung Galaxy A7 2018) 中却不行。我也尝试过使用 Visula Studio Emulator,使用 Android 9.0 和 Android 10.0,效果很好。我不明白为什么它在我的设备上不起作用。这是我对 BroadcastReceiver 的实现:

[BroadcastReceiver(Enabled = true)]
    [IntentFilter(new[] {Intent.ActionBootCompleted })]
    public class BootReceiver : BroadcastReceiver
    {

        public override void OnReceive(Context context, Intent intent)
        {
            try
            {
                Toast.MakeText(context, "It's work", ToastLength.Long).Show();

                Intent downloadIntent = new Intent(context, typeof(DemoIntentService));
                downloadIntent.AddFlags(ActivityFlags.NewTask);
                context.StartService(downloadIntent);

                Intent intent2 = new Intent(context, typeof(TestIntent));
                intent2.AddFlags(ActivityFlags.NewTask);
                context.StartService(intent2);
            }
            catch
            {
                Toast.MakeText(context, "Not works", ToastLength.Long).Show();
            }

        }

    }

然后我给你看清单文件:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application ...
    <receiver android:enabled="true" android:name="crc64a8a173fc3f8c46da.BootReceiver">
      <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
      </intent-filter>
    </receiver>
</application>

2022 答案 - 我使用广播接收器重新安排我的本地通知

在将我的头撞在墙上将近 3 小时后,我终于让它工作了。由于 Google 进行了一些 API 更改,所有答案都已过时。无论如何,这对我有用。

我是如何测试的

  1. 在 phone 上启动应用程序(为了消除任何混淆,我什至使用我的 IDE 调试器启动了它。我可以确认 'debug' 模式对启动接收器没有影响) .仅供参考,我用的是小米Pocophone F1。我的应用的目标是 API 级别 30。
  2. 让 App 日程通知在 3 分钟后出现
  3. 重启 phone
  4. 等待 3 分钟(请注意,我没有启动我的应用程序。我也没有为我启用应用程序自动启动权限。有一些旧的答案表明自动启动必须打开。这是错误的,即不需要)
  5. 3 分钟后通知出现!这意味着在重新启动期间启动了 Boot BroadcastReceiver。

密码

[assembly: UsesPermission (Manifest.Permission.ReceiveBootCompleted)]
namespace MyApp.Droid
{
    [BroadcastReceiver(Name = "com.myapp.whatever.BootReceiver", Enabled = true)]
    [IntentFilter(new[] { Intent.ActionBootCompleted })]    
    public class BootReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            RescheduleNotifications();
        }

        public void RescheduleNotifications()
        {
            try
            {
                AppCenter.Start("android=cfc33334-8f5e-4ab3-1232-e8712345c860;"
                    //"ios={Your iOS App secret here}",
                    , typeof(Crashes));
                
                //Make sure all services are instantiated
                AppCore.DeviceService = new DeviceService();
                AppCore.FbService = new FBService();
                AppCore.AppService = new AppService();
                AppCore.DeviceService.ScheduleNotifications(notif.Notifications, false);
            }
            catch (Exception e)
            {
                Crashes.TrackError(e);
            }
        
        }
    }
}

关于我的代码的注释

  • 我正在使用 MS App Center 来跟踪崩溃。您可以省略这些部分。
  • 请记住,OnReceive 是单独触发的(没有触发 Main Activity)。因此,请确保您的代码可以 运行 并且不会抛出任何异常。
  • 在“com.myapp.whatever.BootReceiver”中将“com.myapp.whatever”替换为您的应用程序包名称

android 清单

<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
<application ....>
<receiver android:enabled="true" android:name="com.myapp.whatever.BootReceiver" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            </intent-filter>
        </receiver>
    </application>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

其他注意事项

  • 不需要'Initialize' MainActivity中的BootReceiver。只要设置 BroadcasrReceiver Attribute 和 Android Manifest 就可以了。
  • 请确保广播接收器没有遇到任何异常。这是我没有看到的部分。跟踪崩溃以查看它是否抛出任何异常。为此,我使用 AppCenter.ms。你可以在上面看到我的代码。