startForeground fail after upgrade to Android 8.1
After some tinkering for a while with different solutions i found out that one must create a notification channel in Android 8.1 and above.
private fun startForeground() { val channelId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { createNotificationChannel("my_service", "My Background Service") } else { // If earlier version channel ID is not used // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) "" } val notificationBuilder = NotificationCompat.Builder(this, channelId ) val notification = notificationBuilder.setOngoing(true) .setSmallIcon(R.mipmap.ic_launcher) .setPriority(PRIORITY_MIN) .setCategory(Notification.CATEGORY_SERVICE) .build() startForeground(101, notification)}@RequiresApi(Build.VERSION_CODES.O)private fun createNotificationChannel(channelId: String, channelName: String): String{ val chan = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_NONE) chan.lightColor = Color.BLUE chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager service.createNotificationChannel(chan) return channelId}
From my understanding background services are now displayed as normal notifications that the user then can select to not show by deselecting the notification channel.
Update:Also don't forget to add the foreground permission as required Android P:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Java Solution (Android 9.0, API 28)
In your Service
class, add this:
@Overridepublic void onCreate(){ super.onCreate(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) startMyOwnForeground(); else startForeground(1, new Notification());}private void startMyOwnForeground(){ String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp"; String channelName = "My Background Service"; NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE); chan.setLightColor(Color.BLUE); chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE); NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); assert manager != null; manager.createNotificationChannel(chan); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID); Notification notification = notificationBuilder.setOngoing(true) .setSmallIcon(R.drawable.icon_1) .setContentTitle("App is running in background") .setPriority(NotificationManager.IMPORTANCE_MIN) .setCategory(Notification.CATEGORY_SERVICE) .build(); startForeground(2, notification);}
UPDATE: ANDROID 9.0 PIE (API 28)
Add this permission to your AndroidManifest.xml
file:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
The first answer is great only for those people who know kotlin, for those who still using java here I translate the first answer
public Notification getNotification() { String channel; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) channel = createChannel(); else { channel = ""; } NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, channel).setSmallIcon(android.R.drawable.ic_menu_mylocation).setContentTitle("snap map fake location"); Notification notification = mBuilder .setPriority(PRIORITY_LOW) .setCategory(Notification.CATEGORY_SERVICE) .build(); return notification; } @NonNull @TargetApi(26) private synchronized String createChannel() { NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); String name = "snap map fake location "; int importance = NotificationManager.IMPORTANCE_LOW; NotificationChannel mChannel = new NotificationChannel("snap map channel", name, importance); mChannel.enableLights(true); mChannel.setLightColor(Color.BLUE); if (mNotificationManager != null) { mNotificationManager.createNotificationChannel(mChannel); } else { stopSelf(); } return "snap map channel"; }
For android, P don't forget to include this permission
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />