diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 402e44597..f599f19d4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -297,6 +297,9 @@
+
diff --git a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java
index 8ec8cd1e4..c6d48b7cb 100644
--- a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java
+++ b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java
@@ -40,6 +40,7 @@ public final class AppUpdateStatusManager {
* * The user clears the list of installed apps from notification manager.
* * The user clears the list of apps available to update from the notification manager.
* * A repo update is completed and a bunch of new apps are ready to be updated.
+ * * F-Droid is opened, and it finds a bunch of .apk files downloaded and ready to install.
*/
public static final String BROADCAST_APPSTATUS_LIST_CHANGED = "org.fdroid.fdroid.installer.appstatus.listchange";
diff --git a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusService.java b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusService.java
new file mode 100644
index 000000000..94cc3e26a
--- /dev/null
+++ b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusService.java
@@ -0,0 +1,54 @@
+package org.fdroid.fdroid;
+
+import android.app.IntentService;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.support.annotation.Nullable;
+
+import org.fdroid.fdroid.data.Apk;
+import org.fdroid.fdroid.data.ApkProvider;
+import org.fdroid.fdroid.data.App;
+import org.fdroid.fdroid.data.AppProvider;
+import org.fdroid.fdroid.data.Schema;
+import org.fdroid.fdroid.installer.ApkCache;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Scans the list of downloaded .apk files in the cache for each app which can be updated.
+ * If a valid .apk file is found then it will tell the {@link AppUpdateStatusManager} that it is
+ * {@link AppUpdateStatusManager.Status#ReadyToInstall}. This is an {@link IntentService} so as to
+ * run on a background thread, as it hits the disk a bit to figure out the hash of each downloaded
+ * file.
+ */
+public class AppUpdateStatusService extends IntentService {
+
+ /**
+ * Queue up a background scan of all downloaded apk files to see if we should notify the user
+ * that they are ready to install.
+ */
+ public static void scanDownloadedApks(Context context) {
+ context.startService(new Intent(context, AppUpdateStatusService.class));
+ }
+
+ public AppUpdateStatusService() {
+ super("AppUpdateStatusService");
+ }
+
+ @Override
+ protected void onHandleIntent(@Nullable Intent intent) {
+ List apps = AppProvider.Helper.findCanUpdate(this, Schema.AppMetadataTable.Cols.ALL);
+ List apksReadyToInstall = new ArrayList<>();
+ for (App app : apps) {
+ Apk apk = ApkProvider.Helper.findApkFromAnyRepo(this, app.packageName, app.suggestedVersionCode);
+ Uri downloadUri = Uri.parse(apk.getUrl());
+ if (ApkCache.apkIsCached(ApkCache.getApkDownloadPath(this, downloadUri), apk)) {
+ apksReadyToInstall.add(apk);
+ }
+ }
+
+ AppUpdateStatusManager.getInstance(this).addApks(apksReadyToInstall, AppUpdateStatusManager.Status.ReadyToInstall);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/fdroid/fdroid/FDroidApp.java b/app/src/main/java/org/fdroid/fdroid/FDroidApp.java
index 41bad692f..49674fba3 100644
--- a/app/src/main/java/org/fdroid/fdroid/FDroidApp.java
+++ b/app/src/main/java/org/fdroid/fdroid/FDroidApp.java
@@ -234,6 +234,7 @@ public class FDroidApp extends Application {
Preferences.get().configureProxy();
InstalledAppProviderService.compareToPackageManager(this);
+ AppUpdateStatusService.scanDownloadedApks(this);
// If the user changes the preference to do with filtering rooted apps,
// it is easier to just notify a change in the app provider,