Mulgard
Mulgard

Reputation: 10589

Closing notification tab on swipe

I implemented a very basic demonstration of a service with an asynctask and notifications:

public class ImageSendEmailService extends Service implements EmailCallback {
    private static final int IMAGE_SEND_EMAIL_SERVICE_ID = 100;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent.getAction().equals(ForegroundServiceTags.STARTFOREGROUND_ACTION.getValue())) {
            EmailTask emailTask = new EmailTask();
            emailTask.setCallback(this);
            emailTask.execute();
        }

        return super.onStartCommand(intent, flags, startId);
    }

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

    public void onEmailSendingStarted() {}

    @Override
    public void onEmailSendingProgressUpdate(String progressMessage) {
        Notification.Builder builder = new Notification.Builder(this);
        builder.setContentTitle("Progress");
        builder.setContentText(progressMessage);
        builder.setTicker("Notification!");
        builder.setWhen(System.currentTimeMillis());
        builder.setSmallIcon(R.drawable.ic_launcher);
        Notification notification = builder.build();

        this.startForeground(IMAGE_SEND_EMAIL_SERVICE_ID, notification);
    }

    @Override
    public void onEmailSendingCompleted() {
        Notification.Builder builder = new Notification.Builder(this);
        builder.setContentTitle("Progress");
        builder.setContentText("Progress completed");
        builder.setTicker("Notification!");
        builder.setWhen(System.currentTimeMillis());
        builder.setSmallIcon(R.drawable.ic_launcher);
        Notification notification = builder.build();

        this.startForeground(IMAGE_SEND_EMAIL_SERVICE_ID, notification);
    }
}   

public class EmailTask extends AsyncTask<Void, Void, Void> {
    private EmailCallback callback = null;
    private int progress = 0;
    private String progressMessage = null;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... params) {
        this.callback.onEmailSendingStarted();

        for (this.progress = 0; this.progress <= 10; this.progress++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            this.progressMessage = String.valueOf((int) (100 * this.progress / 10)) + " %";
            this.publishProgress();
        }

        return null;
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);

        this.callback.onEmailSendingProgressUpdate(this.progressMessage);
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);

        this.callback.onEmailSendingCompleted();
    }

    public void setCallback(EmailCallback callback) {
        this.callback = callback;
    }
}

As you can see i did not set my notification to be ongoing but the notification is still not killable. I want the notification to stay as long as the user decides to swipe it away from the notification bar.

How can i do that?

And btw. can i also make a warning or something when the user swipes away a notification which could kill a long running process?

Upvotes: 0

Views: 543

Answers (1)

Eugen Pechanec
Eugen Pechanec

Reputation: 38223

I want the notification to stay as long as the user decides to swipe it away from the notification bar.

builder.setAutoCancel(false); will make your notification remain in place even if the user clicks it. The user has to swipe it away.

builder.setOngoing(true) will make your notification unswipeable.

Do not use these two together unless you have some other way of removing the notification.

can i also make a warning or something when the user swipes away a notification which could kill a long running process?

A foreground service should use an ongoing notification (so the user does not kill it unintentionally by swiping) which will launch an activity when clicked. This activity may contain the following:

  • Stop button
  • Current state of the service
  • Results so far
  • etc.

Search this article for setContentIntent to find out how to launch an activity by clicking on notification.

Upvotes: 3

Related Questions