Android本地通知不适用于三星银河

时间:2018-09-05 07:58:03

标签: java android android-notifications samsung-galaxy

很长一段时间以来,我一直在努力处理复杂的本地通知。

我有一个活动列表。用户可以选择何时通知他/她:事件的同一天,事件将开始的前一天,事件将开始的前两天。他/她还可以设置他/她想要得到通知的时间。每次都有可能。他/她还只能通过不同类型的事件得到通知。

发生的事情是,它可以在除Samsung Galaxy Phones之外的所有设备上正常工作。用户告诉我,他们收到通知的时间恰好是一次(设置时),然后再也不会收到。

我几乎尝试了所有事情,但我的想法已用尽。三星似乎在通知方面存在一些问题,但适用于其他一些应用程序。那么他们的代码和我的代码有什么区别。

也许其他人知道此问题,可以为我提供帮助。这太神奇了!

这是我的代码:

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");
    }
}
}

我曾经有机会在三星手机上运行它,我想我还记得因为手机无法更新通知而引发了某种SecurityException。只能容纳500条通知,如果尝试对其进行更新,则不会删除旧的通知,而会创建新的通知。因此,您很快就会收到500个通知,这就是抛出SecurityException的时候。但是我再也找不到源了...

3 个答案:

答案 0 :(得分:1)

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

mNotificationManager.cancel(notificationId);
mNotificationManager.notify(++notificationId, notification);

每次必须创建一个新通知时,请手动取消前一个通知,并每次都更新notificationID。

答案 1 :(得分:0)

它工作正常,已在Samsung Galaxy s7 edge上进行了测试

fun showDownloadNotification() {
        try {
            // val selectedUri = Uri.parse(Environment.getExternalStorageState())
            val notiIntent = Intent(DownloadManager.ACTION_VIEW_DOWNLOADS)
            notiIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            //            startActivity(intent);
            val pendingIntent: PendingIntent = PendingIntent.getActivity(baseActivity, 0, notiIntent, PendingIntent.FLAG_CANCEL_CURRENT)
            val builder = NotificationCompat.Builder(baseActivity, "")
                    .setSmallIcon(notificationIcon)
                    .setContentTitle("Subject Topic downloaded")
                    .setContentText(fileName)
                    .setAutoCancel(true)
                    .setContentIntent(pendingIntent)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            val notificationManager: NotificationManagerCompat = NotificationManagerCompat.from(baseActivity)

            // notificationId is a unique int for each notification that you must define
            notificationManager.notify(1, builder.build())
        } catch (e: Exception) {
            // Log.e(FragmentActivity.TAG, "Notification $e")
        }
    }

可能会有所帮助!

答案 2 :(得分:0)

我在三星设备上也遇到了类似的问题,这就是我所做的:

考虑这一点:

 builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);

在上面的行中,我们通过了NOTIFICATION_CHANNEL_ID

现在在代码的后面还会添加:

builder.setChannelId(NOTIFICATION_CHANNEL_ID)     // don't call this method

我们已经通过构造函数将通道ID提供给了构建器,我们无需再次传递它。删除builder.setChannelId(NOTIFICATION_CHANNEL_ID)。它也将在三星设备上工作。