文章目录
一、报错信息
二、解决方案
一、报错信息
使用如下代码启动前台服务 :
public class ForegroundService extends Service { public ForegroundService() { } @Override public void onCreate() { super.onCreate(); // 将该服务转为前台服务 // 需要设置 ID 和 通知 // 设置 ID 为 0 , 就不显示已通知了 , 但是 oom_adj 值会变成后台进程 11 // 设置 ID 为 1 , 会在通知栏显示该前台服务 startForeground(1, new Notification()); } @Override public IBinder onBind(Intent intent) { return null; } }
Android 8.0 以下没问题 , 8.0 及以上 , 报如下错误 ;
报错信息 :
2021-04-08 19:36:34.736 23830-23830/? E/AndroidRuntime: FATAL EXCEPTION: main Process: kim.hsl.keep_progress_alive, PID: 23830 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:1745) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6718) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
二、解决方案
Android 8.0 以上不能用空的通知了 , 必须自己创建通知通道 , 创建通知 ;
package kim.hsl.keep_progress_alive.foreground_service; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.Service; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.os.Build; import android.os.IBinder; import androidx.annotation.RequiresApi; import androidx.core.app.NotificationCompat; import kim.hsl.keep_progress_alive.R; import static androidx.core.app.NotificationCompat.PRIORITY_MIN; public class ForegroundService extends Service { public ForegroundService() { } @Override public void onCreate() { super.onCreate(); // 将该服务转为前台服务 // 需要设置 ID 和 通知 // 设置 ID 为 0 , 就不显示已通知了 , 但是 oom_adj 值会变成后台进程 11 // 设置 ID 为 1 , 会在通知栏显示该前台服务 //startForeground(1, new Notification()); startForeground(); } @Override public IBinder onBind(Intent intent) { return null; } /** * 启动前台服务 */ private void startForeground() { String channelId = null; // 8.0 以上需要特殊处理 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { channelId = createNotificationChannel("kim.hsl", "ForegroundService"); } else { channelId = ""; } NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId); Notification notification = builder.setOngoing(true) .setSmallIcon(R.mipmap.ic_launcher) .setPriority(PRIORITY_MIN) .setCategory(Notification.CATEGORY_SERVICE) .build(); startForeground(1, notification); } /** * 创建通知通道 * @param channelId * @param channelName * @return */ @RequiresApi(Build.VERSION_CODES.O) private String createNotificationChannel(String channelId, String channelName){ NotificationChannel chan = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_NONE); chan.setLightColor(Color.BLUE); chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE); NotificationManager service = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); service.createNotificationChannel(chan); return channelId; } }