Локальные уведомления Android не работают для Samsung Galaxy - PullRequest
0 голосов
/ 05 сентября 2018

Я уже давно борюсь со сложными локальными уведомлениями на Android.

У меня есть список событий. Пользователь может выбрать, когда он / она хотели бы получать уведомления: в тот же день мероприятия, за один день до его начала, за два дня до его начала. Он / она также может установить время, когда он / она хочет получать уведомления. Каждый раз возможно. Он / она также может получать уведомления только о различных типах событий.

Что происходит, так это то, что он отлично работает со всеми устройствами, кроме телефонов Samsung Galaxy. Пользователи сказали мне, что они получают уведомление ровно один раз (когда они их настраивают), а затем никогда больше.

Я перепробовал почти все, у меня заканчиваются идеи. Похоже, у Samsung есть некоторые проблемы с уведомлениями, но это работает для некоторых других приложений. Так в чем же разница между их кодом и моим.

Может быть, кто-то еще знает эту проблему и может помочь мне. Это было бы так удивительно!

А вот и мой код:

public int setEventNotifications(List<Event> chosenEvents) {

    SharedPreferences settings = context.getSharedPreferences(Constants.PREFS_EVENT_SETTINGS, 0);

    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    ArrayList<PendingIntent> intentArray = new ArrayList<>();

    // To cancel an existing pending intent you need to recreate the exact same and cancel it -__-
    // So pending intents need to be stored in the database
    deleteOldGarbagePendingIntents();

    // get notification settings from shared prefs

    int hours = 0;
    int minutes = 0;

    String time = settings.getString(Constants.PREFS_EVENT_TIME, "00:00");
    String parts[] = time.split(":");

    try {
        hours = Integer.parseInt(parts[0]);
        minutes = Integer.parseInt(parts[1]);
    } catch (Exception e) {
        Log.e(TAG, "Invalid time. Cannot be parsed: " + time);
    }

    String interval = settings.getString(Constants.PREFS_EVENT_INTERVAL, "");

    String communeId = settings.getString(Constants.PREFS_EVENT_COMMUNE_ID, "");
    String regionId = settings.getString(Constants.PREFS_EVENT_REGION_ID, "");

    for (Event event : chosenEvents) {
        // check if date is in the future

        Intent intent = new Intent(context, AlarmGarbageReceiver.class);
        intent.putExtra("request_code", Integer.parseInt(event.getId()));
        intent.putExtra("event_type", event.getGarbageType().getType());
        intent.putExtra("event_date", event.getPickupDateAsDate().getTime());

        // calculate trigger time
        long triggerTime = calculateTriggerTime(event.getPickupDateAsDate(), hours, minutes, interval);
        Calendar alarmCalendar = Calendar.getInstance();
        alarmCalendar.setTimeInMillis(triggerTime);

        try {
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, Integer.parseInt(event.getId()), intent, FLAG_UPDATE_CURRENT);

            if (alarmManager != null) {
                alarmManager.set(AlarmManager.RTC_WAKEUP, alarmCalendar.getTimeInMillis(), pendingIntent);
            } else {
                Log.e(TAG, "Alarmmanager is null");
            }

            intentArray.add(pendingIntent);

            // save intents in database
            dbHelper.insertEventData(event.getId(), event.getEventType().getType(), String.valueOf(event.getPickupDateAsDate().getTime()), event.getLocation(), event.getEventType().getColor(), communeId, regionId);
        } catch (SecurityException securityException) {
            Log.e(TAG, "Security Exception");
            securityException.printStackTrace();
        } catch (Exception exception) {
            Log.e(TAG, "Exception");
            exception.printStackTrace();
        }
    }

    return intentArray.size();
}

Класс AlarmEventReceiver:

public class AlarmEventReceiver extends BroadcastReceiver {

private static final String NOTIFICATION_CHANNEL_NAME = "xxx_events";
private static final String NOTIFICATION_CHANNEL_ID = "xxx_events_1";

@Override
public void onReceive(Context context, Intent intent) {
    if(intent.getExtras() != null) {
        Log.e(TAG, AlarmEventReceiver.class.getSimpleName() + " request code: " + intent.getExtras().getInt("request_code"));
    }

    int eventId = intent.getExtras().getInt("request_code");
    String eventType = intent.getExtras().getString("event_type");
    long pickupDate = intent.getExtras().getLong("event_date");

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(pickupDate);
    calendar.set(Calendar.HOUR, 6);
    calendar.set(Calendar.MINUTE, 0);

    long finalDate = calendar.getTimeInMillis();

    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    NotificationCompat.Builder builder;

    Intent resultIntent = new Intent(context, EventCalendarActivity.class);
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    stackBuilder.addParentStack(EventCalendarActivity.class);
    stackBuilder.addNextIntent(resultIntent);
    PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

    if (notificationManager == null) {
        notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    }

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);

        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
        notificationChannel.enableVibration(true);
        notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});

        if (notificationManager != null) {
            notificationManager.createNotificationChannel(notificationChannel);
        } else {
            Log.e(TAG, "Notification Manager is NULL");
        }

        if (eventType != null) {
            builder.setChannelId(NOTIFICATION_CHANNEL_ID)
                    .setDefaults(Notification.DEFAULT_ALL)
                    .setContentTitle("Erinnerung")
                    .setContentText(eventType)
                    .setWhen(finalDate)
                    .setContentIntent(resultPendingIntent)
                    .setAutoCancel(false)
                    .setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
        }
    } else {
        builder = new NotificationCompat.Builder(context);
        builder.setContentTitle("Erinnerung")
                .setDefaults(Notification.DEFAULT_ALL)
                .setContentText(eventType)
                .setWhen(finalDate)
                .setContentIntent(resultPendingIntent)
                .setAutoCancel(false)
                .setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400})
                .setPriority(Notification.PRIORITY_DEFAULT);

    }

    Notification notification = builder.build();
    if (notificationManager != null) {
        notificationManager.notify(eventId, notification);
    } else {
        Log.e(TAG, "notificationManager is NULL");
    }
}
}

Однажды у меня была возможность запустить его на телефоне Samsung, и я думаю, что помню, что возникло какое-то исключение SecurityException, потому что телефон не смог обновить уведомления. Было только 500 уведомлений, и если попытаться обновить их, старые не будут удалены, а будут созданы новые. Поэтому вы достаточно быстро получаете 500 уведомлений, и тогда возникает исключение SecurityException. Но я больше не могу найти источник для этого ...

...