From e75143530f84a01928b1fd4be8600d9d3a110aac Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 11 May 2016 14:32:52 +0200 Subject: [PATCH] track AppDetails visibility to improve Notification UX If AppDetails is visible, then it'll automatically launch the install process, and there is no need to put up a "Tap to install" notification. And of course, whenever I search stackoverflow, I find an answer from @commonsguy :) https://stackoverflow.com/questions/18038399/how-to-check-if-activity-is-in-foreground-or-in-visible-background/18469643#18469643 --- .../java/org/fdroid/fdroid/AppDetails.java | 11 +++++++++++ .../installer/InstallManagerService.java | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/fdroid/fdroid/AppDetails.java b/app/src/main/java/org/fdroid/fdroid/AppDetails.java index abcd19523..5bdb405ef 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppDetails.java +++ b/app/src/main/java/org/fdroid/fdroid/AppDetails.java @@ -110,6 +110,15 @@ public class AppDetails extends AppCompatActivity { private FDroidApp fdroidApp; private ApkListAdapter adapter; + /** + * Check if {@code packageName} is currently visible to the user. + */ + public static boolean isAppVisible(String packageName) { + return packageName != null && packageName.equals(visiblePackageName); + } + + private static String visiblePackageName; + private static class ViewHolder { TextView version; TextView status; @@ -437,6 +446,7 @@ public class AppDetails extends AppCompatActivity { if (DownloaderService.isQueuedOrActive(activeDownloadUrlString)) { registerDownloaderReceivers(); } + visiblePackageName = app.packageName; } /** @@ -458,6 +468,7 @@ public class AppDetails extends AppCompatActivity { @Override protected void onPause() { super.onPause(); + visiblePackageName = null; // save the active URL for this app in case we come back PreferencesCompat.apply(getPreferences(MODE_PRIVATE) .edit() diff --git a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java index aca8a12b5..c0097250d 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java @@ -175,7 +175,11 @@ public class InstallManagerService extends Service { // TODO these need to be removed based on whether they are fed to InstallerService or not Apk apk = ACTIVE_APKS.remove(urlString); ACTIVE_APPS.remove(apk.packageName); - notifyDownloadComplete(apk, urlString); + if (AppDetails.isAppVisible(apk.packageName)) { + cancelNotification(urlString); + } else { + notifyDownloadComplete(apk, urlString); + } unregisterDownloaderReceivers(urlString); } }; @@ -186,6 +190,9 @@ public class InstallManagerService extends Service { Apk apk = ACTIVE_APKS.remove(urlString); ACTIVE_APPS.remove(apk.packageName); unregisterDownloaderReceivers(urlString); + if (AppDetails.isAppVisible(apk.packageName)) { + cancelNotification(urlString); + } } }; localBroadcastManager.registerReceiver(startedReceiver, @@ -269,6 +276,15 @@ public class InstallManagerService extends Service { nm.notify(downloadUrlId, builder.build()); } + /** + * Cancel the {@link Notification} tied to {@code urlString}, which is the + * unique ID used to represent a given APK file. {@link String#hashCode()} + * converts {@code urlString} to the required {@code int}. + */ + private void cancelNotification(String urlString) { + notificationManager.cancel(urlString.hashCode()); + } + /** * Install an APK, checking the cache and downloading if necessary before starting the process. * All notifications are sent as an {@link Intent} via local broadcasts to be received by