summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/org/fox/ttrss/MainActivity.java224
-rw-r--r--src/org/fox/ttrss/OfflineActivity.java4
-rw-r--r--src/org/fox/ttrss/OfflineDownloadService.java400
-rw-r--r--src/org/fox/ttrss/OfflineFeedsFragment.java2
4 files changed, 467 insertions, 163 deletions
diff --git a/src/org/fox/ttrss/MainActivity.java b/src/org/fox/ttrss/MainActivity.java
index 4385c9fe..5fef0277 100644
--- a/src/org/fox/ttrss/MainActivity.java
+++ b/src/org/fox/ttrss/MainActivity.java
@@ -8,9 +8,13 @@ import java.util.TimerTask;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.database.Cursor;
@@ -19,6 +23,7 @@ import android.database.sqlite.SQLiteStatement;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
+import android.os.IBinder;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
import android.support.v4.app.FragmentActivity;
@@ -43,8 +48,6 @@ import com.google.gson.reflect.TypeToken;
public class MainActivity extends FragmentActivity implements OnlineServices {
private final String TAG = this.getClass().getSimpleName();
- private final int OFFLINE_SYNC_SEQ = 60;
- private final int OFFLINE_SYNC_MAX = 500;
private SharedPreferences m_prefs;
private String m_themeName = "";
@@ -62,11 +65,37 @@ public class MainActivity extends FragmentActivity implements OnlineServices {
private boolean m_enableCats = false;
private int m_isLicensed = -1;
private int m_apiLevel = 0;
- private int m_articleOffset = 0;
private boolean m_isOffline = false;
private SQLiteDatabase m_readableDb;
private SQLiteDatabase m_writableDb;
+
+
+ private BroadcastReceiver m_broadcastReceiver = new BroadcastReceiver() {
+
+ @Override
+ public void onReceive(Context content, Intent intent) {
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this).
+ setMessage(R.string.dialog_offline_success).
+ setPositiveButton(R.string.dialog_offline_go, new Dialog.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ Intent refresh = new Intent(MainActivity.this, OfflineActivity.class);
+ startActivity(refresh);
+ finish();
+ }
+ }).
+ setNegativeButton(R.string.dialog_cancel, new Dialog.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ //
+ }
+ });
+
+ AlertDialog dlg = builder.create();
+ dlg.show();
+
+ }
+ };
public void updateHeadlines() {
HeadlinesFragment frag = (HeadlinesFragment)getSupportFragmentManager().findFragmentById(R.id.headlines_fragment);
@@ -311,13 +340,13 @@ public class MainActivity extends FragmentActivity implements OnlineServices {
return m_unreadOnly;
}
- private void setUnreadArticlesOnly(boolean unread) {
+ /* private void setUnreadArticlesOnly(boolean unread) {
m_unreadArticlesOnly = unread;
HeadlinesFragment frag = (HeadlinesFragment)getSupportFragmentManager().findFragmentById(R.id.headlines_fragment);
if (frag != null) frag.refresh(false);
- }
+ } */
@Override
public boolean getUnreadArticlesOnly() {
@@ -376,6 +405,11 @@ public class MainActivity extends FragmentActivity implements OnlineServices {
initDatabase();
+ IntentFilter filter = new IntentFilter("org.fox.ttrss.intent.action.DownloadComplete");
+ filter.addCategory(Intent.CATEGORY_DEFAULT);
+
+ registerReceiver(m_broadcastReceiver, filter);
+
m_isOffline = m_prefs.getBoolean("offline_mode_active", false);
Log.d(TAG, "m_isOffline=" + m_isOffline);
@@ -460,27 +494,6 @@ public class MainActivity extends FragmentActivity implements OnlineServices {
}
@SuppressWarnings("unchecked")
- private void offlineGetArticles() {
- Log.d(TAG, "offline: downloading articles... offset=" + m_articleOffset);
-
- OfflineArticlesRequest req = new OfflineArticlesRequest(this);
-
- 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);
- }
-
- @SuppressWarnings("unchecked")
private void switchOffline() {
AlertDialog.Builder builder = new AlertDialog.Builder(this).
@@ -488,75 +501,30 @@ public class MainActivity extends FragmentActivity implements OnlineServices {
setPositiveButton(R.string.dialog_offline_go, new Dialog.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
- Log.d(TAG, "offline: starting");
-
if (m_sessionId != null) {
-
- findViewById(R.id.loading_container).setVisibility(View.VISIBLE);
- findViewById(R.id.main).setVisibility(View.INVISIBLE);
-
- setLoadingStatus(R.string.offline_downloading, true);
-
- // Download feeds
-
- getWritableDb().execSQL("DELETE FROM feeds;");
-
- ApiRequest req = new ApiRequest(getApplicationContext()) {
- @Override
- protected void onPostExecute(JsonElement content) {
- 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: starting");
- Log.d(TAG, "offline: done downloading feeds");
-
- m_articleOffset = 0;
-
- getWritableDb().execSQL("DELETE FROM articles;");
-
- offlineGetArticles();
- } catch (Exception e) {
- e.printStackTrace();
- setLoadingStatus(R.string.offline_switch_error, false);
- }
-
- } else {
- setLoadingStatus(getErrorMessage(), false);
- // TODO error, could not download feeds, properly report API error (toast)
- }
+ ServiceConnection m_serviceConnection = new ServiceConnection() {
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.d(TAG, "download service disconnected");
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ Log.d(TAG, "download service connected");
+ //((OfflineDownloadService.LocalBinder)service).getService().download();
}
};
- HashMap<String,String> map = new HashMap<String,String>() {
- {
- put("op", "getFeeds");
- put("sid", m_sessionId);
- put("cat_id", "-3");
- put("unread_only", "true");
- }
- };
+ Intent intent = new Intent(MainActivity.this, OfflineDownloadService.class);
+ intent.putExtra("sessionId", m_sessionId);
- req.execute(map);
- } else {
- switchOfflineSuccess();
+ startService(intent);
+
+ //bindService(intent, m_serviceConnection, Context.BIND_AUTO_CREATE);
+
}
}
}).
@@ -1082,6 +1050,8 @@ public class MainActivity extends FragmentActivity implements OnlineServices {
public void onDestroy() {
super.onDestroy();
+ unregisterReceiver(m_broadcastReceiver);
+
m_readableDb.close();
m_writableDb.close();
@@ -1340,7 +1310,7 @@ public class MainActivity extends FragmentActivity implements OnlineServices {
if (hasOfflineData()) {
- AlertDialog.Builder builder = new AlertDialog.Builder(m_context).
+ AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this).
setMessage(R.string.dialog_offline_prompt).
setPositiveButton(R.string.dialog_offline_go, new Dialog.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
@@ -1514,7 +1484,7 @@ public class MainActivity extends FragmentActivity implements OnlineServices {
} else {
- LoginRequest ar = new LoginRequest(this); // do not use getApplicationContext() here because alertdialog chokes on it
+ LoginRequest ar = new LoginRequest(getApplicationContext());
HashMap<String,String> map = new HashMap<String,String>() {
{
@@ -1770,78 +1740,6 @@ public class MainActivity extends FragmentActivity implements OnlineServices {
viewCategory(cat, browse && cat.id >= 0);
}
- public class OfflineArticlesRequest extends ApiRequest {
- public OfflineArticlesRequest(Context context) {
- super(context);
- }
-
- @Override
- protected void onPostExecute(JsonElement content) {
- if (content != null) {
- try {
- Type listType = new TypeToken<List<Article>>() {}.getType();
- List<Article> 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 : 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);
-
- try {
- stmtInsert.execute();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
-
- stmtInsert.close();
-
- //m_canGetMoreArticles = articles.size() == 30;
- m_articleOffset += articles.size();
-
- Log.d(TAG, "offline: received " + articles.size() + " articles");
-
- if (articles.size() == OFFLINE_SYNC_SEQ && m_articleOffset < OFFLINE_SYNC_MAX) {
- offlineGetArticles();
- } else {
- switchOfflineSuccess();
- }
-
- return;
-
- } catch (Exception e) {
- setLoadingStatus(R.string.offline_switch_error, false);
- Log.d(TAG, "offline: failed: exception when loading articles");
- e.printStackTrace();
- }
-
- } else {
- Log.d(TAG, "offline: failed: " + getErrorMessage());
- setLoadingStatus(getErrorMessage(), false);
- }
- }
- }
} \ No newline at end of file
diff --git a/src/org/fox/ttrss/OfflineActivity.java b/src/org/fox/ttrss/OfflineActivity.java
index 9ea3252d..4f6befd0 100644
--- a/src/org/fox/ttrss/OfflineActivity.java
+++ b/src/org/fox/ttrss/OfflineActivity.java
@@ -4,6 +4,7 @@ import org.fox.ttrss.OnlineServices.RelativeArticle;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.app.NotificationManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -63,6 +64,9 @@ public class OfflineActivity extends FragmentActivity implements OfflineServices
}
super.onCreate(savedInstanceState);
+
+ NotificationManager nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+ nmgr.cancel(OfflineDownloadService.NOTIFY_DOWNLOADING);
m_themeName = m_prefs.getString("theme", "THEME_DARK");
diff --git a/src/org/fox/ttrss/OfflineDownloadService.java b/src/org/fox/ttrss/OfflineDownloadService.java
new file mode 100644
index 00000000..e770bad6
--- /dev/null
+++ b/src/org/fox/ttrss/OfflineDownloadService.java
@@ -0,0 +1,400 @@
+package org.fox.ttrss;
+
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.List;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.IntentService;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteStatement;
+import android.os.Bundle;
+import android.os.IBinder;
+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 IntentService {
+
+ private final String TAG = this.getClass().getSimpleName();
+
+ public static final int NOTIFY_DOWNLOADING = 1;
+
+ private static final int OFFLINE_SYNC_SEQ = 60;
+ private static final int OFFLINE_SYNC_MAX = 60; //500
+
+ 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;
+
+ public OfflineDownloadService() {
+ super("OfflineDownloadService");
+ }
+
+ public OfflineDownloadService(String name) {
+ super(name);
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ m_nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+ initDatabase();
+ }
+
+ public boolean getDownloadInProgress() {
+ return m_downloadInProgress;
+ }
+
+ private void updateNotification(String msg) {
+ Notification notification = new Notification(R.drawable.icon,
+ getString(R.string.app_name), System.currentTimeMillis());
+
+ PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+ new Intent(this, MainActivity.class), 0);
+
+ notification.setLatestEventInfo(this, getString(R.string.go_offline), msg, contentIntent);
+
+ m_nmgr.notify(NOTIFY_DOWNLOADING, notification);
+ }
+
+ private void updateNotification(int msgResId) {
+ updateNotification(getString(msgResId));
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ public void downloadComplete() {
+ m_downloadInProgress = false;
+
+ m_nmgr.cancel(NOTIFY_DOWNLOADING);
+
+ Intent intent = new Intent();
+ intent.setAction("org.fox.ttrss.intent.action.DownloadComplete");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ sendBroadcast(intent);
+
+ m_readableDb.close();
+ m_writableDb.close();
+ }
+
+ private void initDatabase() {
+ DatabaseHelper dh = new DatabaseHelper(getApplicationContext());
+ m_writableDb = dh.getWritableDatabase();
+ m_readableDb = dh.getReadableDatabase();
+ }
+
+ public synchronized SQLiteDatabase getReadableDb() {
+ return m_readableDb;
+ }
+
+ public 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);
+
+ 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() {
+ //findViewById(R.id.loading_container).setVisibility(View.VISIBLE);
+ //findViewById(R.id.main).setVisibility(View.INVISIBLE);
+
+ //setLoadingStatus(R.string.offline_downloading, true);
+
+ // Download feeds
+
+ updateNotification(R.string.notify_downloading_feeds);
+
+ getWritableDb().execSQL("DELETE FROM feeds;");
+
+ ApiRequest req = new ApiRequest(getApplicationContext()) {
+ @Override
+ protected void onPostExecute(JsonElement content) {
+ 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;");
+ downloadArticles();
+ } catch (Exception e) {
+ e.printStackTrace();
+ updateNotification(R.string.offline_switch_error);
+ m_downloadInProgress = false;
+ //setLoadingStatus(R.string.offline_switch_error, false);
+ }
+
+ } else {
+ updateNotification(getErrorMessage());
+ m_downloadInProgress = false;
+ // TODO error, could not download feeds, properly report API error (toast)
+ }
+ }
+
+ };
+
+ 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);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void switchOffline() {
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this).
+ setMessage(R.string.dialog_offline_switch_prompt).
+ setPositiveButton(R.string.dialog_offline_go, new Dialog.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+
+ Log.d(TAG, "offline: starting");
+
+ if (m_sessionId != null) {
+
+ //findViewById(R.id.loading_container).setVisibility(View.VISIBLE);
+ //findViewById(R.id.main).setVisibility(View.INVISIBLE);
+
+ //setLoadingStatus(R.string.offline_downloading, true);
+
+ // Download feeds
+
+ getWritableDb().execSQL("DELETE FROM feeds;");
+
+ ApiRequest req = new ApiRequest(getApplicationContext()) {
+ @Override
+ protected void onPostExecute(JsonElement content) {
+ 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;");
+
+ downloadArticles();
+ } catch (Exception e) {
+ e.printStackTrace();
+ //setLoadingStatus(R.string.offline_switch_error, false);
+ }
+
+ } else {
+ //setLoadingStatus(getErrorMessage(), false);
+ // TODO error, could not download feeds, properly report API error (toast)
+ }
+ }
+ };
+
+ 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);
+ } else {
+ downloadComplete();
+ }
+ }
+ }).
+ setNegativeButton(R.string.dialog_cancel, new Dialog.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ //
+ }
+ });
+
+ AlertDialog dlg = builder.create();
+ dlg.show();
+
+ }
+
+ public void download() {
+ if (!m_downloadInProgress) {
+ updateNotification(R.string.notify_downloading_init);
+ m_downloadInProgress = true;
+
+ downloadFeeds();
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ m_nmgr.cancel(NOTIFY_DOWNLOADING);
+
+ //m_readableDb.close();
+ //m_writableDb.close();
+ }
+
+ public class OfflineArticlesRequest extends ApiRequest {
+ public OfflineArticlesRequest(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void onPostExecute(JsonElement content) {
+ if (content != null) {
+ try {
+ Type listType = new TypeToken<List<Article>>() {}.getType();
+ List<Article> 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 : 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);
+
+ try {
+ stmtInsert.execute();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ stmtInsert.close();
+
+ //m_canGetMoreArticles = articles.size() == 30;
+ m_articleOffset += articles.size();
+
+ Log.d(TAG, "offline: received " + articles.size() + " articles");
+
+ if (articles.size() == OFFLINE_SYNC_SEQ && m_articleOffset < OFFLINE_SYNC_MAX) {
+ downloadArticles();
+ } else {
+ downloadComplete();
+ }
+
+ return;
+
+ } catch (Exception e) {
+ updateNotification(R.string.offline_switch_error);
+ Log.d(TAG, "offline: failed: exception when loading articles");
+ e.printStackTrace();
+ m_downloadInProgress = false;
+ }
+
+ } else {
+ Log.d(TAG, "offline: failed: " + getErrorMessage());
+ m_downloadInProgress = false;
+ updateNotification(getErrorMessage());
+ }
+ }
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ Bundle extras = intent.getExtras();
+
+ m_sessionId = extras.getString("sessionId");
+
+ download();
+ }
+}
diff --git a/src/org/fox/ttrss/OfflineFeedsFragment.java b/src/org/fox/ttrss/OfflineFeedsFragment.java
index c0de692b..7c866bfe 100644
--- a/src/org/fox/ttrss/OfflineFeedsFragment.java
+++ b/src/org/fox/ttrss/OfflineFeedsFragment.java
@@ -253,6 +253,8 @@ public class OfflineFeedsFragment extends Fragment implements OnItemClickListene
public void sortFeeds() {
try {
refresh();
+ } catch (NullPointerException e) {
+ // activity is gone?
} catch (IllegalStateException e) {
// we're probably closing and DB is gone already
}