Search code examples
javaandroidandroid-notifications

My notification is only working when the app is opened


So, i have an application that every hour checks a text file for changes. If it finds changes it needs to give a push notification. But when i test the app for a day it only works the first time. Every other time it only inmediatly happens when i open the application. My curent code is as follows:

Main activity:

on create

notificationManager = NotificationManagerCompat.from(this);

        // sets time for when to notify/ check for rescheduling.
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 20);
        calendar.set(Calendar.MINUTE, 01);
        calendar.set(Calendar.SECOND, 00);

        setAlarm(calendar);

set alarm

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private void setAlarm(Calendar calendar) {

        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(this, AlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);

        alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
    }

AlarmReceiver:

public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        NotificationHelper notificationHelper = new NotificationHelper(context);
        NotificationCompat.Builder nb = notificationHelper.getChannelNotification();
        notificationHelper.getManager().notify(1, nb.build());
    }
}

NotificationHelper:

public class NotificationHelper extends ContextWrapper {
    public static final String channelID = "Chanel1";
    public static final String channelName = "Probably change";

    private NotificationManager mManager;

    public NotificationHelper(Context base) {
        super(base);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createChannel();
        }
    }

    @TargetApi(Build.VERSION_CODES.O)
    private void createChannel() {
        NotificationChannel channel1 = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
        channel1.enableLights(true);
        channel1.setLightColor(R.color.colorPrimary);
        channel1.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        channel1.setImportance(NotificationManager.IMPORTANCE_HIGH);

        getManager().createNotificationChannel(channel1);
    }

    public NotificationManager getManager() {
        if (mManager == null) {
            mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        }

        return mManager;
    }

    public NotificationCompat.Builder getChannelNotification(){
        return new NotificationCompat.Builder(getApplicationContext(), channelID)
                .setContentTitle("Schedule change")
                .setContentText("There is probably a change in schedule for your class.")
                .setSmallIcon(R.drawable.ic_launcher_foreground);
    }
}

Solution

  • For a more modern approach, you probably really want to use JobScheduler rather than AlarmManager. But either can be made to work.

    The big thing I see is that you call AlarmManager.setExact. That will schedule the alarm to happen once, and only once. If you want it to happen every hour you either need to call setRepeating, or you need to call setExact again to set a new alarm in your alarm handler.