Option to disable background syncs.

This commit is contained in:
dosiecki 2014-06-03 20:21:02 -07:00
parent 3f1c1bfd5d
commit d02f10a80e
7 changed files with 103 additions and 28 deletions

View file

@ -1,6 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:title="@string/settings_cat_offline">
<CheckBoxPreference
android:defaultValue="false"
android:key="enable_offline"
android:title="@string/settings_enable_offline"
android:summary="@string/settings_enable_offline_sum" >
</CheckBoxPreference>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/settings_cat_story_list">
<ListPreference

View file

@ -178,6 +178,11 @@
<string name="menu_default_view">Default View</string>
<string name="settings">Preferences</string>
<string name="settings_cat_offline">Offline</string>
<string name="settings_enable_offline">Download in Background</string>
<string name="settings_enable_offline_sum">Periodically fetch stories for offline reading</string>
<string name="settings_cat_story_list">Story List</string>
<string-array name="default_story_order_entries">
<item>@string/newest</item>

View file

@ -18,7 +18,6 @@ import com.newsblur.fragment.LogoutDialogFragment;
import com.newsblur.service.BootReceiver;
import com.newsblur.service.NBSyncService;
import com.newsblur.util.FeedUtils;
import com.newsblur.util.PrefsUtils;
import com.newsblur.view.StateToggleButton.StateChangedListener;
public class Main extends NbActivity implements StateChangedListener {
@ -26,13 +25,11 @@ public class Main extends NbActivity implements StateChangedListener {
private ActionBar actionBar;
private FolderListFragment folderFeedList;
private FragmentManager fragmentManager;
private static final String TAG = "MainActivity";
private Menu menu;
@Override
public void onCreate(Bundle savedInstanceState) {
PrefsUtils.checkForUpgrade(this);
PreferenceManager.setDefaultValues(this, R.layout.activity_settings, false);
requestWindowFeature(Window.FEATURE_PROGRESS);
@ -46,26 +43,19 @@ public class Main extends NbActivity implements StateChangedListener {
folderFeedList = (FolderListFragment) fragmentManager.findFragmentByTag("folderFeedListFragment");
folderFeedList.setRetainInstance(true);
//also make sure the interval sync is scheduled, in case it was just now enabled
// make sure the interval sync is scheduled, since we are the root Activity
BootReceiver.scheduleSyncService(this);
}
@Override
protected void onResume() {
super.onResume();
if (PrefsUtils.isTimeToAutoSync(this)) {
triggerRefresh();
}
triggerSync();
// clear all stories from the DB, the story activities will load them.
FeedUtils.clearStories(this);
}
private void triggerRefresh() {
Intent i = new Intent(this, NBSyncService.class);
startService(i);
}
private void setupActionBar() {
actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
@ -87,7 +77,8 @@ public class Main extends NbActivity implements StateChangedListener {
startActivity(profileIntent);
return true;
} else if (item.getItemId() == R.id.menu_refresh) {
triggerRefresh();
NBSyncService.forceFeedsFolders();
triggerSync();
return true;
} else if (item.getItemId() == R.id.menu_add_feed) {
Intent intent = new Intent(this, SearchForFeeds.class);

View file

@ -1,14 +1,20 @@
package com.newsblur.activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.newsblur.service.NBSyncService;
import com.newsblur.util.AppConstants;
import com.newsblur.util.PrefsUtils;
import java.util.ArrayList;
/**
* The base class for all Activities in the NewsBlur app. Handles enforcement of
* login state and tracking of sync/update broadcasts.
*/
public class NbActivity extends Activity {
private final static String UNIQUE_LOGIN_KEY = "uniqueLoginKey";
@ -48,7 +54,7 @@ public class NbActivity extends Activity {
@Override
protected void onPause() {
if (AppConstants.VERBOSE_LOG) Log.d(this.getClass().getName(), "onSuspend");
if (AppConstants.VERBOSE_LOG) Log.d(this.getClass().getName(), "onPause");
super.onPause();
synchronized (AllActivities) {
@ -71,6 +77,14 @@ public class NbActivity extends Activity {
super.onSaveInstanceState(savedInstanceState);
}
/**
* Pokes the sync service to perform any pending sync actions.
*/
protected void triggerSync() {
Intent i = new Intent(this, NBSyncService.class);
startService(i);
}
/**
* Called on each NB activity after the DB has been updated by the sync service. This method
* should return as quickly as possible.
@ -86,7 +100,8 @@ public class NbActivity extends Activity {
}
/**
* Notify all activities in the app that the DB has been updated.
* Notify all activities in the app that the DB has been updated. Should only be called
* by the sync service, which owns updating the DB.
*/
public static void updateAllActivities() {
Log.d(NbActivity.class.getName(), "updating all activities . . .");
@ -98,4 +113,13 @@ public class NbActivity extends Activity {
Log.d(NbActivity.class.getName(), " . . . done updating all activities");
}
/**
* Gets the number of active/foreground NB activities. Used by the sync service to
* determine if the app is active so we can honour user requests not to run in
* the background.
*/
public static int getActiveActivityCount() {
return AllActivities.size();
}
}

View file

@ -9,10 +9,23 @@ import android.util.Log;
import com.newsblur.R;
import com.newsblur.activity.NbActivity;
import com.newsblur.network.APIManager;
import com.newsblur.util.PrefsUtils;
/**
* A background service to handle synchronisation with the NB servers.
*
* It is the design goal of this service to handle all communication with the API.
* Activities and fragments should enqueue actions in the DB or use the methods
* provided herein to request an action and let the service handle things.
*
* Per the contract of the Service class, at most one instance shall be created. It
* will be preserved and re-used where possible. Additionally, regularly scheduled
* invocations are requested via the Main activity and BootReceiver.
*/
public class NBSyncService extends Service {
private static boolean SyncRunning = false;
private volatile static boolean SyncRunning = false;
private volatile static boolean DoFeedsFolders = false;
private APIManager apiManager;
@ -21,25 +34,35 @@ public class NBSyncService extends Service {
super.onCreate();
Log.d(this.getClass().getName(), "onCreate");
apiManager = new APIManager(this);
PrefsUtils.checkForUpgrade(this);
}
/**
* Called serially, once per "start" of the service. This serves as a wakeup call
* that the service should check for outstanding work.
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(this.getClass().getName(), "onStartCommand");
// TODO: check for sync flag or realtime flag
new Thread(new Runnable() {
public void run() {
doSync();
}
}).start();
Log.d(this.getClass().getName(), "onStartCommand complete");
if (PrefsUtils.isOfflineEnabled(this) || (NbActivity.getActiveActivityCount() > 0)) {
// Services actually get invoked on the main system thread, and are not
// allowed to do tangible work. We spawn a thread to do so.
new Thread(new Runnable() {
public void run() {
doSync();
}
}).start();
} else {
Log.d(this.getClass().getName(), "Skipping sync: app not active and background sync not enabled.");
}
// indicate to the system that the service should be alive when started, but
// needn't necessarily persist under memory pressure
return Service.START_NOT_STICKY;
}
/**
* Do the actual work of syncing.
*/
private synchronized void doSync() {
Log.d(this.getClass().getName(), "starting sync . . .");
@ -51,11 +74,18 @@ public class NBSyncService extends Service {
SyncRunning = true;
NbActivity.updateAllActivities();
apiManager.getFolderFeedMapping(true);
if (DoFeedsFolders || PrefsUtils.isTimeToAutoSync(this)) {
apiManager.getFolderFeedMapping(true);
PrefsUtils.updateLastSyncTime(this);
DoFeedsFolders = false;
}
SyncRunning = false;
NbActivity.updateAllActivities();
} catch (Exception e) {
Log.e(this.getClass().getName(), "Sync error.", e);
} finally {
wl.release();
Log.d(this.getClass().getName(), " . . . sync done");
@ -66,6 +96,14 @@ public class NBSyncService extends Service {
return SyncRunning;
}
/**
* Force a refresh of feed/folder data on the next sync, even if enough time
* hasn't passed for an autosync.
*/
public static void forceFeedsFolders() {
DoFeedsFolders = true;
}
@Override
public void onDestroy() {
Log.d(this.getClass().getName(), "onDestroy");

View file

@ -46,4 +46,6 @@ public class PrefConstants {
public static final String READING_ENTER_IMMERSIVE_SINGLE_TAP = "immersive_enter_single_tap";
public static final String STORIES_SHOW_PREVIEWS = "pref_show_content_preview";
public static final String ENABLE_OFFLINE = "enable_offline";
}

View file

@ -302,4 +302,9 @@ public class PrefsUtils {
SharedPreferences prefs = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
return prefs.getBoolean(PrefConstants.STORIES_SHOW_PREVIEWS, true);
}
public static boolean isOfflineEnabled(Context context) {
SharedPreferences prefs = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
return prefs.getBoolean(PrefConstants.ENABLE_OFFLINE, false);
}
}