my onStartCommand function:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    Intent notifIntent = new Intent(this,MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,
            0,notifIntent,0);
    notifManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    contentView = new RemoteViews(getPackageName(), R.layout.download_notification_bar);
    contentView.setImageViewResource(R.id.image, R.mipmap.ic_launcher);
    contentView.setTextViewText(R.id.title, "Custom notification");


    notification = new NotificationCompat.Builder(this,CHANEL_ID)
            .setContentTitle("test")
            .setContentText("test Againg")
            .setContent(contentView)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentIntent(pendingIntent)
            .build();

    startForeground(1,notification);

    return  START_STICKY;

}

but the notification showing on top of screen is able to be removed (swipe out):

enter image description here enter image description here

2 Answers

0
CommonsWare On

START_STICKY has nothing to do with notifications.

Add setOngoing(true) to your NotificationCompat.Builder.

1
János Sicz-Mesziár On

Beginning of Android O, you should start with startForegroundService() but better way to use ContextCompat.startForegroundService().

Beginning of Andorid Q, you have to add permission:

<!-- Android Q requirement -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> 

Here is a minimal setup for foreground service across Android versions:

Kotlin:

class ForegroundServiceSample : Service() {

    companion object {
        @JvmStatic
        fun start(context: Context) {
            ContextCompat.startForegroundService(context, Intent(context, ForegroundServiceSample::class.java))
        }

        @JvmStatic
        fun stop(context: Context) {
            context.stopService(Intent(context, ForegroundServiceSample::class.java))
        }
    }

    // Foreground service notification =========

    private val foregroundNotificationId: Int = (System.currentTimeMillis() % 10000).toInt()
    private val foregroundNotification by lazy {
        NotificationCompat.Builder(this, foregroundNotificationChannelId)
            .setSmallIcon(R.drawable.ic_sample_service)
            .setPriority(NotificationCompat.PRIORITY_MIN)
            .setSound(null)
            .build()
    }
    private val foregroundNotificationChannelName by lazy {
        getString(R.string.sample_service_name)
    }
    private val foregroundNotificationChannelDescription by lazy {
        getString(R.string.sample_service_description)
    }
    private val foregroundNotificationChannelId by lazy {
        "ForegroundServiceSample.NotificationChannel".also {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                (getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager).apply {
                    if (getNotificationChannel(it) == null) {
                        createNotificationChannel(NotificationChannel(
                            it,
                            foregroundNotificationChannelName,
                            NotificationManager.IMPORTANCE_MIN
                        ).also {
                            it.description = foregroundNotificationChannelDescription
                            it.lockscreenVisibility = NotificationCompat.VISIBILITY_PRIVATE
                            it.vibrationPattern = null
                            it.setSound(null, null)
                            it.setShowBadge(false)
                        })
                    }
                }
            }
        }
    }


    // Lifecycle ===============================

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForeground(foregroundNotificationId, foregroundNotification)
        }
        return START_STICKY
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

}

Java:

public class ForegroundServiceSample extends Service {

    public static void start(Context context) {
        ContextCompat.startForegroundService(context, new Intent(context, ForegroundServiceSample.class));
    }

    public static void stop(Context context) {
        context.stopService(new Intent(context, ForegroundServiceSample.class));
    }


    // Foreground service notification =========

    private final static int foregroundNotificationId = (int) (System.currentTimeMillis() % 10000);

    // Notification
    private static Notification foregroundNotification = null;
    public Notification getForegroundNotification() {
        if (foregroundNotification == null) {
            foregroundNotification = new NotificationCompat.Builder(getApplicationContext(), getForegroundNotificationChannelId())
                    .setSmallIcon(R.drawable.ic_sample_service)
                    .setPriority(NotificationCompat.PRIORITY_MIN)
                    .setSound(null)
                    .build();
        }
        return foregroundNotification;
    }

    // Notification channel name
    private static String foregroundNotificationChannelName = null;
    public String getForegroundNotificationChannelName() {
        if (foregroundNotificationChannelName == null) {
            foregroundNotificationChannelName = getString(R.string.sample_service_name);
        }
        return foregroundNotificationChannelName;
    }


    // Notification channel description
    private static String foregroundNotificationChannelDescription = null;
    public String getForegroundNotificationChannelDescription() {
        if (foregroundNotificationChannelDescription == null) {
            foregroundNotificationChannelDescription = getString(R.string.sample_service_description);
        }
        return foregroundNotificationChannelDescription;
    }

    // Notification channel id
    private String foregroundNotificationChannelId = null;
    public String getForegroundNotificationChannelId() {
        if (foregroundNotificationChannelId == null) {
            foregroundNotificationChannelId = "ForegroundServiceSample.NotificationChannel";
            // Android O+ channel is a requirement
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                // Not exists so we create it at first time
                if (manager.getNotificationChannel(foregroundNotificationChannelId) == null) {
                    NotificationChannel nc = new NotificationChannel(
                            getForegroundNotificationChannelId(),
                            getForegroundNotificationChannelName(),
                            NotificationManager.IMPORTANCE_MIN
                    );
                    // Discrete notification setup
                    manager.createNotificationChannel(nc);
                    nc.setDescription(getForegroundNotificationChannelDescription());
                    nc.setLockscreenVisibility(NotificationCompat.VISIBILITY_PRIVATE);
                    nc.setVibrationPattern(null);
                    nc.setSound(null, null);
                    nc.setShowBadge(false);
                }
            }
        }
        return foregroundNotificationChannelId;
    }


    // Lifecycle ===============================

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForeground(foregroundNotificationId, getForegroundNotification());
        }
        return START_STICKY;
    }

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