mirror of
https://github.com/viq/NewsBlur.git
synced 2025-09-18 21:43:31 +00:00
Option to disable background syncs.
This commit is contained in:
parent
3f1c1bfd5d
commit
d02f10a80e
7 changed files with 103 additions and 28 deletions
|
@ -1,6 +1,16 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
|
<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
|
<PreferenceCategory
|
||||||
android:title="@string/settings_cat_story_list">
|
android:title="@string/settings_cat_story_list">
|
||||||
<ListPreference
|
<ListPreference
|
||||||
|
|
|
@ -178,6 +178,11 @@
|
||||||
<string name="menu_default_view">Default View</string>
|
<string name="menu_default_view">Default View</string>
|
||||||
|
|
||||||
<string name="settings">Preferences</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 name="settings_cat_story_list">Story List</string>
|
||||||
<string-array name="default_story_order_entries">
|
<string-array name="default_story_order_entries">
|
||||||
<item>@string/newest</item>
|
<item>@string/newest</item>
|
||||||
|
|
|
@ -18,7 +18,6 @@ import com.newsblur.fragment.LogoutDialogFragment;
|
||||||
import com.newsblur.service.BootReceiver;
|
import com.newsblur.service.BootReceiver;
|
||||||
import com.newsblur.service.NBSyncService;
|
import com.newsblur.service.NBSyncService;
|
||||||
import com.newsblur.util.FeedUtils;
|
import com.newsblur.util.FeedUtils;
|
||||||
import com.newsblur.util.PrefsUtils;
|
|
||||||
import com.newsblur.view.StateToggleButton.StateChangedListener;
|
import com.newsblur.view.StateToggleButton.StateChangedListener;
|
||||||
|
|
||||||
public class Main extends NbActivity implements StateChangedListener {
|
public class Main extends NbActivity implements StateChangedListener {
|
||||||
|
@ -26,13 +25,11 @@ public class Main extends NbActivity implements StateChangedListener {
|
||||||
private ActionBar actionBar;
|
private ActionBar actionBar;
|
||||||
private FolderListFragment folderFeedList;
|
private FolderListFragment folderFeedList;
|
||||||
private FragmentManager fragmentManager;
|
private FragmentManager fragmentManager;
|
||||||
private static final String TAG = "MainActivity";
|
|
||||||
private Menu menu;
|
private Menu menu;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
|
||||||
PrefsUtils.checkForUpgrade(this);
|
|
||||||
PreferenceManager.setDefaultValues(this, R.layout.activity_settings, false);
|
PreferenceManager.setDefaultValues(this, R.layout.activity_settings, false);
|
||||||
|
|
||||||
requestWindowFeature(Window.FEATURE_PROGRESS);
|
requestWindowFeature(Window.FEATURE_PROGRESS);
|
||||||
|
@ -46,26 +43,19 @@ public class Main extends NbActivity implements StateChangedListener {
|
||||||
folderFeedList = (FolderListFragment) fragmentManager.findFragmentByTag("folderFeedListFragment");
|
folderFeedList = (FolderListFragment) fragmentManager.findFragmentByTag("folderFeedListFragment");
|
||||||
folderFeedList.setRetainInstance(true);
|
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);
|
BootReceiver.scheduleSyncService(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
if (PrefsUtils.isTimeToAutoSync(this)) {
|
triggerSync();
|
||||||
triggerRefresh();
|
|
||||||
}
|
|
||||||
// clear all stories from the DB, the story activities will load them.
|
// clear all stories from the DB, the story activities will load them.
|
||||||
FeedUtils.clearStories(this);
|
FeedUtils.clearStories(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void triggerRefresh() {
|
|
||||||
Intent i = new Intent(this, NBSyncService.class);
|
|
||||||
startService(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupActionBar() {
|
private void setupActionBar() {
|
||||||
actionBar = getActionBar();
|
actionBar = getActionBar();
|
||||||
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
|
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
|
||||||
|
@ -87,7 +77,8 @@ public class Main extends NbActivity implements StateChangedListener {
|
||||||
startActivity(profileIntent);
|
startActivity(profileIntent);
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.menu_refresh) {
|
} else if (item.getItemId() == R.id.menu_refresh) {
|
||||||
triggerRefresh();
|
NBSyncService.forceFeedsFolders();
|
||||||
|
triggerSync();
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.menu_add_feed) {
|
} else if (item.getItemId() == R.id.menu_add_feed) {
|
||||||
Intent intent = new Intent(this, SearchForFeeds.class);
|
Intent intent = new Intent(this, SearchForFeeds.class);
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
package com.newsblur.activity;
|
package com.newsblur.activity;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.newsblur.service.NBSyncService;
|
||||||
import com.newsblur.util.AppConstants;
|
import com.newsblur.util.AppConstants;
|
||||||
import com.newsblur.util.PrefsUtils;
|
import com.newsblur.util.PrefsUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
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 {
|
public class NbActivity extends Activity {
|
||||||
|
|
||||||
private final static String UNIQUE_LOGIN_KEY = "uniqueLoginKey";
|
private final static String UNIQUE_LOGIN_KEY = "uniqueLoginKey";
|
||||||
|
@ -48,7 +54,7 @@ public class NbActivity extends Activity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
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();
|
super.onPause();
|
||||||
|
|
||||||
synchronized (AllActivities) {
|
synchronized (AllActivities) {
|
||||||
|
@ -71,6 +77,14 @@ public class NbActivity extends Activity {
|
||||||
super.onSaveInstanceState(savedInstanceState);
|
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
|
* Called on each NB activity after the DB has been updated by the sync service. This method
|
||||||
* should return as quickly as possible.
|
* 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() {
|
public static void updateAllActivities() {
|
||||||
Log.d(NbActivity.class.getName(), "updating all activities . . .");
|
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");
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,23 @@ import android.util.Log;
|
||||||
import com.newsblur.R;
|
import com.newsblur.R;
|
||||||
import com.newsblur.activity.NbActivity;
|
import com.newsblur.activity.NbActivity;
|
||||||
import com.newsblur.network.APIManager;
|
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 {
|
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;
|
private APIManager apiManager;
|
||||||
|
|
||||||
|
@ -21,25 +34,35 @@ public class NBSyncService extends Service {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
Log.d(this.getClass().getName(), "onCreate");
|
Log.d(this.getClass().getName(), "onCreate");
|
||||||
apiManager = new APIManager(this);
|
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
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
Log.d(this.getClass().getName(), "onStartCommand");
|
if (PrefsUtils.isOfflineEnabled(this) || (NbActivity.getActiveActivityCount() > 0)) {
|
||||||
|
// Services actually get invoked on the main system thread, and are not
|
||||||
// TODO: check for sync flag or realtime flag
|
// allowed to do tangible work. We spawn a thread to do so.
|
||||||
|
new Thread(new Runnable() {
|
||||||
new Thread(new Runnable() {
|
public void run() {
|
||||||
public void run() {
|
doSync();
|
||||||
doSync();
|
}
|
||||||
}
|
}).start();
|
||||||
}).start();
|
} else {
|
||||||
|
Log.d(this.getClass().getName(), "Skipping sync: app not active and background sync not enabled.");
|
||||||
Log.d(this.getClass().getName(), "onStartCommand complete");
|
}
|
||||||
|
|
||||||
|
// 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;
|
return Service.START_NOT_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do the actual work of syncing.
|
||||||
|
*/
|
||||||
private synchronized void doSync() {
|
private synchronized void doSync() {
|
||||||
Log.d(this.getClass().getName(), "starting sync . . .");
|
Log.d(this.getClass().getName(), "starting sync . . .");
|
||||||
|
|
||||||
|
@ -51,11 +74,18 @@ public class NBSyncService extends Service {
|
||||||
SyncRunning = true;
|
SyncRunning = true;
|
||||||
NbActivity.updateAllActivities();
|
NbActivity.updateAllActivities();
|
||||||
|
|
||||||
apiManager.getFolderFeedMapping(true);
|
|
||||||
|
if (DoFeedsFolders || PrefsUtils.isTimeToAutoSync(this)) {
|
||||||
|
apiManager.getFolderFeedMapping(true);
|
||||||
|
PrefsUtils.updateLastSyncTime(this);
|
||||||
|
DoFeedsFolders = false;
|
||||||
|
}
|
||||||
|
|
||||||
SyncRunning = false;
|
SyncRunning = false;
|
||||||
NbActivity.updateAllActivities();
|
NbActivity.updateAllActivities();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(this.getClass().getName(), "Sync error.", e);
|
||||||
} finally {
|
} finally {
|
||||||
wl.release();
|
wl.release();
|
||||||
Log.d(this.getClass().getName(), " . . . sync done");
|
Log.d(this.getClass().getName(), " . . . sync done");
|
||||||
|
@ -66,6 +96,14 @@ public class NBSyncService extends Service {
|
||||||
return SyncRunning;
|
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
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
Log.d(this.getClass().getName(), "onDestroy");
|
Log.d(this.getClass().getName(), "onDestroy");
|
||||||
|
|
|
@ -46,4 +46,6 @@ public class PrefConstants {
|
||||||
public static final String READING_ENTER_IMMERSIVE_SINGLE_TAP = "immersive_enter_single_tap";
|
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 STORIES_SHOW_PREVIEWS = "pref_show_content_preview";
|
||||||
|
|
||||||
|
public static final String ENABLE_OFFLINE = "enable_offline";
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,4 +302,9 @@ public class PrefsUtils {
|
||||||
SharedPreferences prefs = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
|
SharedPreferences prefs = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
|
||||||
return prefs.getBoolean(PrefConstants.STORIES_SHOW_PREVIEWS, true);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue