package com.junjunguo.pocketmaps.downloader; import com.junjunguo.pocketmaps.activities.MainActivity; import android.R; import android.annotation.TargetApi; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Build; import android.service.notification.StatusBarNotification; public class ProgressPublisher { Context c; int id; int notifyIntervalMS = 1000; long lastTime = System.currentTimeMillis(); public ProgressPublisher(Context c) { this.c = c; this.id = (int)(Math.random() * 100000.0); } public ProgressPublisher(Context c, int id) { this.c = c; this.id = id; } /** Set the minimum time for the next update notification. **/ public void setInterval(int notifyIntervalMS) { this.notifyIntervalMS = notifyIntervalMS; } /** Create message, or update text of message. * @param checkTime Check the interval time, update only when ok. * @param percent Will be appended to message. **/ public void updateText(boolean checkTime, String txt, int percent) { if (checkTime) { long curTime = System.currentTimeMillis(); long diffTime = curTime - lastTime; if (diffTime < notifyIntervalMS) { return; } lastTime = curTime; } updateNotification("PocketMaps", txt + ": " + percent + "%", true); } public void updateTextFinal(String txt) { if (Build.VERSION.SDK_INT >= 26) //OREO { updateTextFinalOrio(txt); } else { updateTextFinalInternal(txt); } } private void updateTextFinalInternal(String txt) { updateNotification("PocketMaps", txt, false); } private void updateNotification(String title, String text, boolean ongoing) { PendingIntent contentIntent = PendingIntent.getActivity(c, 0, new Intent(c, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); NotificationManager nMgr = (NotificationManager) c.getSystemService(Context.NOTIFICATION_SERVICE); Notification.Builder mBuilder = createNotification(c, nMgr).setSmallIcon(R.drawable.ic_dialog_info) .setContentTitle(title).setContentText(text).setContentIntent(contentIntent).setOngoing(ongoing); nMgr.notify(id, mBuilder.build()); } @SuppressWarnings("deprecation") private Notification.Builder createNotification(Context c, NotificationManager nMgr) { if (Build.VERSION.SDK_INT >= 26) //OREO { String sid = ProgressPublisher.class.getName(); NotificationChannel channel = new NotificationChannel(sid, "Pocketmaps", NotificationManager.IMPORTANCE_LOW); nMgr.createNotificationChannel(channel); return createNotificationOreo(c, sid); } return new Notification.Builder(c); } @TargetApi(26) //OREO private void updateTextFinalOrio(String txt) { // Crazy: Android is blocking when too much notification updates, so final message does not receive. Try later :( int sleepTime = 300; for (int i=0; i<10; i++) { updateTextFinalInternal(txt); NotificationManager nMgr = (NotificationManager) c.getSystemService(Context.NOTIFICATION_SERVICE); boolean found = false; for (StatusBarNotification n : nMgr.getActiveNotifications()) { if (n.getId() != id) { continue; } found = true; if (!n.isOngoing()) { return; } } if (!found) { return; } try { Thread.sleep(sleepTime); } catch (Exception e) {} sleepTime = (sleepTime/2) * 3; } } @TargetApi(26) //OREO private Notification.Builder createNotificationOreo(Context c, String sid) { return new Notification.Builder(c, sid); } }