首页 > 其他分享 >Android 8.0 + Service开启方式兼容处理

Android 8.0 + Service开启方式兼容处理

时间:2022-11-04 21:00:37浏览次数:91  
标签:8.0 服务 Service Notification 通知 Android android


Android 8.0 + ,对后台服务进行了限制了。如果依然采用之前startService()方式。

会导致问题。

前后台服务的一些区别:

类别

区别

应用

前台服务

会在通知一栏显示 ONGOING 的 Notification, 当服务被终止的时候,通知一栏的 Notification 也会消失,这样对于用户有一定的通知作用。

常见的如音乐播放服务

后台服务

默认的服务即为后台服务,即不会在通知一栏显示 ONGOING 的 Notification。 当服务被终止的时候,用户是看不到效果的。

某些不需要运行或终止提示的服务,如天气更新,日期同步,邮件同步等。



有人可能会问,后台服务我们可以自己创建 ONGOING 的 Notification 这样就成为前台服务吗?答案是否定的,前台服务是在做了上述工作之后需要调用 startForeground ( android 2.0 及其以后版本 )或 setForeground (android 2.0 以前的版本)使服务成为 前台服务。这样做的好处在于,当服务被外部强制终止掉的时候,ONGOING 的 Notification 任然会移除掉。

api 8.0+ 、9.0 关于服务的行为变更。

8.0

后台执行限制

Android 8.0 为提高电池续航时间而引入的变更之一是,当您的应用进入已缓存状态时,如果没有活动的组件,系统将解除应用具有的所有唤醒锁。
此外,为提高设备性能,系统会限制未在前台运行的应用的某些行为。具体而言:
* 现在,在后台运行的应用对后台服务的访问受到限制。
* 应用无法使用其清单注册大部分隐式广播(即,并非专门针对此应用的广播)。
默认情况下,这些限制仅适用于针对 O 的应用。不过,用户可以从 Settings 屏幕为任意应用启用这些限制,即使应用并不是以 O 为目标平台。
Android 8.0 还对特定函数做出了以下变更:
* 如果针对 Android 8.0 的应用尝试在不允许其创建后台服务的情况下使用 startService() 函数,则该函数将引发一个 IllegalStateException。
* 新的 Context.startForegroundService() 函数将启动一个前台服务。现在,即使应用在后台运行,系统也允许其调用 Context.startForegroundService()。不过,应用必须在创建服务后的五秒内调用该服务的 startForeground() 函数。
如需了解详细信息,请参阅后台执行限制。

9.0

前台服务

针对 Android 9 或更高版本并使用前台服务的应用必须请求 FOREGROUND_SERVICE 权限。 这是普通权限,因此,系统会自动为请求权限的应用授予此权限。
如果针对 Android 9 或更高版本的应用尝试创建一个前台服务且未请求 FOREGROUND_SERVICE,则系统会引发 SecurityException。

网友推荐的解决方式:

原来startService()需要根据sdk版本进行兼容

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}

**系统说明在调用 context.startForegroundService(intent);服务后5s内需要调用**

startForeground(1, notification);

根据网友提供方案,在 api =26 级别可以正常跑起来,但是在api =27 级别下,启动直接崩溃,具体crash 异常日志如下:

09-03 16:13:28.563 6124-6124/com.nuoyuan.nyd E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.nuoyuan.nyd, PID: 6124
android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel= pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 vis=PRIVATE)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1768)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

这里牵扯到android 8.0 关于 Notification 的行为变更 ###通知

在 Android 8.0 中,我们已重新设计通知,以便为管理通知行为和设置提供更轻松和更统一的方式。这些变更包括:

  • 图 1. 用户可以长按应用启动器图标以查看 Android 8.0 中的通知。
  • 通知渠道:Android 8.0 引入了通知渠道,其允许您为要显示的每种通知类型创建用户可自定义的渠道。用户界面将通知渠道称之为通知类别。要了解如何实现通知渠道的信息,请参阅​​通知渠道​​指南。
  • 通知标志:Android 8.0 引入了对在应用启动器图标上显示通知标志的支持。通知标志可反映某个应用是否存在与其关联、并且用户尚未予以清除也未对其采取行动的通知。通知标志也称为通知点。要了解如何调整通知标志,请参阅​​通知标志​​指南。
  • 休眠:用户可以将通知置于休眠状态,以便稍后重新显示它。重新显示时通知的重要程度与首次显示时相同。应用可以移除或更新已休眠的通知,但更新休眠的通知并不会使其重新显示。
  • 通知超时:现在,使用 ​​setTimeoutAfter()​​ 创建通知时您可以设置超时。您可以使用此函数指定一个持续时间,超过该持续时间后,通知应取消。如果需要,您可以在指定的超时持续时间之前取消通知。
  • 通知设置:当您使用 ​​Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES​​​Intent 从通知创建指向应用通知设置的链接时,您可以调用 ​​setSettingsText()​​​ 来设置要显示的文本。此系统可以提供以下 Extra 数据和 Intent,用于过滤应用必须向用户显示的设置:​​EXTRA_CHANNEL_ID​​​、​​NOTIFICATION_TAG​​​ 和 ​​NOTIFICATION_ID​​。
  • 通知清除:系统现在可区分通知是由用户清除,还是由应用移除。要查看清除通知的方式,您应实现 ​​NotificationListenerService​​​ 类的新 ​​onNotificationRemoved()​​ 函数。
  • 背景颜色:您现在可以设置和启用通知的背景颜色。只能在用户必须一眼就能看到的持续任务的通知中使用此功能。例如,您可以为与驾车路线或正在进行的通话有关的通知设置背景颜色。您还可以使用 ​​Notification.Builder.setColor()​​​ 设置所需的背景颜色。这样做将允许您使用 ​​Notification.Builder.setColorized()​​ 启用通知的背景颜色设置。
  • 消息样式:现在,使用 ​​MessagingStyle​​​ 类的通知可在其折叠形式中显示更多内容。对于与消息有关的通知,您应使用 ​​MessagingStyle​​​ 类。您还可以使用新的 ​​addHistoricMessage()​​ 函数,通过向与消息相关的通知添加历史消息为会话提供上下文。

