diff options
Diffstat (limited to 'src/org/fox/ttrss/offline/OfflineDownloadService.java')
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineDownloadService.java | 972 |
1 files changed, 486 insertions, 486 deletions
diff --git a/src/org/fox/ttrss/offline/OfflineDownloadService.java b/src/org/fox/ttrss/offline/OfflineDownloadService.java index 992c21f6..2fe87570 100644 --- a/src/org/fox/ttrss/offline/OfflineDownloadService.java +++ b/src/org/fox/ttrss/offline/OfflineDownloadService.java @@ -1,486 +1,486 @@ -package org.fox.ttrss.offline;
-
-import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.List;
-
-import org.fox.ttrss.ApiRequest;
-import org.fox.ttrss.OnlineActivity;
-import org.fox.ttrss.R;
-import org.fox.ttrss.types.Article;
-import org.fox.ttrss.types.Feed;
-import org.fox.ttrss.types.FeedCategory;
-import org.fox.ttrss.util.DatabaseHelper;
-import org.fox.ttrss.util.ImageCacheService;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Elements;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningServiceInfo;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteStatement;
-import android.os.Binder;
-import android.os.IBinder;
-import android.preference.PreferenceManager;
-import android.provider.BaseColumns;
-import android.util.Log;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonElement;
-import com.google.gson.reflect.TypeToken;
-
-public class OfflineDownloadService extends Service {
-
- private final String TAG = this.getClass().getSimpleName();
-
- public static final int NOTIFY_DOWNLOADING = 1;
- public static final String INTENT_ACTION_SUCCESS = "org.fox.ttrss.intent.action.DownloadComplete";
- public static final String INTENT_ACTION_CANCEL = "org.fox.ttrss.intent.action.Cancel";
-
- private static final int OFFLINE_SYNC_SEQ = 50;
- private static final int OFFLINE_SYNC_MAX = OFFLINE_SYNC_SEQ * 10;
-
- private SQLiteDatabase m_writableDb;
- private SQLiteDatabase m_readableDb;
- private int m_articleOffset = 0;
- private String m_sessionId;
- private NotificationManager m_nmgr;
-
- private boolean m_downloadInProgress = false;
- private boolean m_downloadImages = false;
- private int m_syncMax;
- private SharedPreferences m_prefs;
- private boolean m_canProceed = true;
-
- private final IBinder m_binder = new LocalBinder();
-
- public class LocalBinder extends Binder {
- OfflineDownloadService getService() {
- return OfflineDownloadService.this;
- }
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return m_binder;
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- m_nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
- m_prefs = PreferenceManager
- .getDefaultSharedPreferences(getApplicationContext());
-
- m_downloadImages = m_prefs.getBoolean("offline_image_cache_enabled", false);
- m_syncMax = Integer.parseInt(m_prefs.getString("offline_sync_max", String.valueOf(OFFLINE_SYNC_MAX)));
-
- initDatabase();
- }
-
- @SuppressWarnings("deprecation")
- private void updateNotification(String msg) {
- Notification notification = new Notification(R.drawable.icon,
- getString(R.string.notify_downloading_title), System.currentTimeMillis());
-
- Intent intent = new Intent(this, OnlineActivity.class);
- intent.setAction(INTENT_ACTION_CANCEL);
-
- PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
- intent, 0);
-
- notification.flags |= Notification.FLAG_ONGOING_EVENT;
- notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
-
- notification.setLatestEventInfo(this, getString(R.string.notify_downloading_title), msg, contentIntent);
-
- m_nmgr.notify(NOTIFY_DOWNLOADING, notification);
- }
-
- private void updateNotification(int msgResId) {
- updateNotification(getString(msgResId));
- }
-
- private void downloadFailed() {
- m_readableDb.close();
- m_writableDb.close();
-
- m_nmgr.cancel(NOTIFY_DOWNLOADING);
-
- // TODO send notification to activity?
-
- m_downloadInProgress = false;
- stopSelf();
- }
-
- private boolean isCacheServiceRunning() {
- ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
- for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
- if ("org.fox.ttrss.ImageCacheService".equals(service.service.getClassName())) {
- return true;
- }
- }
- return false;
- }
-
- public void downloadComplete() {
- m_downloadInProgress = false;
-
- // if cache service is running, it will send a finished intent on its own
- if (!isCacheServiceRunning()) {
- m_nmgr.cancel(NOTIFY_DOWNLOADING);
-
- Intent intent = new Intent();
- intent.setAction(INTENT_ACTION_SUCCESS);
- intent.addCategory(Intent.CATEGORY_DEFAULT);
- sendBroadcast(intent);
- } else {
- updateNotification(getString(R.string.notify_downloading_images, 0));
- }
-
- m_readableDb.close();
- m_writableDb.close();
-
- stopSelf();
- }
-
- private void initDatabase() {
- DatabaseHelper dh = new DatabaseHelper(getApplicationContext());
- m_writableDb = dh.getWritableDatabase();
- m_readableDb = dh.getReadableDatabase();
- }
-
- /* private synchronized SQLiteDatabase getReadableDb() {
- return m_readableDb;
- } */
-
- private synchronized SQLiteDatabase getWritableDb() {
- return m_writableDb;
- }
-
- @SuppressWarnings("unchecked")
- private void downloadArticles() {
- Log.d(TAG, "offline: downloading articles... offset=" + m_articleOffset);
-
- updateNotification(getString(R.string.notify_downloading_articles, m_articleOffset));
-
- OfflineArticlesRequest req = new OfflineArticlesRequest(this);
-
- @SuppressWarnings("serial")
- HashMap<String,String> map = new HashMap<String,String>() {
- {
- put("op", "getHeadlines");
- put("sid", m_sessionId);
- put("feed_id", "-4");
- put("view_mode", "unread");
- put("show_content", "true");
- put("skip", String.valueOf(m_articleOffset));
- put("limit", String.valueOf(OFFLINE_SYNC_SEQ));
- }
- };
-
- req.execute(map);
- }
-
- private void downloadFeeds() {
-
- updateNotification(R.string.notify_downloading_feeds);
-
- getWritableDb().execSQL("DELETE FROM feeds;");
-
- ApiRequest req = new ApiRequest(getApplicationContext()) {
- @Override
- protected JsonElement doInBackground(HashMap<String, String>... params) {
- JsonElement content = super.doInBackground(params);
-
- if (content != null) {
-
- try {
- Type listType = new TypeToken<List<Feed>>() {}.getType();
- List<Feed> feeds = new Gson().fromJson(content, listType);
-
- SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO feeds " +
- "("+BaseColumns._ID+", title, feed_url, has_icon, cat_id) " +
- "VALUES (?, ?, ?, ?, ?);");
-
- for (Feed feed : feeds) {
- stmtInsert.bindLong(1, feed.id);
- stmtInsert.bindString(2, feed.title);
- stmtInsert.bindString(3, feed.feed_url);
- stmtInsert.bindLong(4, feed.has_icon ? 1 : 0);
- stmtInsert.bindLong(5, feed.cat_id);
-
- stmtInsert.execute();
- }
-
- stmtInsert.close();
-
- Log.d(TAG, "offline: done downloading feeds");
-
- m_articleOffset = 0;
-
- getWritableDb().execSQL("DELETE FROM articles;");
- } catch (Exception e) {
- e.printStackTrace();
- updateNotification(R.string.offline_switch_error);
- downloadFailed();
- }
- }
-
- return content;
- }
-
- @Override
- protected void onPostExecute(JsonElement content) {
- if (content != null) {
- if (m_canProceed) {
- downloadArticles();
- } else {
- downloadFailed();
- }
- } else {
- updateNotification(getErrorMessage());
- downloadFailed();
- }
- }
-
- };
-
- @SuppressWarnings("serial")
- HashMap<String,String> map = new HashMap<String,String>() {
- {
- put("op", "getFeeds");
- put("sid", m_sessionId);
- put("cat_id", "-3");
- put("unread_only", "true");
- }
- };
-
- req.execute(map);
- }
-
- private void downloadCategories() {
-
- updateNotification(R.string.notify_downloading_feeds);
-
- getWritableDb().execSQL("DELETE FROM categories;");
-
- ApiRequest req = new ApiRequest(getApplicationContext()) {
- protected JsonElement doInBackground(HashMap<String, String>... params) {
- JsonElement content = super.doInBackground(params);
-
- if (content != null) {
- try {
- Type listType = new TypeToken<List<FeedCategory>>() {}.getType();
- List<FeedCategory> cats = new Gson().fromJson(content, listType);
-
- SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO categories " +
- "("+BaseColumns._ID+", title) " +
- "VALUES (?, ?);");
-
- for (FeedCategory cat : cats) {
- stmtInsert.bindLong(1, cat.id);
- stmtInsert.bindString(2, cat.title);
-
- stmtInsert.execute();
- }
-
- stmtInsert.close();
-
- Log.d(TAG, "offline: done downloading categories");
-
- } catch (Exception e) {
- e.printStackTrace();
- updateNotification(R.string.offline_switch_error);
- downloadFailed();
- }
- }
-
- return content;
- }
- @Override
- protected void onPostExecute(JsonElement content) {
- if (content != null) {
- if (m_canProceed) {
- downloadFeeds();
- } else {
- downloadFailed();
- }
- } else {
- updateNotification(getErrorMessage());
- downloadFailed();
- }
- }
-
- };
-
- @SuppressWarnings("serial")
- HashMap<String,String> map = new HashMap<String,String>() {
- {
- put("op", "getCategories");
- put("sid", m_sessionId);
- //put("cat_id", "-3");
- put("unread_only", "true");
- }
- };
-
- req.execute(map);
- }
-
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- m_nmgr.cancel(NOTIFY_DOWNLOADING);
-
- m_canProceed = false;
- Log.d(TAG, "onDestroy");
-
- //m_readableDb.close();
- //m_writableDb.close();
- }
-
- public class OfflineArticlesRequest extends ApiRequest {
- List<Article> m_articles;
-
- public OfflineArticlesRequest(Context context) {
- super(context);
- }
-
- @Override
- protected JsonElement doInBackground(HashMap<String, String>... params) {
- JsonElement content = super.doInBackground(params);
-
- if (content != null) {
-
- try {
- Type listType = new TypeToken<List<Article>>() {}.getType();
- m_articles = new Gson().fromJson(content, listType);
-
- SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO articles " +
- "("+BaseColumns._ID+", unread, marked, published, updated, is_updated, title, link, feed_id, tags, content) " +
- "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
-
- for (Article article : m_articles) {
-
- String tagsString = "";
-
- for (String t : article.tags) {
- tagsString += t + ", ";
- }
-
- tagsString = tagsString.replaceAll(", $", "");
-
- stmtInsert.bindLong(1, article.id);
- stmtInsert.bindLong(2, article.unread ? 1 : 0);
- stmtInsert.bindLong(3, article.marked ? 1 : 0);
- stmtInsert.bindLong(4, article.published ? 1 : 0);
- stmtInsert.bindLong(5, article.updated);
- stmtInsert.bindLong(6, article.is_updated ? 1 : 0);
- stmtInsert.bindString(7, article.title);
- stmtInsert.bindString(8, article.link);
- stmtInsert.bindLong(9, article.feed_id);
- stmtInsert.bindString(10, tagsString); // comma-separated tags
- stmtInsert.bindString(11, article.content);
-
- if (m_downloadImages) {
- Document doc = Jsoup.parse(article.content);
-
- if (doc != null) {
- Elements images = doc.select("img");
-
- for (Element img : images) {
- String url = img.attr("src");
-
- if (url.indexOf("://") != -1) {
- if (!ImageCacheService.isUrlCached(OfflineDownloadService.this, url)) {
- Intent intent = new Intent(OfflineDownloadService.this,
- ImageCacheService.class);
-
- intent.putExtra("url", url);
- startService(intent);
- }
- }
- }
- }
- }
-
- try {
- stmtInsert.execute();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
-
- m_articleOffset += m_articles.size();
-
- Log.d(TAG, "offline: received " + m_articles.size() + " articles; canProc=" + m_canProceed);
-
- stmtInsert.close();
-
- } catch (Exception e) {
- updateNotification(R.string.offline_switch_error);
- Log.d(TAG, "offline: failed: exception when loading articles");
- e.printStackTrace();
- downloadFailed();
- }
-
- }
-
- return content;
- }
-
- @Override
- protected void onPostExecute(JsonElement content) {
- if (content != null) {
-
- if (m_canProceed && m_articles != null) {
- if (m_articles.size() == OFFLINE_SYNC_SEQ && m_articleOffset < m_syncMax) {
- downloadArticles();
- } else {
- downloadComplete();
- }
- } else {
- downloadFailed();
- }
-
- } else {
- Log.d(TAG, "offline: failed: " + getErrorMessage());
- updateNotification(getErrorMessage());
- downloadFailed();
- }
- }
- }
-
- @Override
- public void onStart(Intent intent, int startId) {
- try {
- if (getWritableDb().isDbLockedByCurrentThread() || getWritableDb().isDbLockedByOtherThreads()) {
- return;
- }
-
- m_sessionId = intent.getStringExtra("sessionId");
-
- if (!m_downloadInProgress) {
- if (m_downloadImages) ImageCacheService.cleanupCache(this, false);
-
- updateNotification(R.string.notify_downloading_init);
- m_downloadInProgress = true;
-
- downloadCategories();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
+package org.fox.ttrss.offline; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.List; + +import org.fox.ttrss.ApiRequest; +import org.fox.ttrss.OnlineActivity; +import org.fox.ttrss.R; +import org.fox.ttrss.types.Article; +import org.fox.ttrss.types.Feed; +import org.fox.ttrss.types.FeedCategory; +import org.fox.ttrss.util.DatabaseHelper; +import org.fox.ttrss.util.ImageCacheService; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import android.app.ActivityManager; +import android.app.ActivityManager.RunningServiceInfo; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteStatement; +import android.os.Binder; +import android.os.IBinder; +import android.preference.PreferenceManager; +import android.provider.BaseColumns; +import android.util.Log; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; + +public class OfflineDownloadService extends Service { + + private final String TAG = this.getClass().getSimpleName(); + + public static final int NOTIFY_DOWNLOADING = 1; + public static final String INTENT_ACTION_SUCCESS = "org.fox.ttrss.intent.action.DownloadComplete"; + public static final String INTENT_ACTION_CANCEL = "org.fox.ttrss.intent.action.Cancel"; + + private static final int OFFLINE_SYNC_SEQ = 50; + private static final int OFFLINE_SYNC_MAX = OFFLINE_SYNC_SEQ * 10; + + private SQLiteDatabase m_writableDb; + private SQLiteDatabase m_readableDb; + private int m_articleOffset = 0; + private String m_sessionId; + private NotificationManager m_nmgr; + + private boolean m_downloadInProgress = false; + private boolean m_downloadImages = false; + private int m_syncMax; + private SharedPreferences m_prefs; + private boolean m_canProceed = true; + + private final IBinder m_binder = new LocalBinder(); + + public class LocalBinder extends Binder { + OfflineDownloadService getService() { + return OfflineDownloadService.this; + } + } + + @Override + public IBinder onBind(Intent intent) { + return m_binder; + } + + @Override + public void onCreate() { + super.onCreate(); + m_nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); + m_prefs = PreferenceManager + .getDefaultSharedPreferences(getApplicationContext()); + + m_downloadImages = m_prefs.getBoolean("offline_image_cache_enabled", false); + m_syncMax = Integer.parseInt(m_prefs.getString("offline_sync_max", String.valueOf(OFFLINE_SYNC_MAX))); + + initDatabase(); + } + + @SuppressWarnings("deprecation") + private void updateNotification(String msg) { + Notification notification = new Notification(R.drawable.icon, + getString(R.string.notify_downloading_title), System.currentTimeMillis()); + + Intent intent = new Intent(this, OnlineActivity.class); + intent.setAction(INTENT_ACTION_CANCEL); + + PendingIntent contentIntent = PendingIntent.getActivity(this, 0, + intent, 0); + + notification.flags |= Notification.FLAG_ONGOING_EVENT; + notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE; + + notification.setLatestEventInfo(this, getString(R.string.notify_downloading_title), msg, contentIntent); + + m_nmgr.notify(NOTIFY_DOWNLOADING, notification); + } + + private void updateNotification(int msgResId) { + updateNotification(getString(msgResId)); + } + + private void downloadFailed() { + m_readableDb.close(); + m_writableDb.close(); + + m_nmgr.cancel(NOTIFY_DOWNLOADING); + + // TODO send notification to activity? + + m_downloadInProgress = false; + stopSelf(); + } + + private boolean isCacheServiceRunning() { + ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); + for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { + if ("org.fox.ttrss.ImageCacheService".equals(service.service.getClassName())) { + return true; + } + } + return false; + } + + public void downloadComplete() { + m_downloadInProgress = false; + + // if cache service is running, it will send a finished intent on its own + if (!isCacheServiceRunning()) { + m_nmgr.cancel(NOTIFY_DOWNLOADING); + + Intent intent = new Intent(); + intent.setAction(INTENT_ACTION_SUCCESS); + intent.addCategory(Intent.CATEGORY_DEFAULT); + sendBroadcast(intent); + } else { + updateNotification(getString(R.string.notify_downloading_images, 0)); + } + + m_readableDb.close(); + m_writableDb.close(); + + stopSelf(); + } + + private void initDatabase() { + DatabaseHelper dh = new DatabaseHelper(getApplicationContext()); + m_writableDb = dh.getWritableDatabase(); + m_readableDb = dh.getReadableDatabase(); + } + + /* private synchronized SQLiteDatabase getReadableDb() { + return m_readableDb; + } */ + + private synchronized SQLiteDatabase getWritableDb() { + return m_writableDb; + } + + @SuppressWarnings("unchecked") + private void downloadArticles() { + Log.d(TAG, "offline: downloading articles... offset=" + m_articleOffset); + + updateNotification(getString(R.string.notify_downloading_articles, m_articleOffset)); + + OfflineArticlesRequest req = new OfflineArticlesRequest(this); + + @SuppressWarnings("serial") + HashMap<String,String> map = new HashMap<String,String>() { + { + put("op", "getHeadlines"); + put("sid", m_sessionId); + put("feed_id", "-4"); + put("view_mode", "unread"); + put("show_content", "true"); + put("skip", String.valueOf(m_articleOffset)); + put("limit", String.valueOf(OFFLINE_SYNC_SEQ)); + } + }; + + req.execute(map); + } + + private void downloadFeeds() { + + updateNotification(R.string.notify_downloading_feeds); + + getWritableDb().execSQL("DELETE FROM feeds;"); + + ApiRequest req = new ApiRequest(getApplicationContext()) { + @Override + protected JsonElement doInBackground(HashMap<String, String>... params) { + JsonElement content = super.doInBackground(params); + + if (content != null) { + + try { + Type listType = new TypeToken<List<Feed>>() {}.getType(); + List<Feed> feeds = new Gson().fromJson(content, listType); + + SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO feeds " + + "("+BaseColumns._ID+", title, feed_url, has_icon, cat_id) " + + "VALUES (?, ?, ?, ?, ?);"); + + for (Feed feed : feeds) { + stmtInsert.bindLong(1, feed.id); + stmtInsert.bindString(2, feed.title); + stmtInsert.bindString(3, feed.feed_url); + stmtInsert.bindLong(4, feed.has_icon ? 1 : 0); + stmtInsert.bindLong(5, feed.cat_id); + + stmtInsert.execute(); + } + + stmtInsert.close(); + + Log.d(TAG, "offline: done downloading feeds"); + + m_articleOffset = 0; + + getWritableDb().execSQL("DELETE FROM articles;"); + } catch (Exception e) { + e.printStackTrace(); + updateNotification(R.string.offline_switch_error); + downloadFailed(); + } + } + + return content; + } + + @Override + protected void onPostExecute(JsonElement content) { + if (content != null) { + if (m_canProceed) { + downloadArticles(); + } else { + downloadFailed(); + } + } else { + updateNotification(getErrorMessage()); + downloadFailed(); + } + } + + }; + + @SuppressWarnings("serial") + HashMap<String,String> map = new HashMap<String,String>() { + { + put("op", "getFeeds"); + put("sid", m_sessionId); + put("cat_id", "-3"); + put("unread_only", "true"); + } + }; + + req.execute(map); + } + + private void downloadCategories() { + + updateNotification(R.string.notify_downloading_feeds); + + getWritableDb().execSQL("DELETE FROM categories;"); + + ApiRequest req = new ApiRequest(getApplicationContext()) { + protected JsonElement doInBackground(HashMap<String, String>... params) { + JsonElement content = super.doInBackground(params); + + if (content != null) { + try { + Type listType = new TypeToken<List<FeedCategory>>() {}.getType(); + List<FeedCategory> cats = new Gson().fromJson(content, listType); + + SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO categories " + + "("+BaseColumns._ID+", title) " + + "VALUES (?, ?);"); + + for (FeedCategory cat : cats) { + stmtInsert.bindLong(1, cat.id); + stmtInsert.bindString(2, cat.title); + + stmtInsert.execute(); + } + + stmtInsert.close(); + + Log.d(TAG, "offline: done downloading categories"); + + } catch (Exception e) { + e.printStackTrace(); + updateNotification(R.string.offline_switch_error); + downloadFailed(); + } + } + + return content; + } + @Override + protected void onPostExecute(JsonElement content) { + if (content != null) { + if (m_canProceed) { + downloadFeeds(); + } else { + downloadFailed(); + } + } else { + updateNotification(getErrorMessage()); + downloadFailed(); + } + } + + }; + + @SuppressWarnings("serial") + HashMap<String,String> map = new HashMap<String,String>() { + { + put("op", "getCategories"); + put("sid", m_sessionId); + //put("cat_id", "-3"); + put("unread_only", "true"); + } + }; + + req.execute(map); + } + + + @Override + public void onDestroy() { + super.onDestroy(); + m_nmgr.cancel(NOTIFY_DOWNLOADING); + + m_canProceed = false; + Log.d(TAG, "onDestroy"); + + //m_readableDb.close(); + //m_writableDb.close(); + } + + public class OfflineArticlesRequest extends ApiRequest { + List<Article> m_articles; + + public OfflineArticlesRequest(Context context) { + super(context); + } + + @Override + protected JsonElement doInBackground(HashMap<String, String>... params) { + JsonElement content = super.doInBackground(params); + + if (content != null) { + + try { + Type listType = new TypeToken<List<Article>>() {}.getType(); + m_articles = new Gson().fromJson(content, listType); + + SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO articles " + + "("+BaseColumns._ID+", unread, marked, published, updated, is_updated, title, link, feed_id, tags, content) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); + + for (Article article : m_articles) { + + String tagsString = ""; + + for (String t : article.tags) { + tagsString += t + ", "; + } + + tagsString = tagsString.replaceAll(", $", ""); + + stmtInsert.bindLong(1, article.id); + stmtInsert.bindLong(2, article.unread ? 1 : 0); + stmtInsert.bindLong(3, article.marked ? 1 : 0); + stmtInsert.bindLong(4, article.published ? 1 : 0); + stmtInsert.bindLong(5, article.updated); + stmtInsert.bindLong(6, article.is_updated ? 1 : 0); + stmtInsert.bindString(7, article.title); + stmtInsert.bindString(8, article.link); + stmtInsert.bindLong(9, article.feed_id); + stmtInsert.bindString(10, tagsString); // comma-separated tags + stmtInsert.bindString(11, article.content); + + if (m_downloadImages) { + Document doc = Jsoup.parse(article.content); + + if (doc != null) { + Elements images = doc.select("img"); + + for (Element img : images) { + String url = img.attr("src"); + + if (url.indexOf("://") != -1) { + if (!ImageCacheService.isUrlCached(OfflineDownloadService.this, url)) { + Intent intent = new Intent(OfflineDownloadService.this, + ImageCacheService.class); + + intent.putExtra("url", url); + startService(intent); + } + } + } + } + } + + try { + stmtInsert.execute(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + m_articleOffset += m_articles.size(); + + Log.d(TAG, "offline: received " + m_articles.size() + " articles; canProc=" + m_canProceed); + + stmtInsert.close(); + + } catch (Exception e) { + updateNotification(R.string.offline_switch_error); + Log.d(TAG, "offline: failed: exception when loading articles"); + e.printStackTrace(); + downloadFailed(); + } + + } + + return content; + } + + @Override + protected void onPostExecute(JsonElement content) { + if (content != null) { + + if (m_canProceed && m_articles != null) { + if (m_articles.size() == OFFLINE_SYNC_SEQ && m_articleOffset < m_syncMax) { + downloadArticles(); + } else { + downloadComplete(); + } + } else { + downloadFailed(); + } + + } else { + Log.d(TAG, "offline: failed: " + getErrorMessage()); + updateNotification(getErrorMessage()); + downloadFailed(); + } + } + } + + @Override + public void onStart(Intent intent, int startId) { + try { + if (getWritableDb().isDbLockedByCurrentThread() || getWritableDb().isDbLockedByOtherThreads()) { + return; + } + + m_sessionId = intent.getStringExtra("sessionId"); + + if (!m_downloadInProgress) { + if (m_downloadImages) ImageCacheService.cleanupCache(this, false); + + updateNotification(R.string.notify_downloading_init); + m_downloadInProgress = true; + + downloadCategories(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} |