Android 保活后台启动Service 8.0踩坑记录

Android 保活后台启动Service 8.0踩坑记录

发现的问题

android使用保活后,启动后台服务抛出一下异常:

Caused by java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.yangwenhao.demo/.keepalive.StepService }: app is in background uid UidRecord{68e0b96 u0a190 TRNB idle procs:1 seq(0,0,0)}

在Android 8.0之后版本,禁止启动后台服务,startService(intent)会抛出不允许启动服务意图

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

解决方法

1.修改启动方法

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

2.被启动Service调整为前台服务,否则会出现ANR

在Service的onCreate()方法中,注意Android 8.0版本通知栏创建方式

		//设置点击跳转
        Intent intent = new Intent(context, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

        String id = "1";
        String name = "channel_name_1";
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notification = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel mChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_DEFAULT);
            mChannel.setSound(null, null);
            notificationManager.createNotificationChannel(mChannel);
            notification = new Notification.Builder(context)
                    .setChannelId(id)
                    .setContentTitle(context.getResources().getString(R.string.app_name))
                    .setContentIntent(pendingIntent)
                    .setAutoCancel(false)// 设置这个标志当用户单击面板就可以让通知将自动取消
                    .setOngoing(true)// true,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
                    .setSmallIcon(R.drawable.ic_logo).build();
        } else {
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
                    .setContentTitle(context.getResources().getString(R.string.app_name))
                    .setContentIntent(pendingIntent)
                    .setPriority(Notification.PRIORITY_DEFAULT)// 设置该通知优先级
                    .setAutoCancel(false)// 设置这个标志当用户单击面板就可以让通知将自动取消
                    .setOngoing(true)// true,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
                    .setSmallIcon(R.drawable.ic_logo);
            notification = notificationBuilder.build();
        }
        startForeground(1, notification);

猜你喜欢

转载自blog.csdn.net/QingTeng_CSDN/article/details/83543219