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); myAppObserver);
} }
@Override
protected void onResume() {
super.onResume();
updateNotificationsForApp();
}
@Override @Override
protected void onResumeFragments() { protected void onResumeFragments() {
// Must be called before super.onResumeFragments(), as the fragments depend on the active // 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() { protected void onStop() {
super.onStop(); super.onStop();
visiblePackageName = null;
getContentResolver().unregisterContentObserver(myAppObserver); 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 @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
visiblePackageName = null;
// save the active URL for this app in case we come back // save the active URL for this app in case we come back
getPreferences(MODE_PRIVATE) getPreferences(MODE_PRIVATE)
.edit() .edit()
@ -554,7 +581,7 @@ public class AppDetails extends AppCompatActivity {
String errorMessage = String errorMessage =
intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE); intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE);
if (!TextUtils.isEmpty(errorMessage)) { if (!TextUtils.isEmpty(errorMessage) && !isFinishing()) {
Log.e(TAG, "install aborted with errorMessage: " + errorMessage); Log.e(TAG, "install aborted with errorMessage: " + errorMessage);
String title = String.format( String title = String.format(
@ -701,14 +728,6 @@ public class AppDetails extends AppCompatActivity {
app = newApp; app = newApp;
startingPrefs = app.getPrefs(this).createClone(); 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() { private void refreshApkList() {

View File

@ -64,6 +64,16 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
private LocalBroadcastManager localBroadcastManager; private LocalBroadcastManager localBroadcastManager;
private String activeDownloadUrlString; 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 @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
fdroidApp = (FDroidApp) getApplication(); 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 @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
boolean ret = super.onCreateOptionsMenu(menu); boolean ret = super.onCreateOptionsMenu(menu);
@ -372,7 +417,7 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog
String errorMessage = String errorMessage =
intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE); intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE);
if (!TextUtils.isEmpty(errorMessage)) { if (!TextUtils.isEmpty(errorMessage) && !isFinishing()) {
Log.e(TAG, "install aborted with errorMessage: " + errorMessage); Log.e(TAG, "install aborted with errorMessage: " + errorMessage);
String title = String.format( 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) { public void updateApkProgress(String key, int max, int current) {
synchronized (appMapping) { synchronized (appMapping) {
AppUpdateStatus entry = appMapping.get(key); AppUpdateStatus entry = appMapping.get(key);

View File

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

View File

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