1

Ok, so this is a kind of a duplicate in a sense of a lot of questions for example this one: Using Service to run background and create notification from which I have taken code and got it to do what I need to work.

However there is a problem now with all the answers, they want to use WakefulBroadcastReceiver which is now depreciated. I understand I now need to use JobService, so I tried updating the code in the previous post to look like this (using in part this tutorial https://www.vogella.com/tutorials/AndroidTaskScheduling/article.html)

public class NotificationEventReceiver extends JobService {

    private static final String ACTION_START_NOTIFICATION_SERVICE = "ACTION_START_NOTIFICATION_SERVICE";
    private static final String ACTION_DELETE_NOTIFICATION = "ACTION_DELETE_NOTIFICATION";
    private static final int NOTIFICATIONS_INTERVAL = 1;

    public static void setupAlarm(Context context) {
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        PendingIntent alarmIntent = getStartPendingIntent(context);
        alarmManager.setRepeating(AlarmManager.RTC,
                getTriggerAt(new Date()),
                NOTIFICATIONS_INTERVAL * AlarmManager.INTERVAL_DAY,
                alarmIntent);
    }

    private static long getTriggerAt(Date now) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        //calendar.add(Calendar.HOUR, NOTIFICATIONS_INTERVAL_IN_HOURS);
        calendar.set(Calendar.HOUR_OF_DAY, 5);
        calendar.set(Calendar.MINUTE, 0);
        return calendar.getTimeInMillis();
    }

    @Override
    public boolean onStartJob(JobParameters params) {
        Intent service = new Intent(getApplicationContext(), NotificationIntentService.class);
        getApplicationContext().startService(service);
        setupAlarm(getApplicationContext()); // reschedule the job
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return true;
    }

    private static PendingIntent getStartPendingIntent(Context context) {
        Intent intent = new Intent(context, NotificationEventReceiver.class);
        intent.setAction(ACTION_START_NOTIFICATION_SERVICE);
        return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    public static PendingIntent getDeleteIntent(Context context) {
        Intent intent = new Intent(context, NotificationEventReceiver.class);
        intent.setAction(ACTION_DELETE_NOTIFICATION);
        return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }
}

And then in the Android Manifest

    <service
        android:name=".NotificationEventReceiver"
        android:label="Notification Service"
        android:permission="android.permission.BIND_JOB_SERVICE" />

When run I no longer get any notifications, so I clearly did something wrong, but I am at a loss as it what I need to do.

Michael Buckley
  • 591
  • 4
  • 14
  • 1
    you asked for create a notification but i dont see you define a notification in your code? so what your purpose? – Chuong Le Van Apr 12 '20 at 03:09
  • Read up on https://developer.android.com/training/scheduling/alarms especially it's caveats and limitations. Also depending on your device manufacturer, they limit if and when Services are allowed to start. – JensV Apr 13 '20 at 10:43

1 Answers1

1

I recently had this problem and I solved mine using a broadcast receiver.

While the WakefulBroadcastReceiver has been deprecated, it's parent class has not been deprecated.

Intent intent = new Intent(context, ClassReminderReceiver.class);

  PendingIntent pendingIntent = PendingIntent.getBroadcast(
     context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
  AlarmManager alarmManager = (AlarmManager) 
     context.getSystemService(Context.ALARM_SERVICE);
  alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(), 
        AlarmManager.INTERVAL_DAY, pendingIntent);

I am using the Alarm manager setRepeating() and RTC_WAKEUP see Appropriate alarm type guide for appropriate alarm type

also, see the link below to see best practices on alarms. Best practices on alarms

You need to declare your broadcast receiver in your manifest

<receiver
        android:name=".ClassReminderReceiver"
        android:enabled="true"
        android:exported="true" />

This is the Broadcast receiver class

 public class ClassReminderReceiver extends BroadcastReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
      ClassReminderNotification.notify(context);
     }
  }

You said you want to create a notification, but as @Chuong Le Van mentioned I can't see where you define a notification in your code.

Below is the ClassNotification class

class ClassReminderNotification {

static void notify(Context context) {
    createNotificationChannel(context);
    // Create an explicit intent for an Activity in your app
    Intent intent = new Intent(context, YourActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);


    NotificationCompat.Builder builder = new NotificationCompat.Builder(context, 
          "class_reminder")
            .setSmallIcon(R.drawable.ic_school_black_24dp)
            .setContentTitle("Your Notification Title")
            .setContentText("Your Text")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            // Set the intent that will fire when the user taps the notification
            .setContentIntent(pendingIntent)
            .setAutoCancel(true);

    NotificationManagerCompat notificationManager = 
    NotificationManagerCompat.from(context);

    // notificationId is a unique int for each notification that you must define
    int notificationId = 1;
    notificationManager.notify(notificationId, builder.build());

}

private static void createNotificationChannel(Context context) {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is new and not in the support library
    String CHANNEL_ID = "class_reminder";
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = context.getString(R.string.channel_name);
        String description = context.getString(R.string.channel_description);
        int importance = NotificationManager.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, 
          importance);
        channel.setDescription(description);
        // Register the channel with the system; you can't change the importance
        // or other notification behaviors after this
        NotificationManager notificationManager = 
           context.getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
        }
    }
}

Here is google's guide Notification overviewNotifications Overview

Here is also the official guide for building a notification Official guide on how to create a notification.

I hope this helps.

Lone Wolf
  • 404
  • 3
  • 11