Extracted notification from DownloadService
This commit is contained in:
parent
056d7db16b
commit
798868db9c
|
@ -98,10 +98,8 @@ public class DownloadService extends Service {
|
|||
|
||||
private DownloadRequester requester;
|
||||
|
||||
|
||||
private NotificationCompat.Builder notificationCompatBuilder;
|
||||
private static final int NOTIFICATION_ID = 2;
|
||||
private static final int REPORT_ID = 3;
|
||||
private DownloadServiceNotification notificationManager;
|
||||
public static final int NOTIFICATION_ID = 2;
|
||||
|
||||
/**
|
||||
* Currently running downloads.
|
||||
|
@ -169,7 +167,7 @@ public class DownloadService extends Service {
|
|||
numberOfDownloads.decrementAndGet();
|
||||
if (!status.isCancelled()) {
|
||||
if (status.getReason() == DownloadError.ERROR_UNAUTHORIZED) {
|
||||
postAuthenticationNotification(downloader.getDownloadRequest());
|
||||
notificationManager.postAuthenticationNotification(downloader.getDownloadRequest());
|
||||
} else if (status.getReason() == DownloadError.ERROR_HTTP_DATA_ERROR
|
||||
&& Integer.parseInt(status.getReasonDetailed()) == 416) {
|
||||
|
||||
|
@ -288,9 +286,11 @@ public class DownloadService extends Service {
|
|||
});
|
||||
feedSyncThread.start();
|
||||
|
||||
setupNotificationBuilders();
|
||||
requester = DownloadRequester.getInstance();
|
||||
startForeground(NOTIFICATION_ID, updateNotifications());
|
||||
notificationManager = new DownloadServiceNotification(this);
|
||||
Notification notification = notificationManager.updateNotifications(
|
||||
requester.getNumberOfDownloads(), downloads);
|
||||
startForeground(NOTIFICATION_ID, notification);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -303,9 +303,10 @@ public class DownloadService extends Service {
|
|||
Log.d(TAG, "Service shutting down");
|
||||
isRunning = false;
|
||||
|
||||
if (ClientConfig.downloadServiceCallbacks.shouldCreateReport() &&
|
||||
UserPreferences.showDownloadReport()) {
|
||||
updateReport();
|
||||
if (ClientConfig.downloadServiceCallbacks.shouldCreateReport()
|
||||
&& UserPreferences.showDownloadReport()) {
|
||||
notificationManager.updateReport(reportQueue);
|
||||
reportQueue.clear();
|
||||
}
|
||||
|
||||
postHandler.removeCallbacks(postDownloaderTask);
|
||||
|
@ -334,40 +335,6 @@ public class DownloadService extends Service {
|
|||
DBTasks.autodownloadUndownloadedItems(getApplicationContext());
|
||||
}
|
||||
|
||||
private void setupNotificationBuilders() {
|
||||
notificationCompatBuilder = new NotificationCompat.Builder(this, NotificationUtils.CHANNEL_ID_DOWNLOADING)
|
||||
.setOngoing(true)
|
||||
.setContentIntent(ClientConfig.downloadServiceCallbacks.getNotificationContentIntent(this))
|
||||
.setSmallIcon(R.drawable.stat_notify_sync);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
notificationCompatBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
}
|
||||
|
||||
Log.d(TAG, "Notification set up");
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the contents of the service's notifications. Should be called
|
||||
* after setupNotificationBuilders.
|
||||
*/
|
||||
private Notification updateNotifications() {
|
||||
if (notificationCompatBuilder == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String contentTitle = getString(R.string.download_notification_title);
|
||||
int numDownloads = requester.getNumberOfDownloads();
|
||||
String downloadsLeft = (numDownloads > 0) ?
|
||||
getResources().getQuantityString(R.plurals.downloads_left, numDownloads, numDownloads) :
|
||||
getString(R.string.downloads_processing);
|
||||
String bigText = compileNotificationString(downloads);
|
||||
|
||||
notificationCompatBuilder.setContentTitle(contentTitle);
|
||||
notificationCompatBuilder.setContentText(downloadsLeft);
|
||||
notificationCompatBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText));
|
||||
return notificationCompatBuilder.build();
|
||||
}
|
||||
|
||||
private Downloader getDownloader(String downloadUrl) {
|
||||
for (Downloader downloader : downloads) {
|
||||
if (downloader.getDownloadRequest().getSource().equals(downloadUrl)) {
|
||||
|
@ -502,55 +469,6 @@ public class DownloadService extends Service {
|
|||
DBWriter.addDownloadStatus(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a notification at the end of the service lifecycle to notify the
|
||||
* user about the number of completed downloads. A report will only be
|
||||
* created if there is at least one failed download excluding images
|
||||
*/
|
||||
private void updateReport() {
|
||||
// check if report should be created
|
||||
boolean createReport = false;
|
||||
int successfulDownloads = 0;
|
||||
int failedDownloads = 0;
|
||||
|
||||
// a download report is created if at least one download has failed
|
||||
// (excluding failed image downloads)
|
||||
for (DownloadStatus status : reportQueue) {
|
||||
if (status.isSuccessful()) {
|
||||
successfulDownloads++;
|
||||
} else if (!status.isCancelled()) {
|
||||
createReport = true;
|
||||
failedDownloads++;
|
||||
}
|
||||
}
|
||||
|
||||
if (createReport) {
|
||||
Log.d(TAG, "Creating report");
|
||||
// create notification object
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NotificationUtils.CHANNEL_ID_ERROR)
|
||||
.setTicker(getString(R.string.download_report_title))
|
||||
.setContentTitle(getString(R.string.download_report_content_title))
|
||||
.setContentText(
|
||||
String.format(
|
||||
getString(R.string.download_report_content),
|
||||
successfulDownloads, failedDownloads)
|
||||
)
|
||||
.setSmallIcon(R.drawable.stat_notify_sync_error)
|
||||
.setContentIntent(
|
||||
ClientConfig.downloadServiceCallbacks.getReportNotificationContentIntent(this)
|
||||
)
|
||||
.setAutoCancel(true);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
}
|
||||
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nm.notify(REPORT_ID, builder.build());
|
||||
} else {
|
||||
Log.d(TAG, "No report is created");
|
||||
}
|
||||
reportQueue.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls query downloads on the services main thread. This method should be used instead of queryDownloads if it is
|
||||
* used from a thread other than the main thread.
|
||||
|
@ -570,32 +488,12 @@ public class DownloadService extends Service {
|
|||
stopSelf();
|
||||
} else {
|
||||
setupNotificationUpdater();
|
||||
startForeground(NOTIFICATION_ID, updateNotifications());
|
||||
Notification notification = notificationManager.updateNotifications(
|
||||
requester.getNumberOfDownloads(), downloads);
|
||||
startForeground(NOTIFICATION_ID, notification);
|
||||
}
|
||||
}
|
||||
|
||||
private void postAuthenticationNotification(final DownloadRequest downloadRequest) {
|
||||
handler.post(() -> {
|
||||
final String resourceTitle = (downloadRequest.getTitle() != null) ?
|
||||
downloadRequest.getTitle() : downloadRequest.getSource();
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(DownloadService.this, NotificationUtils.CHANNEL_ID_USER_ACTION);
|
||||
builder.setTicker(getText(R.string.authentication_notification_title))
|
||||
.setContentTitle(getText(R.string.authentication_notification_title))
|
||||
.setContentText(getText(R.string.authentication_notification_msg))
|
||||
.setStyle(new NotificationCompat.BigTextStyle().bigText(getText(R.string.authentication_notification_msg)
|
||||
+ ": " + resourceTitle))
|
||||
.setSmallIcon(R.drawable.ic_notification_key)
|
||||
.setAutoCancel(true)
|
||||
.setContentIntent(ClientConfig.downloadServiceCallbacks.getAuthentificationNotificationContentIntent(DownloadService.this, downloadRequest));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
}
|
||||
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nm.notify(downloadRequest.getSource().hashCode(), builder.build());
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FeedItem getFeedItemFromId(long id) {
|
||||
FeedMedia media = DBReader.getFeedMedia(id);
|
||||
|
@ -667,7 +565,8 @@ public class DownloadService extends Service {
|
|||
private class NotificationUpdater implements Runnable {
|
||||
public void run() {
|
||||
handler.post(() -> {
|
||||
Notification n = updateNotifications();
|
||||
Notification n = notificationManager.updateNotifications(
|
||||
requester.getNumberOfDownloads(), downloads);
|
||||
if (n != null) {
|
||||
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nm.notify(NOTIFICATION_ID, n);
|
||||
|
@ -703,34 +602,4 @@ public class DownloadService extends Service {
|
|||
lastPost = now;
|
||||
}
|
||||
}
|
||||
|
||||
private static String compileNotificationString(List<Downloader> downloads) {
|
||||
List<String> lines = new ArrayList<>(downloads.size());
|
||||
for (Downloader downloader : downloads) {
|
||||
if (downloader.cancelled) {
|
||||
continue;
|
||||
}
|
||||
StringBuilder line = new StringBuilder("• ");
|
||||
DownloadRequest request = downloader.getDownloadRequest();
|
||||
switch (request.getFeedfileType()) {
|
||||
case Feed.FEEDFILETYPE_FEED:
|
||||
if (request.getTitle() != null) {
|
||||
line.append(request.getTitle());
|
||||
}
|
||||
break;
|
||||
case FeedMedia.FEEDFILETYPE_FEEDMEDIA:
|
||||
if (request.getTitle() != null) {
|
||||
line.append(request.getTitle())
|
||||
.append(" (")
|
||||
.append(request.getProgressPercent())
|
||||
.append("%)");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
line.append("Unknown: ").append(request.getFeedfileType());
|
||||
}
|
||||
lines.add(line.toString());
|
||||
}
|
||||
return TextUtils.join("\n", lines);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
package de.danoeh.antennapod.core.service.download;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import de.danoeh.antennapod.core.ClientConfig;
|
||||
import de.danoeh.antennapod.core.R;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.util.gui.NotificationUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class DownloadServiceNotification {
|
||||
private static final String TAG = "DownloadSvcNotification";
|
||||
private static final int REPORT_ID = 3;
|
||||
|
||||
private final Context context;
|
||||
private NotificationCompat.Builder notificationCompatBuilder;
|
||||
|
||||
public DownloadServiceNotification(Context context) {
|
||||
this.context = context;
|
||||
setupNotificationBuilders();
|
||||
}
|
||||
|
||||
private void setupNotificationBuilders() {
|
||||
notificationCompatBuilder = new NotificationCompat.Builder(context, NotificationUtils.CHANNEL_ID_DOWNLOADING)
|
||||
.setOngoing(true)
|
||||
.setContentIntent(ClientConfig.downloadServiceCallbacks.getNotificationContentIntent(context))
|
||||
.setSmallIcon(R.drawable.stat_notify_sync);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
notificationCompatBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
}
|
||||
|
||||
Log.d(TAG, "Notification set up");
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the contents of the service's notifications. Should be called
|
||||
* after setupNotificationBuilders.
|
||||
*/
|
||||
public Notification updateNotifications(int numDownloads, List<Downloader> downloads) {
|
||||
if (notificationCompatBuilder == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String contentTitle = context.getString(R.string.download_notification_title);
|
||||
String downloadsLeft = (numDownloads > 0)
|
||||
? context.getResources().getQuantityString(R.plurals.downloads_left, numDownloads, numDownloads)
|
||||
: context.getString(R.string.downloads_processing);
|
||||
String bigText = compileNotificationString(downloads);
|
||||
|
||||
notificationCompatBuilder.setContentTitle(contentTitle);
|
||||
notificationCompatBuilder.setContentText(downloadsLeft);
|
||||
notificationCompatBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText));
|
||||
return notificationCompatBuilder.build();
|
||||
}
|
||||
|
||||
private static String compileNotificationString(List<Downloader> downloads) {
|
||||
List<String> lines = new ArrayList<>(downloads.size());
|
||||
for (Downloader downloader : downloads) {
|
||||
if (downloader.cancelled) {
|
||||
continue;
|
||||
}
|
||||
StringBuilder line = new StringBuilder("• ");
|
||||
DownloadRequest request = downloader.getDownloadRequest();
|
||||
switch (request.getFeedfileType()) {
|
||||
case Feed.FEEDFILETYPE_FEED:
|
||||
if (request.getTitle() != null) {
|
||||
line.append(request.getTitle());
|
||||
}
|
||||
break;
|
||||
case FeedMedia.FEEDFILETYPE_FEEDMEDIA:
|
||||
if (request.getTitle() != null) {
|
||||
line.append(request.getTitle())
|
||||
.append(" (")
|
||||
.append(request.getProgressPercent())
|
||||
.append("%)");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
line.append("Unknown: ").append(request.getFeedfileType());
|
||||
}
|
||||
lines.add(line.toString());
|
||||
}
|
||||
return TextUtils.join("\n", lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a notification at the end of the service lifecycle to notify the
|
||||
* user about the number of completed downloads. A report will only be
|
||||
* created if there is at least one failed download excluding images
|
||||
*/
|
||||
public void updateReport(List<DownloadStatus> reportQueue) {
|
||||
// check if report should be created
|
||||
boolean createReport = false;
|
||||
int successfulDownloads = 0;
|
||||
int failedDownloads = 0;
|
||||
|
||||
// a download report is created if at least one download has failed
|
||||
// (excluding failed image downloads)
|
||||
for (DownloadStatus status : reportQueue) {
|
||||
if (status.isSuccessful()) {
|
||||
successfulDownloads++;
|
||||
} else if (!status.isCancelled()) {
|
||||
createReport = true;
|
||||
failedDownloads++;
|
||||
}
|
||||
}
|
||||
|
||||
if (createReport) {
|
||||
Log.d(TAG, "Creating report");
|
||||
// create notification object
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context,
|
||||
NotificationUtils.CHANNEL_ID_ERROR)
|
||||
.setTicker(context.getString(R.string.download_report_title))
|
||||
.setContentTitle(context.getString(R.string.download_report_content_title))
|
||||
.setContentText(
|
||||
String.format(
|
||||
context.getString(R.string.download_report_content),
|
||||
successfulDownloads, failedDownloads)
|
||||
)
|
||||
.setSmallIcon(R.drawable.stat_notify_sync_error)
|
||||
.setContentIntent(
|
||||
ClientConfig.downloadServiceCallbacks.getReportNotificationContentIntent(context)
|
||||
)
|
||||
.setAutoCancel(true);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
}
|
||||
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nm.notify(REPORT_ID, builder.build());
|
||||
} else {
|
||||
Log.d(TAG, "No report is created");
|
||||
}
|
||||
}
|
||||
|
||||
public void postAuthenticationNotification(final DownloadRequest downloadRequest) {
|
||||
final String resourceTitle = (downloadRequest.getTitle() != null) ?
|
||||
downloadRequest.getTitle() : downloadRequest.getSource();
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NotificationUtils.CHANNEL_ID_USER_ACTION);
|
||||
builder.setTicker(context.getText(R.string.authentication_notification_title))
|
||||
.setContentTitle(context.getText(R.string.authentication_notification_title))
|
||||
.setContentText(context.getText(R.string.authentication_notification_msg))
|
||||
.setStyle(new NotificationCompat.BigTextStyle().bigText(context.getText(R.string.authentication_notification_msg)
|
||||
+ ": " + resourceTitle))
|
||||
.setSmallIcon(R.drawable.ic_notification_key)
|
||||
.setAutoCancel(true)
|
||||
.setContentIntent(ClientConfig.downloadServiceCallbacks.getAuthentificationNotificationContentIntent(context, downloadRequest));
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
}
|
||||
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nm.notify(downloadRequest.getSource().hashCode(), builder.build());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue