1. Download our Official Android App: Forums for Android!

Pusing notificaitons after app is killed

Discussion in 'Android Development' started by AsafKov, Aug 10, 2018.

  1. AsafKov

    AsafKov Lurker
    Thread Starter
    Rank:
    None
    Points:
    6
    Posts:
    8
    Joined:
    Jul 23, 2018

    Jul 23, 2018
    8
    1
    6
    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 (Text):
    1.         <service android:name=".Helpers.NotificationService"
    2.             android:exported="false" />
    NotificationService (The class that's supposed to handle the notifications)-
    Code (Text):
    1. package com.example.android.calendar.Helpers;
    2.  
    3. import android.app.AlarmManager;
    4. import android.app.IntentService;
    5. import android.app.Notification;
    6. import android.app.NotificationChannel;
    7. import android.app.NotificationManager;
    8. import android.app.PendingIntent;
    9. import android.content.Context;
    10. import android.content.Intent;
    11. import android.support.v4.app.NotificationCompat;
    12. import android.support.v4.app.NotificationManagerCompat;
    13.  
    14. import com.example.android.calendar.Model.Event;
    15. import com.example.android.calendar.R;
    16. import java.util.Calendar;
    17. import java.util.HashMap;
    18. import java.util.UUID;
    19.  
    20. public class NotificationService extends IntentService {
    21.  
    22.     private static Context mContext;
    23.     private static final String NOTIFICATION_CHANNEL_ID = "notificationChannelId";
    24.     private static final String NOTIFICATION_CHANNEL_NAME = "eventsNotificationChannel";
    25.  
    26.     public static final String EX_ID = "extraId";
    27.     public static final String ACTION_START_SERVICE = "startService";
    28.     public static final String ACTION_NOTIFY_ON_TIME = "notifyOnTime";
    29.  
    30.     private static HashMap<UUID, Notification> notifications = new HashMap<>();
    31.     public static int mCounter = 0;
    32.  
    33.  
    34.     public NotificationService(){
    35.         super("notificationService");
    36.     }
    37.  
    38.     @Override
    39.     public void onCreate(){
    40.         super.onCreate();
    41.     }
    42.  
    43.     @Override
    44.     protected void onHandleIntent(Intent intent){
    45.         if(intent.getAction().contentEquals(ACTION_START_SERVICE))
    46.             return;
    47.         UUID id = (UUID) intent.getSerializableExtra(EX_ID);
    48.         Notification notification = notifications.get(id);
    49.         NotificationManagerCompat mNM = NotificationManagerCompat.from(mContext);
    50.         mNM.notify(mCounter++, notification);
    51.         try{
    52.             Thread.sleep(1000);
    53.         } catch(InterruptedException e){
    54.             e.printStackTrace();
    55.         }
    56.     }
    57.  
    58.     @Override
    59.     public int onStartCommand(Intent intent, int flags, int startId){
    60.         super.onStartCommand(intent, flags, startId);
    61.         return IntentService.START_REDELIEVER_INTENT;
    62.     }
    63.  
    64.     public void createNotificationChannel(Context context){
    65.         mContext = context;
    66.         NotificationManager mNM = (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE);
    67.         NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
    68.                 NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
    69.         notificationChannel.enableVibration(true);
    70.         notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 100});
    71.         notificationChannel.enableLights(true);
    72.         mNM.createNotificationChannel(notificationChannel);
    73.     }
    74.  
    75.     public void createNotification(int minutesBefore, Event event){
    76.         NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mContext, NOTIFICATION_CHANNEL_ID).
    77.                 setSmallIcon(R.drawable.ic_launcher_foreground).setContentTitle(event.getLabel()).
    78.                 setContentText(event.getComment()).setAutoCancel(true);
    79.  
    80.         // If an event is edited, remove existing notification
    81.         if(notifications.get(event.getId()) != null)
    82.             notifications.remove(event.getId());
    83.  
    84.         Calendar mCalendar = Calendar.getInstance();
    85.         notifications.put(event.getId(), mBuilder.build());
    86.         mCalendar.setTime(event.getTime());
    87.         mCalendar.set(Calendar.SECOND, 0);
    88.  
    89.         Intent intent = new Intent(mContext, NotificationService.class);
    90.         intent.putExtra(EX_ID, event.getId());
    91.         intent.setAction(ACTION_NOTIFY_ON_TIME);
    92.         PendingIntent notificationIntent = PendingIntent.getService(mContext, (int)System.currentTimeMillis(),
    93.                 intent, PendingIntent.FLAG_CANCEL_CURRENT);
    94.         long triggerInMills = mCalendar.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();
    95.         AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
    96.         alarmManager.setExact(AlarmManager.RTC, System.currentTimeMillis() + triggerInMills, notificationIntent);
    97.     }
    98.  
    99.     public void cancelNotification(Event event, PendingIntent notificationIntent){
    100.         AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
    101.         alarmManager.cancel(notificationIntent);
    102.         notifications.remove(event.getId());
    103.     }
    104. }
    105.  
    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.
     

    Advertisement

Share This Page

Loading...