0

I've got a service which setups an AlarmManager as shown:

private void setupInsuranceNotification(@NonNull String plate, @NonNull LocalDate insuranceDeadline)
    {
        LocalDate now = LocalDate.now();
        int daysToDeadline = getDaysBetweenDates(now, insuranceDeadline);
        String notificationTitle = "Assicurazione " + plate;
        String notificationMessage;
        int millsBetweenNotifications = 1000 * 60 * 60 * 24; // 1 day default
        LocalDate notificationStart = now;

        if (daysToDeadline > 0)
        {
            notificationMessage = daysToDeadline + " giorni alla scadenza.";

            if (daysToDeadline > 30)
            {
                // show the notification only when they are 30 days left
                notificationStart = now.withFieldAdded(DurationFieldType.days(), daysToDeadline - 30);
            }
        }
        else if (daysToDeadline == 0)
        {
            notificationMessage = "Assicurazione scaduta oggi.";
        }
        else
        {
            if (daysToDeadline >= -15)
            {
                // tolerance period
                notificationMessage = Math.abs(daysToDeadline) + " alla fine del periodo di tolleranza!";
                millsBetweenNotifications = 1000 * 60 * 60 * 6; // 6 hours
            }
            else
            {
                // insurance expired
                notificationMessage = "Periodo di tolleranza finito! L'assicurazione è scaduta!";
                millsBetweenNotifications = 1000 * 60 * 60; // 1 hour
            }
        }

        Intent notificationIntent = new Intent(this, NotificationPublisher.class);
        notificationIntent.putExtra("notification_title", notificationTitle);
        notificationIntent.putExtra("notification_message", notificationMessage);
        PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, notificationStart.toDate().getTime(), millsBetweenNotifications, alarmIntent);
    }

this is my NotificationPublisher class:

public class NotificationPublisher extends BroadcastReceiver
{
    private static final int NOTIFICATION_ID = 1;

    @Override
    public void onReceive(Context context, Intent intent)
    {
        String title = intent.getStringExtra("notification_title");
        String message = intent.getStringExtra("notification_message");
        Notification.Builder builder = new Notification.Builder(context);
        NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        builder.setContentTitle(title);
        builder.setContentText(message);
        builder.setSmallIcon(R.drawable.ic_notification);
        manager.notify(NOTIFICATION_ID, builder.build());
    }
}

My problem is that the setupInsuranceNotification is correctly executed untill the end (there isn't any exception), but my NotificationPublisher is never fired (I've put a breakpoint on in to check).

EDIT

this is my onHandleIntent from NotificationService class:

@Override
    protected void onHandleIntent(@Nullable Intent intent)
    {
        Debug.waitForDebugger();

        if (Utilities.vehicleFileExists(this))
        {
            try
            {
                DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
                Document doc = dBuilder.parse(Utilities.getVehicleListFile(this));
                Element root = doc.getDocumentElement();

                root.normalize();

                NodeList vehicleNodeList = root.getElementsByTagName("vehicle");

                for (int i = 0; i < vehicleNodeList.getLength(); i++)
                {
                    Element vehicleElement = (Element) vehicleNodeList.item(i);
                    Element matriculationDateElement = (Element) vehicleElement.getFirstChild();
                    Element endInsuranceDateElement = (Element) matriculationDateElement.getNextSibling();
                    Element lastInspectionDateElement = (Element) endInsuranceDateElement.getNextSibling();

                    String plate = vehicleElement.getAttribute("plate");
                    LocalDate matriculationDate = LocalDate.parse(matriculationDateElement.getFirstChild().getNodeValue(), DateTimeFormat.forPattern(Utilities.Formats.Date.ITALIAN));
                    LocalDate endInsuranceDate = LocalDate.parse(endInsuranceDateElement.getFirstChild().getNodeValue(), DateTimeFormat.forPattern(Utilities.Formats.Date.ITALIAN));
                    LocalDate lastInspectionDate = null;

                    if (lastInspectionDateElement.getFirstChild() != null) // <inspection_dates/>
                    {
                        lastInspectionDate = LocalDate.parse(lastInspectionDateElement.getFirstChild().getNodeValue(), DateTimeFormat.forPattern(Utilities.Formats.Date.ITALIAN));
                    }

                    LocalDate inspectionDeadline = getInspectionDeadline(matriculationDate, lastInspectionDate);

                    setupInsuranceNotification(plate, endInsuranceDate);
                    setupInspectionNotification(plate, inspectionDeadline);
                }
            }
            catch (ParserConfigurationException | SAXException | IOException ignored) {}
        }
    }
  • Have you registerd the receiver in the Manifest? – MatPag May 30 '17 at 15:07
  • @MatPag yes: ` ` –  May 30 '17 at 15:10
  • You should try to replace your AlarmManager code with this one [here](https://stackoverflow.com/a/31838628/2910520) and see if it works. In this way we can say for sure that the problem is the Intent or the AlarmManager of your code and not something else – MatPag May 30 '17 at 15:36
  • @MatPag I've tried that and I've noticed one thing: my `setupInsuranceNotification` method is called in a for loop, but my `NotificationPublisher` is fired only one time, for the last iteration –  May 30 '17 at 15:45
  • That's because the system will group all the notifications togheter. Starting from API 19 even if you use `setRepeating` the system will change it to `setInexactRepeating` to save user battery life. You should avoid firing so many broadcasts in a `for loop` – MatPag May 30 '17 at 15:53
  • Can you please post more code? from where `setupInsuranceNotification()` being called? – Ferdous Ahamed May 30 '17 at 15:56
  • @MatPag so what can I do? I need to send to user a notification for each `insuranceDate` deadline –  May 30 '17 at 16:30
  • @FAT I've edited my post –  May 30 '17 at 16:30
  • your `NotificationPublisher` fired only once.. am I right? – Ferdous Ahamed May 30 '17 at 16:50
  • @FAT yes, you're right, only on the last iteration, but if there are 8 `insuranceDate`s which are about to the deadline, l want to show 8 notification –  May 30 '17 at 17:09

1 Answers1

0

Your NotificationPublisher is fired only for last iteration because of same requestCode that you used in alarm PendingIntent.

As you are using requestCode as 0 for all alarm, its just overrides the previous alarm data. That's why only for last alarm your NotificationPublisher's onReceive() executed.

SOLUTION:

Use different REQUEST_CODE for different alarm PendingIntent.

PendingIntent alarmIntent = PendingIntent.getBroadcast(this, REQUEST_CODE, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Hope this will help~

Ferdous Ahamed
  • 21,438
  • 5
  • 52
  • 61
  • thank you very much, I've understood where the problem was :) but I have another question: I've resolved the problem in (I think) a brutal way, using `Random` to generate random ids. Is it correct? And then, is there another smart way to sent a group of notifications? –  May 30 '17 at 18:35
  • I think there is no other way. The main thing is your have to set unique request code for each alarm. For making multiple alarm you should use looping technique. – Ferdous Ahamed May 30 '17 at 18:39
  • If there is no possibility to trigger multiple alarm at same time, then you can create a single alarm with repetition instead of creating multiple alarm. Hope you understand :) – Ferdous Ahamed May 30 '17 at 18:41
  • If my answer helps and seems useful then please mark it as right answer. Thanks in advance :) – Ferdous Ahamed May 30 '17 at 18:53