![](/img/trans.png)
[英]How to send data to Firebase continuously avoiding Doze and App Standby
[英]How to show notifications EVEN when phone is in Doze or app is in App Standby mode?
我正在構建一個應用程序,它應該提醒用戶他們設置的即將發生的事件(基本上是提醒)。 我正在遇到的問題是當應用程序暫時沒有被使用(大約15分鍾或更長時間)時,將通知推送到用戶的手機(僅限API 26+); 根本不顯示通知。
我讀到了這一點並意識到App Standby和Doze模式可能會阻止我的應用程序推送此類通知; 用戶在運行API 25及更低版本的手機上按預期收到我的通知。 為了解決這個問題,我嘗試使用AlarmManager.setExactAndAllowWhileIdle(),但問題仍然存在。
class TaskNotifications {
private AlarmManager alarmManager;
private Context c;
TaskNotifications(Context context) {
this.c = context;
this.alarmManager = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
}
void setReminder(Context context, Task task) {
if (VERSION.SDK_INT < Build.VERSION_CODES.O) {
long reminderMilliseconds = task.getReminderMilliseconds();
if (reminderMilliseconds > Calendar.getInstance().getTimeInMillis() && !task.isDone()) {
Intent intent = new Intent(context, NotificationReceiver.class);
intent.putExtra("ID", task.getID());
intent.putExtra("TITLE", task.getTitle());
intent.putExtra("DETAILS", task.getDetails());
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, task.getID(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
if (VERSION.SDK_INT >= 23) {
this.alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, reminderMilliseconds, pendingIntent);
} else
this.alarmManager.setExact(AlarmManager.RTC_WAKEUP, reminderMilliseconds, pendingIntent);
}
}
}
void cancelReminder(Task task) {
if (VERSION.SDK_INT < Build.VERSION_CODES.O) {
this.alarmManager.cancel(PendingIntent.getBroadcast(this.c, task.getID(),
new Intent(this.c, NotificationReceiver.class), PendingIntent.FLAG_CANCEL_CURRENT));
}
}
}
public class NotificationReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Intent startIntent = new Intent(context, NotificationJobIntentService.class);
startIntent.putExtra("ID", intent.getIntExtra("ID", -1));
startIntent.putExtra("TITLE", intent.getStringExtra("TITLE"));
startIntent.putExtra("DETAILS", intent.getStringExtra("DETAILS"));
JobIntentService.enqueueWork(context, NotificationJobIntentService.class, intent.getIntExtra("ID", -1), startIntent);
}
}
public class NotificationJobIntentService extends JobIntentService {
private String CHANNEL_ID = getResources().getString(R.string.channel_name);
protected void onHandleWork(@NonNull Intent intent) {
createNotificationChannel(NotificationJobIntentService.this);
int NOTIFICATION_ID = intent.getIntExtra("ID", -1);
String GROUP = "NOTIFICATION_GROUP";
String title = intent.getStringExtra("TITLE");
if (title.isEmpty())
title = getResources().getString(R.string.no_title);
String details = intent.getStringExtra("DETAILS");
if (details.isEmpty())
details = getResources().getString(R.string.no_details);
Intent openAppIntent = new Intent(NotificationJobIntentService.this, MainActivity.class);
TaskStackBuilder create = TaskStackBuilder.create(this);
create.addNextIntentWithParentStack(openAppIntent);
NotificationCompat.Builder builder = new NotificationCompat.Builder(NotificationJobIntentService.this, this.CHANNEL_ID)
.setContentTitle(title)
.setContentText(details)
.setSmallIcon(R.drawable.baseline_alarm_black_18)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setContentIntent(create.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT))
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setGroup(GROUP)
.setAutoCancel(true)
.setColor(Color.argb(100, 0, 87, 75))
.setVibrate(new long[]{1000, 1000})
.setLights(Color.GREEN, PathInterpolatorCompat.MAX_NUM_POINTS, PathInterpolatorCompat.MAX_NUM_POINTS)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM));
NotificationManagerCompat.from(this).notify(NOTIFICATION_ID, builder.build());
}
private void createNotificationChannel(Context context) {
if (VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence string = context.getString(R.string.channel_name);
String description = context.getString(R.string.channel_description);
NotificationChannel notificationChannel = new NotificationChannel(this.CHANNEL_ID, string, NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setDescription(description);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.GREEN);
notificationChannel.enableVibration(true);
notificationChannel.setVibrationPattern(new long[]{1000, 1000});
(context.getSystemService(NotificationManager.class)).createNotificationChannel(notificationChannel);
}
}
}
有沒有可靠的方法讓我向運行API 26+的用戶手機發送准確/稍微確切的通知? 或者我的代碼中是否有錯誤,我沒有注意到?
我無法使通知系統在API 26+設備上運行,但是,我使用Android日歷提供程序提醒將事件添加到用戶日歷,然后通過默認日歷設置提醒...不是我原來想要的,但它是一種創可貼解決方案。
如果有人仍能按預期解決問題,請告訴我。
代碼如下:
if (task.getEventID() > 0) {
//Remove existing events for this task
ContentResolver cr = c.getContentResolver();
int iNumRowsDeleted;
Uri eventUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, task.getEventID());
iNumRowsDeleted = cr.delete(eventUri, null, null);
Log.i("removeEvent()", "Deleted " + iNumRowsDeleted + " calendar entry.");
}
try {
//Add an event
ContentResolver cr = context.getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, task.getCal().getTimeInMillis());
values.put(CalendarContract.Events.DTEND, task.getCal().getTimeInMillis()+60*60*1000);//Each task a duration of 60 minutes
values.put(CalendarContract.Events.TITLE, task.getTitle() + " - " + task.getDetails());
values.put(CalendarContract.Events.CALENDAR_ID, getPrimaryCalendar());
values.put(CalendarContract.Events.EVENT_TIMEZONE, Calendar.getInstance().getTimeZone().getID());
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
// Save the eventId into the Task object for possible future delete.
task.setEventID(Integer.parseInt(uri.getLastPathSegment()));
Log.i("addEvent()","The event id is " + task.getEventID());
// Add a reminder
ContentValues valuesR = new ContentValues();
valuesR.put(CalendarContract.Reminders.MINUTES, (task.getCal().getTimeInMillis() - reminderMilliseconds)/(1000*60));
valuesR.put(CalendarContract.Reminders.EVENT_ID, task.getEventID());
valuesR.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT); /*The alarm method, as set on the server. METHOD_DEFAULT, METHOD_ALERT, METHOD_EMAIL, METHOD_SMS and METHOD_ALARM are possible values; the device will only process METHOD_DEFAULT and METHOD_ALERT reminders (the other types are simply stored so we can send the same reminder info back to the server when we make changes).*/
Uri uriR = cr.insert(CalendarContract.Reminders.CONTENT_URI, valuesR);
Cursor c = CalendarContract.Reminders.query(cr, task.getEventID(), new String[]{CalendarContract.Reminders.MINUTES});
if (c.moveToFirst()) {
Log.i("setReminder()",task.toString());
Log.i("setReminder()","calendar has reminder at " + c.getInt(c.getColumnIndex(CalendarContract.Reminders.MINUTES)));
}
c.close();
} catch (Exception e) {
e.printStackTrace();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.