move offline download stuff into an IntentService
This commit is contained in:
parent
fb14a67a2a
commit
7b5f11ee40
@ -1,37 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.fox.ttrss"
|
||||
android:versionCode="33"
|
||||
android:versionName="0.3.0">
|
||||
package="org.fox.ttrss"
|
||||
android:versionCode="33"
|
||||
android:versionName="0.3.0" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="4" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<application android:icon="@drawable/icon" android:label="@string/app_name" android:hardwareAccelerated="true">
|
||||
<activity android:name=".LoginActivity"
|
||||
android:label="@string/app_name">
|
||||
<application
|
||||
android:hardwareAccelerated="true"
|
||||
android:icon="@drawable/icon"
|
||||
android:label="@string/app_name" >
|
||||
<activity
|
||||
android:label="@string/app_name"
|
||||
android:name=".LoginActivity" >
|
||||
</activity>
|
||||
|
||||
<activity android:name=".OfflineActivity"
|
||||
android:label="@string/app_name">
|
||||
<activity
|
||||
android:label="@string/app_name"
|
||||
android:name=".OfflineActivity" >
|
||||
</activity>
|
||||
|
||||
<activity android:name=".MainActivity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<activity
|
||||
android:label="@string/app_name"
|
||||
android:name=".MainActivity" >
|
||||
<intent-filter >
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
<activity android:name=".PreferencesActivity"
|
||||
android:label="@string/preferences">
|
||||
<activity
|
||||
android:label="@string/preferences"
|
||||
android:name=".PreferencesActivity" >
|
||||
</activity>
|
||||
|
||||
<activity android:name="com.google.ads.AdActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
|
||||
|
||||
<service android:enabled="true" android:name=".OfflineDownloadService" />
|
||||
|
||||
<activity
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
|
||||
android:name="com.google.ads.AdActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -98,8 +98,12 @@
|
||||
<string name="no_feeds">No feeds to display</string>
|
||||
<string name="no_headlines">No articles to display</string>
|
||||
<string name="dialog_offline_prompt">Login failed, but you have stored offline data. Would you like to go offline?</string>
|
||||
<string name="dialog_offline_success">Offline mode is ready</string>
|
||||
<string name="dialog_offline_go">Go offline</string>
|
||||
<string name="dialog_cancel">Cancel</string>
|
||||
<string name="syncing_offline_data">Synchronizing offline data...</string>
|
||||
<string name="dialog_offline_switch_prompt">Download unread articles and go offline?</string>
|
||||
<string name="notify_downloading_articles">Downloading articles (%1$d)...</string>
|
||||
<string name="notify_downloading_init">Starting download...</string>
|
||||
<string name="notify_downloading_feeds">Downloading feeds...</string>
|
||||
</resources>
|
@ -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);
|
||||
@ -459,27 +493,6 @@ public class MainActivity extends FragmentActivity implements OnlineServices {
|
||||
return m_writableDb;
|
||||
}
|
||||
|
||||
@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() {
|
||||
|
||||
@ -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()) {
|
||||
Log.d(TAG, "offline: starting");
|
||||
|
||||
ServiceConnection m_serviceConnection = new ServiceConnection() {
|
||||
|
||||
@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;");
|
||||
|
||||
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)
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
|
||||
|
400
src/org/fox/ttrss/OfflineDownloadService.java
Normal file
400
src/org/fox/ttrss/OfflineDownloadService.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user