From 14461fa1466f52d37ae5bafffddd7d252bc34c85 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Wed, 7 Dec 2011 12:33:47 +0300 Subject: [PATCH] move offline data synchronization to an intentservice, bump version --- AndroidManifest.xml | 5 +- res/values/strings.xml | 4 + src/org/fox/ttrss/MainActivity.java | 353 +++++------------- src/org/fox/ttrss/OfflineDownloadService.java | 157 ++------ src/org/fox/ttrss/OfflineUploadService.java | 256 +++++++++++++ 5 files changed, 392 insertions(+), 383 deletions(-) create mode 100644 src/org/fox/ttrss/OfflineUploadService.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index cb75cb37..20282d97 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="36" + android:versionName="0.3.3" > @@ -37,6 +37,7 @@ + Downloading articles (%1$d)... Starting download... Downloading feeds... + Sending data to server... + Preparing offline mode + Synchronizing offline data + Finished synchronizing your offline data \ No newline at end of file diff --git a/src/org/fox/ttrss/MainActivity.java b/src/org/fox/ttrss/MainActivity.java index 27c46108..53075466 100644 --- a/src/org/fox/ttrss/MainActivity.java +++ b/src/org/fox/ttrss/MainActivity.java @@ -8,12 +8,10 @@ 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; @@ -21,7 +19,6 @@ import android.database.sqlite.SQLiteDatabase; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Bundle; -import android.os.IBinder; import android.preference.PreferenceManager; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTransaction; @@ -36,6 +33,7 @@ import android.view.animation.AnimationUtils; import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.LinearLayout; import android.widget.TextView; +import android.widget.Toast; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -60,6 +58,7 @@ public class MainActivity extends FragmentActivity implements OnlineServices { private int m_isLicensed = -1; private int m_apiLevel = 0; private boolean m_isOffline = false; + private boolean m_offlineModeReady = false; private SQLiteDatabase m_readableDb; private SQLiteDatabase m_writableDb; @@ -69,30 +68,23 @@ public class MainActivity extends FragmentActivity implements OnlineServices { @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) { - // - } - }); + if (intent.getAction().equals(OfflineDownloadService.INTENT_ACTION_SUCCESS)) { + + m_offlineModeReady = true; + + switchOffline(); + + } else if (intent.getAction().equals(OfflineUploadService.INTENT_ACTION_SUCCESS)) { + //Log.d(TAG, "offline upload service reports success"); + + if (!m_enableCats || m_activeCategory != null) + refreshFeeds(); + else + refreshCategories(); - AlertDialog dlg = builder.create(); - dlg.show(); + Toast toast = Toast.makeText(MainActivity.this, R.string.offline_sync_success, Toast.LENGTH_SHORT); + toast.show(); + } } }; @@ -133,10 +125,6 @@ public class MainActivity extends FragmentActivity implements OnlineServices { return false; } - public void clearPendingOfflineData() { - getWritableDb().execSQL("UPDATE articles SET modified = 0"); - } - private boolean hasOfflineData() { try { Cursor c = getReadableDb().query("articles", @@ -425,6 +413,7 @@ public class MainActivity extends FragmentActivity implements OnlineServices { .getParcelable("activeCategory"); m_apiLevel = savedInstanceState.getInt("apiLevel"); m_isLicensed = savedInstanceState.getInt("isLicensed"); + m_offlineModeReady = savedInstanceState.getBoolean("offlineModeReady"); } m_enableCats = m_prefs.getBoolean("enable_cats", false); @@ -446,8 +435,9 @@ public class MainActivity extends FragmentActivity implements OnlineServices { initDatabase(); - IntentFilter filter = new IntentFilter( - "org.fox.ttrss.intent.action.DownloadComplete"); + IntentFilter filter = new IntentFilter(); + filter.addAction(OfflineDownloadService.INTENT_ACTION_SUCCESS); + filter.addAction(OfflineUploadService.INTENT_ACTION_SUCCESS); filter.addCategory(Intent.CATEGORY_DEFAULT); registerReceiver(m_broadcastReceiver, filter); @@ -552,60 +542,65 @@ public class MainActivity extends FragmentActivity implements OnlineServices { @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) { - - if (m_sessionId != null) { - Log.d(TAG, "offline: starting"); - - 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(); - } - }; - - Intent intent = new Intent( + if (m_offlineModeReady) { + + 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, - OfflineDownloadService.class); - intent.putExtra("sessionId", m_sessionId); - - startService(intent); - - // bindService(intent, m_serviceConnection, - // Context.BIND_AUTO_CREATE); - + 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(); + }) + .setNegativeButton(R.string.dialog_cancel, + new Dialog.OnClickListener() { + public void onClick(DialogInterface dialog, + int which) { + // + } + }); + AlertDialog dlg = builder.create(); + dlg.show(); + + } else { + + 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) { + + if (m_sessionId != null) { + Log.d(TAG, "offline: starting"); + + Intent intent = new Intent( + MainActivity.this, + OfflineDownloadService.class); + intent.putExtra("sessionId", m_sessionId); + + startService(intent); + } + } + }) + .setNegativeButton(R.string.dialog_cancel, + new Dialog.OnClickListener() { + public void onClick(DialogInterface dialog, + int which) { + // + } + }); + + AlertDialog dlg = builder.create(); + dlg.show(); + } } private void switchOfflineSuccess() { @@ -648,6 +643,7 @@ public class MainActivity extends FragmentActivity implements OnlineServices { out.putParcelable("activeCategory", m_activeCategory); out.putInt("apiLevel", m_apiLevel); out.putInt("isLicensed", m_isLicensed); + out.putBoolean("offlineModeReady", m_offlineModeReady); } @Override @@ -1095,133 +1091,16 @@ public class MainActivity extends FragmentActivity implements OnlineServices { } - private void syncOfflineRead() { - Log.d(TAG, "syncing modified offline data... (read)"); - - final String ids = getOfflineModifiedIds(ModifiedCriteria.READ); - - if (ids.length() > 0) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - @Override - protected void onPostExecute(JsonElement result) { - if (result != null) { - syncOfflineMarked(); - } else { - setLoadingStatus(getErrorMessage(), false); - } - } - }; - - @SuppressWarnings("serial") - HashMap map = new HashMap() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", ids); - put("mode", "0"); - put("field", "2"); - } - }; - - req.execute(map); - } else { - syncOfflineMarked(); - } - } - - private void syncOfflineMarked() { - Log.d(TAG, "syncing modified offline data... (marked)"); - - final String ids = getOfflineModifiedIds(ModifiedCriteria.MARKED); - - if (ids.length() > 0) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - @Override - protected void onPostExecute(JsonElement result) { - if (result != null) { - syncOfflinePublished(); - } else { - setLoadingStatus(getErrorMessage(), false); - } - } - }; - - @SuppressWarnings("serial") - HashMap map = new HashMap() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", ids); - put("mode", "0"); - put("field", "0"); - } - }; - - req.execute(map); - } else { - syncOfflinePublished(); - } - } - - private void syncOfflinePublished() { - Log.d(TAG, "syncing modified offline data... (published)"); - - final String ids = getOfflineModifiedIds(ModifiedCriteria.MARKED); - - if (ids.length() > 0) { - ApiRequest req = new ApiRequest(getApplicationContext()) { - @Override - protected void onPostExecute(JsonElement result) { - if (result != null) { - loginSuccessInitUI(); - loginSuccess(); - clearPendingOfflineData(); - } else { - setLoadingStatus(getErrorMessage(), false); - } - } - }; - - @SuppressWarnings("serial") - HashMap map = new HashMap() { - { - put("sid", m_sessionId); - put("op", "updateArticle"); - put("article_ids", ids); - put("mode", "0"); - put("field", "1"); - } - }; - - req.execute(map); - } else { - loginSuccessInitUI(); - loginSuccess(); - clearPendingOfflineData(); - } - } - private void syncOfflineData() { - setLoadingStatus(R.string.syncing_offline_data, true); - syncOfflineRead(); - } + Log.d(TAG, "offlineSync: starting"); + + Intent intent = new Intent( + MainActivity.this, + OfflineUploadService.class); + + intent.putExtra("sessionId", m_sessionId); - private void loginSuccessInitUI() { - FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); - - if (m_enableCats) { - FeedCategoriesFragment frag = new FeedCategoriesFragment(); - ft.replace(R.id.cats_fragment, frag); - } else { - FeedsFragment frag = new FeedsFragment(); - ft.replace(R.id.feeds_fragment, frag); - } - - try { - ft.commit(); - } catch (IllegalStateException e) { - e.printStackTrace(); - } + startService(intent); } private void loginSuccess() { @@ -1248,43 +1127,6 @@ public class MainActivity extends FragmentActivity implements OnlineServices { m_refreshTimer.schedule(m_refreshTask, 60 * 1000L, 120 * 1000L); } - private enum ModifiedCriteria { - READ, MARKED, PUBLISHED - }; - - private String getOfflineModifiedIds(ModifiedCriteria criteria) { - - String criteriaStr = ""; - - switch (criteria) { - case READ: - criteriaStr = "unread = 0"; - break; - case MARKED: - criteriaStr = "marked = 1"; - break; - case PUBLISHED: - criteriaStr = "published = 1"; - break; - } - - Cursor c = getReadableDb().query("articles", null, - "modified = 1 AND " + criteriaStr, null, null, null, null); - - String tmp = ""; - - while (c.moveToNext()) { - tmp += c.getInt(0) + ","; - } - - tmp = tmp.replaceAll(",$", ""); - - // Log.d(TAG, "getOfflineModifiedIds " + criteria + " = " + tmp); - - c.close(); - - return tmp; - } private class LoginRequest extends ApiRequest { public LoginRequest(Context context) { @@ -1312,16 +1154,27 @@ public class MainActivity extends FragmentActivity implements OnlineServices { Log.d(TAG, "Received API level: " + m_apiLevel); - if (hasPendingOfflineData()) { - + if (hasPendingOfflineData()) syncOfflineData(); - // loginSuccess(); + FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); + + if (m_enableCats) { + FeedCategoriesFragment frag = new FeedCategoriesFragment(); + ft.replace(R.id.cats_fragment, frag); } else { - loginSuccessInitUI(); - loginSuccess(); + FeedsFragment frag = new FeedsFragment(); + ft.replace(R.id.feeds_fragment, frag); } + try { + ft.commit(); + } catch (IllegalStateException e) { + e.printStackTrace(); + } + + loginSuccess(); + } }; diff --git a/src/org/fox/ttrss/OfflineDownloadService.java b/src/org/fox/ttrss/OfflineDownloadService.java index 55dacced..7a44d48b 100644 --- a/src/org/fox/ttrss/OfflineDownloadService.java +++ b/src/org/fox/ttrss/OfflineDownloadService.java @@ -13,7 +13,6 @@ 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; @@ -26,6 +25,7 @@ public class OfflineDownloadService extends IntentService { 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"; private static final int OFFLINE_SYNC_SEQ = 60; private static final int OFFLINE_SYNC_MAX = 500; @@ -42,10 +42,6 @@ public class OfflineDownloadService extends IntentService { super("OfflineDownloadService"); } - public OfflineDownloadService(String name) { - super(name); - } - @Override public void onCreate() { super.onCreate(); @@ -53,18 +49,18 @@ public class OfflineDownloadService extends IntentService { initDatabase(); } - public boolean getDownloadInProgress() { + /* 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()); + getString(R.string.notify_downloading_title), System.currentTimeMillis()); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0); - notification.setLatestEventInfo(this, getString(R.string.go_offline), msg, contentIntent); + notification.setLatestEventInfo(this, getString(R.string.notify_downloading_title), msg, contentIntent); m_nmgr.notify(NOTIFY_DOWNLOADING, notification); } @@ -73,9 +69,13 @@ public class OfflineDownloadService extends IntentService { updateNotification(getString(msgResId)); } - @Override - public IBinder onBind(Intent intent) { - return null; + private void downloadFailed() { + m_readableDb.close(); + m_writableDb.close(); + + // TODO send notification to activity? + + m_downloadInProgress = false; } public void downloadComplete() { @@ -84,7 +84,7 @@ public class OfflineDownloadService extends IntentService { m_nmgr.cancel(NOTIFY_DOWNLOADING); Intent intent = new Intent(); - intent.setAction("org.fox.ttrss.intent.action.DownloadComplete"); + intent.setAction(INTENT_ACTION_SUCCESS); intent.addCategory(Intent.CATEGORY_DEFAULT); sendBroadcast(intent); @@ -98,11 +98,11 @@ public class OfflineDownloadService extends IntentService { m_readableDb = dh.getReadableDatabase(); } - public synchronized SQLiteDatabase getReadableDb() { + private synchronized SQLiteDatabase getReadableDb() { return m_readableDb; } - public synchronized SQLiteDatabase getWritableDb() { + private synchronized SQLiteDatabase getWritableDb() { return m_writableDb; } @@ -131,13 +131,7 @@ public class OfflineDownloadService extends IntentService { } 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;"); @@ -176,14 +170,12 @@ public class OfflineDownloadService extends IntentService { } catch (Exception e) { e.printStackTrace(); updateNotification(R.string.offline_switch_error); - m_downloadInProgress = false; - //setLoadingStatus(R.string.offline_switch_error, false); + downloadFailed(); } } else { updateNotification(getErrorMessage()); - m_downloadInProgress = false; - // TODO error, could not download feeds, properly report API error (toast) + downloadFailed(); } } @@ -201,106 +193,6 @@ public class OfflineDownloadService extends IntentService { 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>() {}.getType(); - List 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 map = new HashMap() { - { - 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() { @@ -377,23 +269,26 @@ public class OfflineDownloadService extends IntentService { updateNotification(R.string.offline_switch_error); Log.d(TAG, "offline: failed: exception when loading articles"); e.printStackTrace(); - m_downloadInProgress = false; + downloadFailed(); } } else { Log.d(TAG, "offline: failed: " + getErrorMessage()); - m_downloadInProgress = false; updateNotification(getErrorMessage()); + downloadFailed(); } } } @Override protected void onHandleIntent(Intent intent) { - Bundle extras = intent.getExtras(); + m_sessionId = intent.getStringExtra("sessionId"); - m_sessionId = extras.getString("sessionId"); + if (!m_downloadInProgress) { + updateNotification(R.string.notify_downloading_init); + m_downloadInProgress = true; - download(); + downloadFeeds(); + } } } diff --git a/src/org/fox/ttrss/OfflineUploadService.java b/src/org/fox/ttrss/OfflineUploadService.java new file mode 100644 index 00000000..90e0543b --- /dev/null +++ b/src/org/fox/ttrss/OfflineUploadService.java @@ -0,0 +1,256 @@ +package org.fox.ttrss; + +import java.util.HashMap; + +import com.google.gson.JsonElement; + +import android.app.IntentService; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Intent; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.util.Log; + +public class OfflineUploadService extends IntentService { + private final String TAG = this.getClass().getSimpleName(); + + public static final int NOTIFY_UPLOADING = 2; + public static final String INTENT_ACTION_SUCCESS = "org.fox.ttrss.intent.action.UploadComplete"; + + private SQLiteDatabase m_writableDb; + private SQLiteDatabase m_readableDb; + private String m_sessionId; + private NotificationManager m_nmgr; + private boolean m_uploadInProgress = false; + + public OfflineUploadService() { + super("OfflineUploadService"); + } + + @Override + public void onCreate() { + super.onCreate(); + m_nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); + initDatabase(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + + m_nmgr.cancel(NOTIFY_UPLOADING); + } + + private void updateNotification(String msg) { + Notification notification = new Notification(R.drawable.icon, + getString(R.string.notify_uploading_title), System.currentTimeMillis()); + + PendingIntent contentIntent = PendingIntent.getActivity(this, 0, + new Intent(this, MainActivity.class), 0); + + notification.setLatestEventInfo(this, getString(R.string.notify_uploading_title), msg, contentIntent); + + m_nmgr.notify(NOTIFY_UPLOADING, notification); + } + + private void updateNotification(int msgResId) { + updateNotification(getString(msgResId)); + } + + 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; + } + + private void uploadRead() { + Log.d(TAG, "syncing modified offline data... (read)"); + + final String ids = getModifiedIds(ModifiedCriteria.READ); + + if (ids.length() > 0) { + ApiRequest req = new ApiRequest(getApplicationContext()) { + @Override + protected void onPostExecute(JsonElement result) { + if (result != null) { + uploadMarked(); + } else { + updateNotification(getErrorMessage()); + uploadFailed(); + } + } + }; + + @SuppressWarnings("serial") + HashMap map = new HashMap() { + { + put("sid", m_sessionId); + put("op", "updateArticle"); + put("article_ids", ids); + put("mode", "0"); + put("field", "2"); + } + }; + + req.execute(map); + } else { + uploadMarked(); + } + } + + private enum ModifiedCriteria { + READ, MARKED, PUBLISHED + }; + + private String getModifiedIds(ModifiedCriteria criteria) { + + String criteriaStr = ""; + + switch (criteria) { + case READ: + criteriaStr = "unread = 0"; + break; + case MARKED: + criteriaStr = "marked = 1"; + break; + case PUBLISHED: + criteriaStr = "published = 1"; + break; + } + + Cursor c = getReadableDb().query("articles", null, + "modified = 1 AND " + criteriaStr, null, null, null, null); + + String tmp = ""; + + while (c.moveToNext()) { + tmp += c.getInt(0) + ","; + } + + tmp = tmp.replaceAll(",$", ""); + + c.close(); + + return tmp; + } + + private void uploadMarked() { + Log.d(TAG, "syncing modified offline data... (marked)"); + + final String ids = getModifiedIds(ModifiedCriteria.MARKED); + + if (ids.length() > 0) { + ApiRequest req = new ApiRequest(getApplicationContext()) { + @Override + protected void onPostExecute(JsonElement result) { + if (result != null) { + uploadPublished(); + } else { + updateNotification(getErrorMessage()); + uploadFailed(); + } + } + }; + + @SuppressWarnings("serial") + HashMap map = new HashMap() { + { + put("sid", m_sessionId); + put("op", "updateArticle"); + put("article_ids", ids); + put("mode", "0"); + put("field", "0"); + } + }; + + req.execute(map); + } else { + uploadPublished(); + } + } + + private void uploadFailed() { + m_readableDb.close(); + m_writableDb.close(); + + // TODO send notification to activity? + + m_uploadInProgress = false; + } + + private void uploadSuccess() { + getWritableDb().execSQL("UPDATE articles SET modified = 0"); + + Intent intent = new Intent(); + intent.setAction(INTENT_ACTION_SUCCESS); + intent.addCategory(Intent.CATEGORY_DEFAULT); + sendBroadcast(intent); + + m_readableDb.close(); + m_writableDb.close(); + + m_uploadInProgress = false; + + m_nmgr.cancel(NOTIFY_UPLOADING); + } + + private void uploadPublished() { + Log.d(TAG, "syncing modified offline data... (published)"); + + final String ids = getModifiedIds(ModifiedCriteria.MARKED); + + if (ids.length() > 0) { + ApiRequest req = new ApiRequest(getApplicationContext()) { + @Override + protected void onPostExecute(JsonElement result) { + if (result != null) { + uploadSuccess(); + } else { + updateNotification(getErrorMessage()); + uploadFailed(); + } + } + }; + + @SuppressWarnings("serial") + HashMap map = new HashMap() { + { + put("sid", m_sessionId); + put("op", "updateArticle"); + put("article_ids", ids); + put("mode", "0"); + put("field", "1"); + } + }; + + req.execute(map); + } else { + uploadSuccess(); + } + } + + + @Override + protected void onHandleIntent(Intent intent) { + m_sessionId = intent.getStringExtra("sessionId"); + + if (!m_uploadInProgress) { + m_uploadInProgress = true; + + updateNotification(R.string.notify_uploading_sending_data); + + uploadRead(); + } + } + +}