• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Pusing notificaitons after app is killed

AsafKov

Newbie
Jul 23, 2018
12
1
Hi guys. I've been trying to make notifications for my calendar-planner project and I'm stuck for the past couple of days on an issue with no progress.
Thus far I have a notification publisher that works fine as long as the app is isn't removed from the recent tasks. Otherwise, the notifications will not be shown.
I tried searching online for answers but got no concrete answer for how it is supposed to work. What I did find simply doesn't work. The code:
Declaring the service in the manifest-
Code:
        <service android:name=".Helpers.NotificationService"
            android:exported="false" />
NotificationService (The class that's supposed to handle the notifications)-
Code:
package com.example.android.calendar.Helpers;

import android.app.AlarmManager;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;

import com.example.android.calendar.Model.Event;
import com.example.android.calendar.R;
import java.util.Calendar;
import java.util.HashMap;
import java.util.UUID;

public class NotificationService extends IntentService {

    private static Context mContext;
    private static final String NOTIFICATION_CHANNEL_ID = "notificationChannelId";
    private static final String NOTIFICATION_CHANNEL_NAME = "eventsNotificationChannel";

    public static final String EX_ID = "extraId";
    public static final String ACTION_START_SERVICE = "startService";
    public static final String ACTION_NOTIFY_ON_TIME = "notifyOnTime";

    private static HashMap<UUID, Notification> notifications = new HashMap<>();
    public static int mCounter = 0;


    public NotificationService(){
        super("notificationService");
    }

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

    @Override
    protected void onHandleIntent(Intent intent){
        if(intent.getAction().contentEquals(ACTION_START_SERVICE))
            return;
        UUID id = (UUID) intent.getSerializableExtra(EX_ID);
        Notification notification = notifications.get(id);
        NotificationManagerCompat mNM = NotificationManagerCompat.from(mContext);
        mNM.notify(mCounter++, notification);
        try{
            Thread.sleep(1000);
        } catch(InterruptedException e){
            e.printStackTrace();
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId){
        super.onStartCommand(intent, flags, startId);
        return IntentService.START_REDELIEVER_INTENT;
    }

    public void createNotificationChannel(Context context){
        mContext = context;
        NotificationManager mNM = (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE);
        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
                NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
        notificationChannel.enableVibration(true);
        notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 100});
        notificationChannel.enableLights(true);
        mNM.createNotificationChannel(notificationChannel);
    }

    public void createNotification(int minutesBefore, Event event){
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mContext, NOTIFICATION_CHANNEL_ID).
                setSmallIcon(R.drawable.ic_launcher_foreground).setContentTitle(event.getLabel()).
                setContentText(event.getComment()).setAutoCancel(true);

        // If an event is edited, remove existing notification
        if(notifications.get(event.getId()) != null)
            notifications.remove(event.getId());

        Calendar mCalendar = Calendar.getInstance();
        notifications.put(event.getId(), mBuilder.build());
        mCalendar.setTime(event.getTime());
        mCalendar.set(Calendar.SECOND, 0);

        Intent intent = new Intent(mContext, NotificationService.class);
        intent.putExtra(EX_ID, event.getId());
        intent.setAction(ACTION_NOTIFY_ON_TIME);
        PendingIntent notificationIntent = PendingIntent.getService(mContext, (int)System.currentTimeMillis(),
                intent, PendingIntent.FLAG_CANCEL_CURRENT);
        long triggerInMills = mCalendar.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();
        AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        alarmManager.setExact(AlarmManager.RTC, System.currentTimeMillis() + triggerInMills, notificationIntent);
    }

    public void cancelNotification(Event event, PendingIntent notificationIntent){
        AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        alarmManager.cancel(notificationIntent);
        notifications.remove(event.getId());
    }
}

I want to stress - the notifications properly work when the app is in the background\foreground.
I don't have prior knowledge with processes. From what I gathered the problem is that this app component is destroyed when the app itself is destroyed.
One work around I found was making it a foreground service, however this doesn't suit the nature of the app. The other is making onStartCommand() return START_REDELIEVER_INTENT, I thought it made sense according to the docs, but it does nothing. Some people suggested START_STICKY is the key but it didn't work either.

I hope I descirbed the issue well enough and gave the relevant code. Any insight into the matter would be appreciated.
Also, any good sources that explain this subject. Pehaps I overlooked something obvious or simply didn't manage to peice things together.
 

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones