java - Android 本地通知不适用于三星 Galaxy

标签 java android android-notifications samsung-galaxy

很长一段时间以来,我一直在为 Android 上复杂的本地通知而苦苦挣扎。
我有一个事件列表。用户可以选择何时收到通知:

  • Activity 当天
  • Activity 开始前一天
  • Activity 开始前两天

  • 他/她还可以设置他/她想要得到通知的时间。每一次都是可能的。他/她也只能通过不同类型的事件获得通知。
    发生的情况是,它适用于除三星 Galaxy 手机之外的所有设备。用户告诉我,他们只会收到一次通知(当他们设置它们时),然后就再也不会收到了。
    我几乎尝试了一切,我的想法已经不多了。三星似乎在通知方面存在一些问题,但它适用于其他一些应用程序。那么他们的代码和我的代码有什么区别。
    也许其他人知道这个问题并且可以帮助我。这将是如此惊人!
    这是我的代码:
    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();
    }
    
    警报事件接收器类:
    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");
        }
    }
    }
    
    我曾经有机会在三星手机上运行它,我想我记得由于手机无法更新通知而引发了某种 SecurityException。只有 500 个通知的容量,如果尝试更新它们,旧的不会被删除,但会创建新的。因此,您很快就会收到 500 个通知,这就是引发 SecurityException 的时候。但是我再也找不到这个的来源了......

    最佳答案

    我过去浏览过一个相关问题,它发生在 Galaxy Note 上,但我不确定它是否会有所帮助。

    mNotificationManager.cancel(notificationId);
    mNotificationManager.notify(++notificationId, notification);
    
    每次必须创建新通知时,手动取消前一个通知并每次更新通知ID。

    关于java - Android 本地通知不适用于三星 Galaxy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52180013/

    相关文章:

    java - 在 Java 中,对于单行上的多个整数使用 BufferedReader 而不是 Scanner Class 是最佳选择吗?

    java - Maven 使用错误版本的 android 进行编译

    java - 无法解析方法'show(android.support.v4.app.FragmentManager, java.lang.String)

    android - whatsapp/telegram 如何确保来电通知?

    android - 如何在自定义通知 TextView 中设置值

    android - 服务被系统自动杀死时取消Android通知

    java - 获取泛型类型或泛型实例的类

    java - 使用java从sql排序?

    java - 如何访问LinkedHashMap内部的链表?

    java - Android:将字节数组转换为整数数组