android Service在8.0以及通知栏不显示的问题

android系统在8.0以后Service无法正常使用,在低版本上面不会出现问题,这是因为
在后台中运行的服务会消耗设备资源,这可能降低用户体验。 为了缓解这一问题,系统对这些服务施加了一些限制。系统可以区分 前台 和 后台 应用。(用于服务限制目的的后台定义与内存管理使用的定义不同;一个应用按照内存管理的定义可能处于后台,但按照能够启动服务的定义又处于前台。)如果满足以下任意条件,应用将被视为处于前台:
• 具有可见 Activity(不管该 Activity 已启动还是已暂停)。
• 具有前台服务。
• 另一个前台应用已关联到该应用(不管是通过绑定到其中一个服务,还是通过使用其中一个内容提供程序)。 例如,如果另一个应用绑定到该应用的服务,那么该应用处于前台。
Android 8.0 还对特定函数做出了以下变更:
如果针对 Android 8.0 的应用尝试在不允许其创建后台服务的情况下使用 startService() 函数,如果使用将会出现异常IllegalStateException。
新的 Context.startForegroundService() 函数将启动一个前台服务。现在,即使应用在后台运行,系统也允许其调用 Context.startForegroundService()。不过,应用必须在创建服务后的五秒内调用该服务的 startForeground() 函数。
具体代码如下

Intent intent = new Intent(this, PlayService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent);
} else {
startService(intent);
}

如果仅仅只是做上面的设置,还是远远不够的,因为这样的话你运行的时候就会发现,会报ANR,这个问题又如何解决呢?只需要在你设置的Service的onCreate()里面设置加入如下代码即可解决

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(DEFAULT_CHANNEL_ID, DEFAULT_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
channel.enableVibration(false);
channel.setVibrationPattern(new long[]{0});
channel.setSound(null, null);
if (mNotificationManager != null) {
mNotificationManager.createNotificationChannel(channel);
}
Notification notification = new Notification.Builder(getApplicationContext(), DEFAULT_CHANNEL_ID).build();
startForeground(SERVICE_NOTIFICATION_ID, notification);
stopForeground(true);
}

但是我们有时需要显示通知栏,但是通知栏在8.0的系统上面突然消失了,Android8.0中,对于通知栏的下载更新显示需要重新定义,需要优先定义一个应用中唯一的ID和Name。通过下面的代码对比你会发现NotificationChannel ,Android O 引入了 通知渠道(Notification Channels),以提供统一的系统来帮助用户管理通知,如果是针对 android O 为目标平台时,必须实现一个或者多个通知渠道,以向用户显示通知。比如聊天软件,为每个聊天组设置一个通知渠道,指定特定声音、灯光等配置。设置代码如下:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationChannel channel = new NotificationChannel(PUSH_CHANNEL_ID, PUSH_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
    channel.enableVibration(false);
    channel.setVibrationPattern(new long[]{0});
    channel.setSound(null, null);
    if (mNotificationManager != null) {
        mNotificationManager.createNotificationChannel(channel);
    }
    builder = new Notification.Builder(this, PUSH_CHANNEL_ID).setContent(remoteViews)
            .setSmallIcon(R.drawable.icon_logo)
            .setContentIntent(click)
            .setDeleteIntent(cancelPIntent)
            .setWhen(mNotificationPostTime)
            .setChannelId(PUSH_CHANNEL_ID)
            .setPriority(Notification.PRIORITY_MAX);
    mNotification = builder.getNotification();

} else {
    builder = new Notification.Builder(this).setContent(remoteViews)
            .setSmallIcon(R.drawable.icon_logo)
            .setContentIntent(click)
            .setDeleteIntent(cancelPIntent)
            .setWhen(mNotificationPostTime)
            .setPriority(Notification.PRIORITY_MAX);
    mNotification = builder.build();
}

建议ID和Name字符尽量简短,不易过长,否则会被截取。例如:

private static final String DEFAULT_CHANNEL_ID = "COM.QZYX.YIQU_CHANNEL_ID";
private static final String DEFAULT_CHANNEL_NAME = "默认音频";
private static final int SERVICE_NOTIFICATION_ID = 0x888;

切记!startForeground的id不能设置为0.
如有什么不明白的欢迎留言!

你可能感兴趣的:(android,Service8.0)