diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d6dede04c..cdfa9cffb 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -251,6 +251,12 @@
             <!-- Doesn't require an intent-filter because it is explicitly invoked via Intent.setClass() -->
         </receiver>
 
+        <receiver android:name=".receiver.DeviceStorageReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.DEVICE_STORAGE_LOW"/>
+            </intent-filter>
+        </receiver>
+
         <service android:name=".UpdateService"/>
         <service
                 android:name=".net.DownloaderService"
@@ -279,6 +285,7 @@
                 android:name=".AppUpdateStatusService"
                 android:exported="false"/>
 
+
         <!-- Warning: Please add all new services to HidingManager -->
 
         <activity
@@ -534,9 +541,11 @@
             <meta-data
                     android:name="android.support.PARENT_ACTIVITY"
                     android:value=".views.main.MainActivity"/>
+
             <intent-filter>
                 <action android:name="info.guardianproject.panic.action.CONNECT"/>
                 <action android:name="info.guardianproject.panic.action.DISCONNECT"/>
+
                 <category android:name="android.intent.category.DEFAULT"/>
             </intent-filter>
         </activity>
@@ -544,16 +553,17 @@
                 android:name=".views.panic.PanicResponderActivity"
                 android:noHistory="true"
                 android:theme="@android:style/Theme.NoDisplay">
+
             <!-- this can never have launchMode singleTask or singleInstance! -->
             <intent-filter>
                 <action android:name="info.guardianproject.panic.action.TRIGGER"/>
+
                 <category android:name="android.intent.category.DEFAULT"/>
             </intent-filter>
         </activity>
         <activity
                 android:name=".views.panic.ExitActivity"
                 android:theme="@android:style/Theme.NoDisplay"/>
-
         <activity
                 android:name=".views.hiding.CalculatorActivity"
                 android:enabled="false"
@@ -562,6 +572,7 @@
                 android:theme="@style/AppThemeLight">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
+
                 <category android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
         </activity>
diff --git a/app/src/main/java/org/fdroid/fdroid/CleanCacheService.java b/app/src/main/java/org/fdroid/fdroid/CleanCacheService.java
index ce464991e..da887eb00 100644
--- a/app/src/main/java/org/fdroid/fdroid/CleanCacheService.java
+++ b/app/src/main/java/org/fdroid/fdroid/CleanCacheService.java
@@ -8,7 +8,6 @@ import android.content.Intent;
 import android.os.Build;
 import android.os.Process;
 import android.os.SystemClock;
-
 import org.apache.commons.io.FileUtils;
 import org.fdroid.fdroid.installer.ApkCache;
 
@@ -51,6 +50,10 @@ public class CleanCacheService extends IntentService {
                 SystemClock.elapsedRealtime() + 5000, interval, pending);
     }
 
+    public static void start(Context context) {
+        context.startService(new Intent(context, CleanCacheService.class));
+    }
+
     public CleanCacheService() {
         super("CleanCacheService");
     }
diff --git a/app/src/main/java/org/fdroid/fdroid/Utils.java b/app/src/main/java/org/fdroid/fdroid/Utils.java
index 682135a18..9ca43a347 100644
--- a/app/src/main/java/org/fdroid/fdroid/Utils.java
+++ b/app/src/main/java/org/fdroid/fdroid/Utils.java
@@ -24,6 +24,8 @@ import android.content.res.Resources;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.net.Uri;
+import android.os.Build;
+import android.os.StatFs;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RequiresApi;
@@ -133,6 +135,38 @@ public final class Utils {
         return new File(cacheDir, "icons");
     }
 
+    public static long getImageCacheDirAvailableMemory(Context context) {
+        File statDir = getImageCacheDir(context);
+        while (statDir != null && !statDir.exists()) {
+            statDir = statDir.getParentFile();
+        }
+        if (statDir == null) {
+            return 50 * 1024 * 1024; // just return a minimal amount
+        }
+        StatFs stat = new StatFs(statDir.getPath());
+        if (Build.VERSION.SDK_INT < 18) {
+            return stat.getAvailableBlocks() * stat.getBlockSize();
+        } else {
+            return stat.getAvailableBlocksLong() * stat.getBlockSizeLong();
+        }
+    }
+
+    public static long getImageCacheDirTotalMemory(Context context) {
+        File statDir = getImageCacheDir(context);
+        while (statDir != null && !statDir.exists()) {
+            statDir = statDir.getParentFile();
+        }
+        if (statDir == null) {
+            return 100 * 1024 * 1024; // just return a minimal amount
+        }
+        StatFs stat = new StatFs(statDir.getPath());
+        if (Build.VERSION.SDK_INT < 18) {
+            return stat.getBlockCount() * stat.getBlockSize();
+        } else {
+            return stat.getBlockCountLong() * stat.getBlockSizeLong();
+        }
+    }
+
     public static void copy(InputStream input, OutputStream output) throws IOException {
         byte[] buffer = new byte[BUFFER_SIZE];
         while (true) {
diff --git a/app/src/main/java/org/fdroid/fdroid/receiver/DeviceStorageReceiver.java b/app/src/main/java/org/fdroid/fdroid/receiver/DeviceStorageReceiver.java
new file mode 100644
index 000000000..2beef8404
--- /dev/null
+++ b/app/src/main/java/org/fdroid/fdroid/receiver/DeviceStorageReceiver.java
@@ -0,0 +1,19 @@
+package org.fdroid.fdroid.receiver;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import org.fdroid.fdroid.CleanCacheService;
+
+public class DeviceStorageReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (intent == null) {
+            return;
+        }
+        String action = intent.getAction();
+        if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(action)) {
+            CleanCacheService.schedule(context);
+        }
+    }
+}