Android 本地通知不适用于三星 Galaxy
Posted
技术标签:
【中文标题】Android 本地通知不适用于三星 Galaxy【英文标题】:Android local notifications not working for samsung galaxy 【发布时间】:2019-02-10 07:07:54 【问题描述】:长期以来,我一直在为 android 上复杂的本地通知而苦苦挣扎。
我有一个事件列表。用户可以选择何时收到通知:
活动当天 活动开始前一天 活动开始前两天他/她还可以设置他/她想要得到通知的时间。每一次都是可能的。他/她也只能收到不同类型事件的通知。
实际情况是,它适用于除三星 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();
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 的时候。但是我再也找不到这个的来源了......
【问题讨论】:
要取消PendingIntent
,您不需要完全重新创建它。您需要创建一个 PendingIntent
对象,该对象具有相同的 requestCode 和 same Intent with extras 并带有标志 FLAG_NO_CREATE
。如果这样的PendingIntent
不存在,则该对象将为空,并且仅当它为非空时才需要取消它。如果我误解了你并且你做了同样的事情,我很抱歉。
请把偶数课也分享一下,谢谢。
【参考方案1】:
我在三星设备上也遇到了类似的问题,这就是我所做的:
考虑一下:
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)
。它也适用于三星设备。
【讨论】:
【参考方案2】:工作正常,在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")
可能会有所帮助!
【讨论】:
【参考方案3】:我过去浏览过一个相关问题,它发生在 Galaxy Note 上,虽然我不确定它是否会有所帮助。
mNotificationManager.cancel(notificationId);
mNotificationManager.notify(++notificationId, notification);
每次必须创建新通知时,手动取消之前的通知,并且每次都更新 notificationID。
【讨论】:
以上是关于Android 本地通知不适用于三星 Galaxy的主要内容,如果未能解决你的问题,请参考以下文章
三星 Galaxy S3 Android 浏览器上的 Web 套接字?
Android phonegap 应用程序在三星 Galaxy 设备上存在 SQlite 和本地存储问题
Android 应用无法在三星 Galaxy 应用上提交(如何包含三星 SDK?)