Add logic to show/hide notifications based on appdetails screen

Also, add code to AppDetails2 to match AppDetails, keeping track of
currently viewed app. Moved the nulling of this info to onStop instead
of onPause, since alerts may be shown on top of the details page, while
still visible.
This commit is contained in:
mvp76 2017-02-28 16:33:37 +01:00
parent d2cc4fcb05
commit 04d2d004a3
5 changed files with 92 additions and 20 deletions

View File

@ -432,6 +432,12 @@ public class AppDetails extends AppCompatActivity {
myAppObserver);
}
@Override
protected void onResume() {
super.onResume();
updateNotificationsForApp();
}
@Override
protected void onResumeFragments() {
// Must be called before super.onResumeFragments(), as the fragments depend on the active
@ -462,13 +468,34 @@ public class AppDetails extends AppCompatActivity {
protected void onStop() {
super.onStop();
visiblePackageName = null;
getContentResolver().unregisterContentObserver(myAppObserver);
// When leaving the app details, make sure to refresh app status for this app, since
// we might want to show notifications for it now.
updateNotificationsForApp();
}
/**
* Some notifications (like "downloading" and "installed") are not shown for this app if it is open in app details.
* When closing, we need to refresh the notifications, so they are displayed again.
*/
private void updateNotificationsForApp() {
if (app != null) {
AppUpdateStatusManager appUpdateStatusManager = AppUpdateStatusManager.getInstance(this);
for (AppUpdateStatusManager.AppUpdateStatus status : appUpdateStatusManager.getByPackageName(app.packageName)) {
if (status.status == AppUpdateStatusManager.Status.Installed) {
appUpdateStatusManager.removeApk(status.getUniqueKey());
} else {
appUpdateStatusManager.refreshApk(status.getUniqueKey());
}
}
}
}
@Override
protected void onPause() {
super.onPause();
visiblePackageName = null;
// save the active URL for this app in case we come back
getPreferences(MODE_PRIVATE)
.edit()
@ -554,7 +581,7 @@ public class AppDetails extends AppCompatActivity {
String errorMessage =
intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE);
if (!TextUtils.isEmpty(errorMessage)) {
if (!TextUtils.isEmpty(errorMessage) && !isFinishing()) {
Log.e(TAG, "install aborted with errorMessage: " + errorMessage);
String title = String.format(
@ -701,14 +728,6 @@ public class AppDetails extends AppCompatActivity {
app = newApp;
startingPrefs = app.getPrefs(this).createClone();
// Remove all "installed" statuses for this app, since we are now viewing it.
AppUpdateStatusManager appUpdateStatusManager = AppUpdateStatusManager.getInstance(this);
for (AppUpdateStatusManager.AppUpdateStatus status : appUpdateStatusManager.getByPackageName(app.packageName)) {
if (status.status == AppUpdateStatusManager.Status.Installed) {
appUpdateStatusManager.removeApk(status.getUniqueKey());
}
}
}
private void refreshApkList() {

View File

@ -64,6 +64,16 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
private LocalBroadcastManager localBroadcastManager;
private String activeDownloadUrlString;
/**
* 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;
@Override
protected void onCreate(Bundle savedInstanceState) {
fdroidApp = (FDroidApp) getApplication();
@ -131,6 +141,41 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
}
}
/**
* Some notifications (like "downloading" and "installed") are not shown for this app if it is open in app details.
* When closing, we need to refresh the notifications, so they are displayed again.
*/
private void updateNotificationsForApp() {
if (app != null) {
AppUpdateStatusManager appUpdateStatusManager = AppUpdateStatusManager.getInstance(this);
for (AppUpdateStatusManager.AppUpdateStatus status : appUpdateStatusManager.getByPackageName(app.packageName)) {
if (status.status == AppUpdateStatusManager.Status.Installed) {
appUpdateStatusManager.removeApk(status.getUniqueKey());
} else {
appUpdateStatusManager.refreshApk(status.getUniqueKey());
}
}
}
}
@Override
protected void onResume() {
super.onResume();
if (app != null) {
visiblePackageName = app.packageName;
}
updateNotificationsForApp();
}
protected void onStop() {
super.onStop();
visiblePackageName = null;
// When leaving the app details, make sure to refresh app status for this app, since
// we might want to show notifications for it now.
updateNotificationsForApp();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean ret = super.onCreateOptionsMenu(menu);
@ -372,7 +417,7 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
String errorMessage =
intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE);
if (!TextUtils.isEmpty(errorMessage)) {
if (!TextUtils.isEmpty(errorMessage) && !isFinishing()) {
Log.e(TAG, "install aborted with errorMessage: " + errorMessage);
String title = String.format(

View File

@ -237,6 +237,16 @@ public class AppUpdateStatusManager {
}
}
public void refreshApk(String key) {
synchronized (appMapping) {
AppUpdateStatus entry = appMapping.get(key);
if (entry != null) {
Utils.debugLog(LOGTAG, "Refresh APK " + entry.apk.apkName);
notifyChange(entry, true);
}
}
}
public void updateApkProgress(String key, int max, int current) {
synchronized (appMapping) {
AppUpdateStatus entry = appMapping.get(key);

View File

@ -178,8 +178,9 @@ class NotificationHelper {
// Ignore unknown status
if (entry.status == AppUpdateStatusManager.Status.Unknown)
return true;
// Ignore first time install downloads, assumed to be done from UI
else if (!entry.app.isInstalled() && (entry.status == AppUpdateStatusManager.Status.Downloading || entry.status == AppUpdateStatusManager.Status.ReadyToInstall))
// Ignore downloading, readyToInstall and installError if we are showing the details screen for this app
else if ((entry.status == AppUpdateStatusManager.Status.Downloading || entry.status == AppUpdateStatusManager.Status.ReadyToInstall || entry.status == AppUpdateStatusManager.Status.InstallError) &&
(AppDetails.isAppVisible(entry.app.packageName) || AppDetails2.isAppVisible(entry.app.packageName)))
return true;
return false;
}

View File

@ -15,6 +15,7 @@ import android.text.TextUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.fdroid.fdroid.AppDetails;
import org.fdroid.fdroid.AppDetails2;
import org.fdroid.fdroid.AppUpdateStatusManager;
import org.fdroid.fdroid.Hasher;
import org.fdroid.fdroid.Utils;
@ -313,17 +314,13 @@ public class InstallManagerService extends Service {
localBroadcastManager.unregisterReceiver(this);
break;
case Installer.ACTION_INSTALL_INTERRUPTED:
AppUpdateStatusManager.AppUpdateStatus status = appUpdateStatusManager.get(downloadUrl);
appUpdateStatusManager.removeApk(downloadUrl);
apk = intent.getParcelableExtra(Installer.EXTRA_APK);
String errorMessage =
intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE);
// show notification if app details is not visible
if (!TextUtils.isEmpty(errorMessage)) {
if (status == null || status.app == null || !AppDetails.isAppVisible(status.app.packageName)) {
appUpdateStatusManager.setApkError(apk, errorMessage);
}
appUpdateStatusManager.setApkError(apk, errorMessage);
} else {
appUpdateStatusManager.removeApk(downloadUrl);
}
localBroadcastManager.unregisterReceiver(this);
break;