根据上面提示,Notification 需要添加 channelId 才可以正常使用

如下修改,可以正常兼容 api 级别 8.0 ,8.1 + 的service 正常开启

public class UploadFilesIntentService extends IntentService {
private static final String UPLOAD_FILE = "com.nuoyuan.statistic.action.UPLOAD_FILE";
private static String loadUrlPath = "";
private static SttcHeadParams mHeadParams;
public static final String CHANNEL_ID_STRING = "nyd001";
@Override
public void onCreate() {
super.onCreate();
//适配8.0service
NotificationManager notificationManager = (NotificationManager) MyApp.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel mChannel = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
mChannel = new NotificationChannel(CHANNEL_ID_STRING, "诺秒贷", NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(mChannel);
Notification notification = new Notification.Builder(getApplicationContext(), CHANNEL_ID_STRING).build();
startForeground(1, notification);
}
}

public UploadFilesIntentService() {
super("UploadFilesIntentService");
}

public static void startActionFoo(Context context, String loadPath, SttcHeadParams headParams) {
Intent intent = new Intent(context, UploadFilesIntentService.class);
intent.setAction(UPLOAD_FILE);
mHeadParams = headParams;
loadUrlPath = loadPath;
//开启服务兼容
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
}

……
……
…….
}

引用
google 官方文档 ​​​https://developer.android.google.cn/about/versions/oreo/android-8.0​


标签:8.0,服务,Service,Notification,通知,Android,android
From: https://blog.51cto.com/u_15861646/5824769

相关文章

  • systemctl start 1.service 2.service 3.service 多服务同时操作
    启动服务:systemctlstartxxx.service关闭服务:systemctlstopxxx.service重启服务:systemctlrestartxxx.service显示服务的状态:systemctlstatusxxx.service在开机......
  • 从android 谈重构
    什麽是重构可以运作的程式跟可以维护的程式之间,还有一道难以言说的鸿沟。一个程式设计之初,是用来解决特定问题。就像在前面章节的学习中,我们也已......
  • Windows Server 2016部署MySQL 8.0 MGR
    环境介绍操作系统IP主机名MySQL版本WindowsServer2016192.168.1.91db18.0.31WindowsServer2016192.168.1.92db28.0.31WindowsServer2016192.......
  • Android的BLE广播数据包解析---Android系列, 蓝牙技术(含BLE)
      一、引言理解和分析这个数据包结构(这里面也涉及广播间隔时间的设置,设备广播数据间隔设置长了,会影响设备被发现的效率;设置短时,又响应功耗)。我们所说的BLE设备,其实......
  • CompletionService 源码解析
    ​​CompletionService​​​的主要作用是:按照异步任务的完成顺序,逐个获取到已经完成的异步任务。主要实现是在​​ExecutorCompletionService​​中。类图核心内部类privat......
  • Android TextView 设置内容可滚动
    前言开发中scrollBar用的最多的地方就是在内容超过显示区域后,可以手动上下左右滑动来查看解决方案比较多。方案一使用一个可滑动的组件ScroolView包裹用于在内容超过显示......
  • Android Compose 修饰符类行为整理
    前言compose修饰符用来对界面组件装饰,类似ViewTree系统的组件属性,compose对于修饰符用法做了限制,RowScope,ColumScope,BoxScope,等等限制为仅可以在这些组件使用的修饰符......
  • Android LayoutParam,MarginLayoutParams
    前言开发中经常会遇到一个场景,给View动态设置margin边距,针对容器类布局比较直观。对非容器类进行margin边距设置需按不同的LayoutParams设置,否则很容造成异常。问题:为......
  • Android 使用 unity 导出obb包
    1.通过unity导出包含obb的工程。2.按照google官方给定的obb命名方式,已经存放路径进行操作​​Obb命名方式​​命名方式:[main|patch]。<扩展版本>。<程序包名称>.obbeg......
  • Android LocalBroadcastManager 使用
    前言LocalBroadcastManager简单使用。1.注册【添加IntentFilter】2.反注册3.发广播publicclassMain2ActivityextendsAppCompatActivity{@Overrideprotect......