diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 20282d97..ef0bcc01 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
Preparing offline mode
Synchronizing offline data
Finished synchronizing your offline data
+ Offline mode
+ Cache images
+ Download images to sdcard. This might significantly increase time it takes to go offline.
\ No newline at end of file
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index ec3c5d16..1afeac97 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -1,40 +1,107 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
\ No newline at end of file
diff --git a/src/org/fox/ttrss/FeedsFragment.java b/src/org/fox/ttrss/FeedsFragment.java
index 0ead6de9..bb823dd0 100644
--- a/src/org/fox/ttrss/FeedsFragment.java
+++ b/src/org/fox/ttrss/FeedsFragment.java
@@ -7,6 +7,7 @@ import java.io.InputStream;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
+import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -308,7 +309,9 @@ public class FeedsFragment extends Fragment implements OnItemClickListener, OnSh
else
setLoadingStatus(R.string.blank, false);
- if (m_enableFeedIcons && !m_feedIconsChecked) getFeedIcons();
+ if (m_enableFeedIcons && !m_feedIconsChecked &&
+ Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
+ getFeedIcons();
return;
}
diff --git a/src/org/fox/ttrss/ImageCacheService.java b/src/org/fox/ttrss/ImageCacheService.java
new file mode 100644
index 00000000..999b7437
--- /dev/null
+++ b/src/org/fox/ttrss/ImageCacheService.java
@@ -0,0 +1,181 @@
+package org.fox.ttrss;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Date;
+
+import android.app.ActivityManager;
+import android.app.IntentService;
+import android.app.NotificationManager;
+import android.app.ActivityManager.RunningServiceInfo;
+import android.content.Intent;
+import android.os.Environment;
+import android.util.Log;
+
+public class ImageCacheService extends IntentService {
+
+ private final String TAG = this.getClass().getSimpleName();
+
+ public static final int NOTIFY_DOWNLOADING = 1;
+
+ private static final String CACHE_PATH = "/org.fox.ttrss/image-cache/";
+
+ private int m_imagesDownloaded = 0;
+
+ private NotificationManager m_nmgr;
+
+ public ImageCacheService() {
+ super("ImageCacheService");
+ }
+
+ private boolean isDownloadServiceRunning() {
+ ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
+ for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
+ if ("org.fox.ttrss.OfflineDownloadService".equals(service.service.getClassName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ m_nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+ }
+
+ protected static boolean isUrlCached(String url) {
+ String hashedUrl = md5(url);
+
+ File storage = Environment.getExternalStorageDirectory();
+
+ File file = new File(storage.getAbsolutePath() + CACHE_PATH + "/" + hashedUrl + ".png");
+
+ return file.exists();
+ }
+
+ protected static String getCacheFileName(String url) {
+ String hashedUrl = md5(url);
+
+ File storage = Environment.getExternalStorageDirectory();
+
+ File file = new File(storage.getAbsolutePath() + CACHE_PATH + "/" + hashedUrl + ".png");
+
+ return file.getAbsolutePath();
+ }
+
+ protected static void cleanupCache(boolean deleteAll) {
+ if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
+ File storage = Environment.getExternalStorageDirectory();
+ File cachePath = new File(storage.getAbsolutePath() + CACHE_PATH);
+
+ long now = new Date().getTime();
+
+ if (cachePath.isDirectory()) {
+ for (File file : cachePath.listFiles()) {
+ if (deleteAll || now - file.lastModified() > 1000*60*60*24*7) {
+ file.delete();
+ }
+ }
+ }
+ }
+ }
+
+ protected static String md5(String s) {
+ try {
+ MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
+ digest.update(s.getBytes());
+ byte messageDigest[] = digest.digest();
+
+ StringBuffer hexString = new StringBuffer();
+ for (int i=0; i" +
@@ -134,7 +160,7 @@ public class OfflineArticleFragment extends Fragment implements OnClickListener
"body { text-align : justify; }" +
"" +
"" +
- "" + m_cursor.getString(m_cursor.getColumnIndex("content")) + "