Android 8.0开启服务报错,自定义广播无法接收到

作者:燕歆波
导读:8.0在广播中调用startService报出异常;自定义广播接收不到

项目中为了防止服务在后台被杀死,在service的onDestroy中发送了广播,在广播中重新打开service,结果报出了下面的错误:

Not allowed to start service Intent  xxxx   app is in background uid UidRecord...

Android 8.0 还对特定函数做出了以下变更:


1、如果针对 Android 8.0 的应用尝试在不允许其创建后台服务的情况下使用 startService() 函数,则该函数将引发一个 IllegalStateException。新的 Context.startForegroundService() 函数将启动一个前台服务。
 
2、即使应用在后台运行,系统也允许其调用 Context.startForegroundService()。不过,
应用必须在创建服务后的五秒内调用该服务的 startForeground() 函数。

所以在启动服务的地方需要针对8.0做出判断

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
}else{
}

官方建议使用JobIntentService 实现:

If the service is running in a background thread by extending IntentService, 
you can replace IntentService with JobIntentService which is provided as part of Android Support Library
The best way is to use JobIntentService which uses the new JobScheduler for Oreo or the old services if not available.

还有一个问题就是,在8.0上,自定义广播无法接受到广播的问题:

官方文档做出了解释:
在这里插入图片描述解决方式有两种:
1、使用动态注册广播接收器代替静态注册广播接收器,建议使用JobScheduler

2、保留静态注册广播接收器,但是需要发送显式广播,可以通过更改广播方式设置ComponentName为显式广播(指定包名):

Intent cast= new Intent("目标广播接收器的action");
ComponentName comp = new ComponentName("目标广播接收器所在应用的包名","目标广播接收器类全路径")
cast.setComponent(comp);
sendBroadcast(cast);

感谢:
https://blog.csdn.net/kongbaidepao/article/details/80259150
https://blog.csdn.net/michael_hejing/article/details/83830895

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 8.0 及以上版本,为了增强应用程序的安全性,Android 引入了后台限制,禁止未在前台运行的应用程序启动服务。如果您想在后台启动服务,需要使用 `startForegroundService()` 方法。这个方法会启动一个前台服务,然后你可以在服务启动后在通知栏显示一个通知,以此来告知用户服务正在运行。 以下是一个使用 `startForegroundService()` 的示例代码: ``` if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 创建一个 NotificationChannel NotificationChannel channel = new NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_DEFAULT); // 向系统注册 NotificationChannel NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.createNotificationChannel(channel); } // 创建一个 Intent,启动你的服务 Intent serviceIntent = new Intent(this, YourService.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 在 Android 8.0 及以上版本上,需要调用 startForegroundService() 方法启动服务。 startForegroundService(serviceIntent); } else { // 在 Android 8.0 以下版本上,可以直接调用 startService() 方法启动服务。 startService(serviceIntent); } ``` 注意:如果你使用的是 `startForeground()` 方法,会在 Android 8.0 及以上版本上抛出 `IllegalStateException` 异常,因为 Android 8.0 及以上版本禁止在后台启动服务
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值