tweaks to the download notifications (#260)

This commit is contained in:
Akinwale Ariwodola 2018-08-28 07:29:12 +01:00 committed by GitHub
parent e1e8fa410a
commit 050fc2b29e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -6,6 +6,7 @@ import android.app.PendingIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat;
@ -33,6 +34,8 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#"); private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#");
private static final int MAX_FILENAME_LENGTH = 20;
private static final int MAX_PROGRESS = 100; private static final int MAX_PROGRESS = 100;
private static final String GROUP_DOWNLOADS = "io.lbry.browser.GROUP_DOWNLOADS"; private static final String GROUP_DOWNLOADS = "io.lbry.browser.GROUP_DOWNLOADS";
@ -45,6 +48,8 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
public static final int GROUP_ID = 0; public static final int GROUP_ID = 0;
private static NotificationCompat.Builder groupBuilder = null;
public static boolean groupCreated = false; public static boolean groupCreated = false;
public DownloadManagerModule(ReactApplicationContext reactContext) { public DownloadManagerModule(ReactApplicationContext reactContext) {
@ -80,15 +85,16 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, GROUP_ID, intent, 0); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, GROUP_ID, intent, 0);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID); groupBuilder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
builder.setContentTitle("Active LBRY downloads") groupBuilder.setContentTitle("Active LBRY downloads")
.setContentText("Active LBRY downloads") // contentText will be displayed if there are no notifications in the group
.setSmallIcon(android.R.drawable.stat_sys_download) .setContentText("There are no active LBRY downloads.")
.setPriority(NotificationCompat.PRIORITY_LOW) .setSmallIcon(android.R.drawable.stat_sys_download)
.setGroup(GROUP_DOWNLOADS) .setPriority(NotificationCompat.PRIORITY_LOW)
.setGroupSummary(true) .setGroup(GROUP_DOWNLOADS)
.setDeleteIntent(pendingIntent); .setGroupSummary(true)
notificationManager.notify(GROUP_ID, builder.build()); .setDeleteIntent(pendingIntent);
notificationManager.notify(GROUP_ID, groupBuilder.build());
groupCreated = true; groupCreated = true;
} }
@ -102,7 +108,7 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
} }
@ReactMethod @ReactMethod
public void startDownload(String id, String fileName) { public void startDownload(String id, String filename) {
createNotificationChannel(); createNotificationChannel();
createNotificationGroup(); createNotificationGroup();
@ -110,34 +116,44 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID); NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
// The file URI is used as the unique ID // The file URI is used as the unique ID
builder.setContentIntent(getLaunchPendingIntent(id)) builder.setContentIntent(getLaunchPendingIntent(id))
.setContentTitle(String.format("Downloading %s...", fileName)) .setContentTitle(String.format("Downloading %s", truncateFilename(filename)))
.setGroup(GROUP_DOWNLOADS) .setGroup(GROUP_DOWNLOADS)
.setPriority(NotificationCompat.PRIORITY_LOW) .setPriority(NotificationCompat.PRIORITY_LOW)
.setProgress(MAX_PROGRESS, 0, false) .setProgress(MAX_PROGRESS, 0, false)
.setSmallIcon(android.R.drawable.stat_sys_download); .setSmallIcon(android.R.drawable.stat_sys_download);
int notificationId = generateNotificationId(); int notificationId = getNotificationId(id);
downloadIdNotificationIdMap.put(id, notificationId);
builders.put(notificationId, builder); builders.put(notificationId, builder);
notificationManager.notify(notificationId, builder.build()); notificationManager.notify(notificationId, builder.build());
if (groupCreated && groupBuilder != null) {
groupBuilder.setSmallIcon(android.R.drawable.stat_sys_download);
notificationManager.notify(GROUP_ID, groupBuilder.build());
}
} }
@ReactMethod @ReactMethod
public void updateDownload(String id, String fileName, double progress, double writtenBytes, double totalBytes) { public void updateDownload(String id, String filename, double progress, double writtenBytes, double totalBytes) {
if (!downloadIdNotificationIdMap.containsKey(id)) { int notificationId = getNotificationId(id);
return; if (notificationId == -1) {
}
int notificationId = downloadIdNotificationIdMap.get(id);
if (!builders.containsKey(notificationId)) {
return; return;
} }
createNotificationChannel(); createNotificationChannel();
createNotificationGroup(); createNotificationGroup();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
NotificationCompat.Builder builder = builders.get(notificationId);
NotificationCompat.Builder builder = null;
if (builders.containsKey(notificationId)) {
builder = builders.get(notificationId);
} else {
builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
builder.setContentTitle(String.format("Downloading %s", truncateFilename(filename)))
.setPriority(NotificationCompat.PRIORITY_LOW);
builders.put(notificationId, builder);
}
builder.setContentIntent(getLaunchPendingIntent(id)) builder.setContentIntent(getLaunchPendingIntent(id))
.setContentText(String.format("%.0f%% (%s / %s)", progress, formatBytes(writtenBytes), formatBytes(totalBytes))) .setContentText(String.format("%.0f%% (%s / %s)", progress, formatBytes(writtenBytes), formatBytes(totalBytes)))
.setGroup(GROUP_DOWNLOADS) .setGroup(GROUP_DOWNLOADS)
@ -145,13 +161,31 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
notificationManager.notify(notificationId, builder.build()); notificationManager.notify(notificationId, builder.build());
if (progress == MAX_PROGRESS) { if (progress == MAX_PROGRESS) {
builder.setContentTitle(String.format("Downloaded %s", fileName)) builder.setContentTitle(String.format("Downloaded %s", truncateFilename(filename, 30)))
.setContentText(String.format("%s", formatBytes(totalBytes))) .setContentText(String.format("%s", formatBytes(totalBytes)))
.setProgress(0, 0, false); .setGroup(GROUP_DOWNLOADS)
.setProgress(0, 0, false)
.setSmallIcon(android.R.drawable.stat_sys_download_done);
notificationManager.notify(notificationId, builder.build()); notificationManager.notify(notificationId, builder.build());
downloadIdNotificationIdMap.remove(id); if (downloadIdNotificationIdMap.containsKey(id)) {
builders.remove(notificationId); downloadIdNotificationIdMap.remove(id);
}
if (builders.containsKey(notificationId)) {
builders.remove(notificationId);
}
// If there are no more downloads and the group exists, set the icon to stop animating
if (groupCreated && groupBuilder != null && downloadIdNotificationIdMap.size() == 0) {
groupBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done);
notificationManager.notify(GROUP_ID, groupBuilder.build());
}
String spKey = String.format("dl__%s", id);
SharedPreferences sp = context.getSharedPreferences(MainActivity.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.remove(spKey);
editor.apply();
} }
} }
@ -179,7 +213,22 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
} }
} }
private String formatBytes(double bytes) private int getNotificationId(String id) {
String spKey = String.format("dl__%s", id);
SharedPreferences sp = context.getSharedPreferences(MainActivity.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
int notificationId = sp.getInt(spKey, -1);
if (notificationId == -1) {
notificationId = generateNotificationId();
SharedPreferences.Editor editor = sp.edit();
editor.putInt(spKey, notificationId);
editor.apply();
}
downloadIdNotificationIdMap.put(id, notificationId);
return notificationId;
}
private static String formatBytes(double bytes)
{ {
if (bytes < 1048576) { // < 1MB if (bytes < 1048576) { // < 1MB
return String.format("%s KB", DECIMAL_FORMAT.format(bytes / 1024.0)); return String.format("%s KB", DECIMAL_FORMAT.format(bytes / 1024.0));
@ -191,4 +240,24 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
return String.format("%s GB", DECIMAL_FORMAT.format(bytes / (1024.0 * 1024.0 * 1024.0))); return String.format("%s GB", DECIMAL_FORMAT.format(bytes / (1024.0 * 1024.0 * 1024.0)));
} }
private static String truncateFilename(String filename, int alternateMaxLength) {
int maxLength = alternateMaxLength > 0 ? alternateMaxLength : MAX_FILENAME_LENGTH;
if (filename.length() < maxLength) {
return filename;
}
// Get the extension
int dotIndex = filename.lastIndexOf(".");
if (dotIndex > -1) {
String extension = filename.substring(dotIndex);
return String.format("%s...%s", filename.substring(0, maxLength - extension.length() - 4), extension);
}
return String.format("%s...", filename.substring(0, maxLength - 3));
}
private static String truncateFilename(String filename) {
return truncateFilename(filename, 0);
}
} }