Android 8.0中Service和Notification

Android 8.0中Service和Notification

后台执行限制

Android 8.0 为提高电池续航时间而引入的变更之一是,当您的应用进入已缓存状态时,如果没有活动的组件,系统将解除应用具有的所有>>>唤醒锁。

此外,为提高设备性能,系统会限制未在前台运行的应用的某些行为。具体而言:

现在,在后台运行的应用对后台服务的访问受到限制。
应用无法使用其清单注册大部分隐式广播(即,并非专门针对此应用的广播)。
默认情况下,这些限制仅适用于针对 O 的应用。不过,用户可以从 Settings 屏幕为任意应用启用这些限制,即使应用并不是以 O 为目标平台。

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

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

因此我们需要根据版本判断是调用startForegroundService()或者startService()函数;

import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //android8.0以上通过startForegroundService启动service
            startForegroundService(new Intent(MainActivity.this, MyService.class));
        }else{
            startService(new Intent(MainActivity.this, MyService.class));
        }
    }
}

同时描述中提到,

应用必须在创建服务后的五秒内调用该服务的 startForeground() 函数。

因此我们必须在服务创建之后调用startForeground()函数。

public class MyService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
       startForeground(1,new Notification());
    }
}

调用之后会发现崩溃报错如下信息:

09-26 17:01:17.654 18911-18911/com.zy.testmyservice E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.zy.testmyservice, PID: 18911
    android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=null pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 vis=PRIVATE)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1793)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6648)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:818)

在android8.0中对Notificationj进行了变更,如下所示:

通知

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

Android 8.0 中的通知长按菜单。

通知渠道:Android 8.0 引入了通知渠道,其允许您为要显示的每种通知类型创建用户可自定义的渠道。用户界面将
通知渠道称之为通知类别。要了解如何实现通知渠道的信息,请参阅通知渠道指南。

通知标志:Android 8.0 引入了对在应用启动器图标上显示通知标志的支持。通知标志可反映某个应用是否存在与其
关联、并且用户尚未予以清除也未对其采取行动的通知。通知标志也称为通知点。要了解如何调整通知标志,请参阅通知标志指南。

休眠:用户可以将通知置于休眠状态,以便稍后重新显示它。重新显示时通知的重要程度与首次显示时相同。应用可以移除或更新已休眠的通知,但更新休眠的通知并不会使其重新显示。

通知超时:现在,使用 setTimeoutAfter() 创建通知时您可以设置超时。您可以使用此函数指定一个持续时间,超过该持续时间后,通知应取消。如果需要,您可以在指定的超时持续时间之前取消通知。

通知设置:当您使用 Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCESIntent 从通知创建指向应用通知设置的链接时,您可以调用 setSettingsText() 来设置要显示的文本。此系统可以提供以下 Extra 数据和 Intent,用于过滤应用必须向用户显示的设置:EXTRA_CHANNEL_ID、NOTIFICATION_TAG 和 NOTIFICATION_ID。

通知清除:系统现在可区分通知是由用户清除,还是由应用移除。要查看清除通知的方式,您应实现 NotificationListenerService 类的新 onNotificationRemoved() 函数。

背景颜色:您现在可以设置和启用通知的背景颜色。只能在用户必须一眼就能看到的持续任务的通知中使用此功能。例如,您可以为与驾车路线或正在进行的通话有关的通知设置背景颜色。您还可以使用 Notification.Builder.setColor() 设置所需的背景颜色。这样做将允许您使用 Notification.Builder.setColorized() 启用通知的背景颜色设置。

消息样式:现在,使用 MessagingStyle 类的通知可在其折叠形式中显示更多内容。对于与消息有关的通知,您应使用 MessagingStyle 类。您还可以使用新的 addHistoricMessage() 函数,通过向与消息相关的通知添加历史消息为会话提供上下文。

同时提供了示例代码:android-NotificationChannels

因此我们需要针对Android8.0以上版本增加NotificationChannel,如下所示:

public class MyService extends Service {

    private NotificationManager notificationManager;
    private String notificationId = "channelId";
    private String notificationName = "channelName";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private Notification getNotification() {
        Notification.Builder builder = new Notification.Builder(this)
                .setSmallIcon(R.drawable.logo_small)
                .setContentTitle("测试服务")
                .setContentText("我正在运行");
        //设置Notification的ChannelID,否则不能正常显示
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder.setChannelId(notificationId);
        }
        Notification notification = builder.build();
        return notification;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        //创建NotificationChannel
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            NotificationChannel channel = new NotificationChannel(notificationId, notificationName, NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(channel);
        }
        startForeground(1,getNotification());
    }
}

以上,便能正常在Android8.0以上版本中正常启动Service。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 4

打赏作者

苍蝇小黑

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值