mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-09-18 21:50:56 +00:00
Android widget bypass update interval via alarm manager for faster updates
This commit is contained in:
parent
042e33d314
commit
48b30f9bf4
10 changed files with 145 additions and 38 deletions
|
@ -152,13 +152,24 @@
|
|||
<receiver android:name=".util.NotifyDismissReceiver" android:exported="false" />
|
||||
<receiver android:name=".util.NotifySaveReceiver" android:exported="false" />
|
||||
<receiver android:name=".util.NotifyMarkreadReceiver" android:exported="false" />
|
||||
<receiver android:name=".widget.WidgetProvider" >
|
||||
<receiver android:name=".widget.WidgetProvider"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.appwidget.provider"
|
||||
android:resource="@xml/newsblur_appwidget_info" />
|
||||
</receiver>
|
||||
<receiver android:name=".service.TimeChangeReceiver">
|
||||
<intent-filter >
|
||||
<action android:name="android.intent.action.TIME_SET"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name=".widget.WidgetUpdateReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="false">
|
||||
</receiver>
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="com.newsblur.fileprovider"
|
||||
|
|
|
@ -8,10 +8,11 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
|
||||
import com.newsblur.util.AppConstants;
|
||||
import com.newsblur.widget.WidgetUtils;
|
||||
|
||||
/**
|
||||
* First receiver in the chain that starts with the device. Simply schedules another broadcast
|
||||
* that will periodicaly start the sync service.
|
||||
* that will periodically start the sync service.
|
||||
*/
|
||||
public class BootReceiver extends BroadcastReceiver {
|
||||
|
||||
|
@ -19,6 +20,7 @@ public class BootReceiver extends BroadcastReceiver {
|
|||
public void onReceive(Context context, Intent intent) {
|
||||
com.newsblur.util.Log.d(this, "triggering sync service from device boot");
|
||||
scheduleSyncService(context);
|
||||
resetWidgetSync(context);
|
||||
}
|
||||
|
||||
public static void scheduleSyncService(Context context) {
|
||||
|
@ -32,5 +34,9 @@ public class BootReceiver extends BroadcastReceiver {
|
|||
int result = sched.schedule(builder.build());
|
||||
com.newsblur.util.Log.d("BootReceiver", String.format("Scheduling result: %s - %s", result, result == 0 ? "Failure" : "Success"));
|
||||
}
|
||||
|
||||
|
||||
private static void resetWidgetSync(Context context) {
|
||||
com.newsblur.util.Log.d(BootReceiver.class.getName(), "Received " + Intent.ACTION_BOOT_COMPLETED + " - reset widget sync");
|
||||
WidgetUtils.resetUpdateAlarm(context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package com.newsblur.service;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.newsblur.widget.WidgetUtils;
|
||||
|
||||
public class TimeChangeReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, @Nullable Intent intent) {
|
||||
if (intent != null && intent.getAction() != null
|
||||
&& intent.getAction().equals(Intent.ACTION_TIME_CHANGED)) {
|
||||
com.newsblur.util.Log.d(TimeChangeReceiver.class.getName(), "Received " + Intent.ACTION_TIME_CHANGED + " - reset widget sync");
|
||||
WidgetUtils.resetUpdateAlarm(context);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,14 +6,9 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import android.app.job.JobInfo;
|
||||
import android.app.job.JobScheduler;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.PersistableBundle;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.newsblur.R;
|
||||
|
@ -28,7 +23,6 @@ import com.newsblur.fragment.ReadingActionConfirmationFragment;
|
|||
import com.newsblur.network.APIManager;
|
||||
import com.newsblur.network.domain.NewsBlurResponse;
|
||||
import com.newsblur.service.NBSyncService;
|
||||
import com.newsblur.widget.WidgetProvider;
|
||||
|
||||
public class FeedUtils {
|
||||
|
||||
|
@ -63,21 +57,6 @@ public class FeedUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void triggerAppWidgetSync(Context context, int appWidgetId) {
|
||||
// direct start service is not allowed when the app is in background
|
||||
PersistableBundle bundle = new PersistableBundle();
|
||||
bundle.putInt(WidgetProvider.EXTRA_WIDGET_ID, appWidgetId);
|
||||
com.newsblur.util.Log.d(FeedUtils.class.getName(), "Trigger sync from background");
|
||||
JobInfo.Builder builder = new JobInfo.Builder( 1, new ComponentName(context, NBSyncService.class));
|
||||
builder.setOverrideDeadline(0);
|
||||
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
|
||||
builder.setExtras(bundle);
|
||||
JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
|
||||
|
||||
int result = scheduler.schedule(builder.build());
|
||||
com.newsblur.util.Log.d(FeedUtils.class.getName(), String.format("Sync scheduling %s", result == 0 ? "failed" : "successful"));
|
||||
}
|
||||
|
||||
public static void triggerSync(Context c) {
|
||||
// NB: when our minSDKversion hits 28, it could be possible to start the service via the JobScheduler
|
||||
// with the setImportantWhileForeground() flag via an enqueue() and get rid of all legacy startService
|
||||
|
|
|
@ -106,5 +106,6 @@ public class PrefConstants {
|
|||
public static final String ENABLE_NOTIFICATIONS = "enable_notifications";
|
||||
|
||||
public static final String READING_FONT = "reading_font";
|
||||
public static final String WIDGET_FEED_ID = "WIDGET_FEED_ID";
|
||||
public static final String WIDGET_FEED_ID = "widget_feed_id";
|
||||
public static final String WIDGET_ID = "widget_id";
|
||||
}
|
||||
|
|
|
@ -878,8 +878,19 @@ public class PrefsUtils {
|
|||
|
||||
public static String getWidgetFeed(Context context, int widgetId) {
|
||||
SharedPreferences preferences = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
|
||||
String feedId = preferences.getString(PrefConstants.WIDGET_FEED_ID + widgetId, null);
|
||||
return feedId;
|
||||
return preferences.getString(PrefConstants.WIDGET_FEED_ID + widgetId, null);
|
||||
}
|
||||
|
||||
public static void setWidgetId(Context context, int widgetId) {
|
||||
SharedPreferences prefs = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
|
||||
Editor editor = prefs.edit();
|
||||
editor.putInt(PrefConstants.WIDGET_ID, widgetId);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public static int getWidgetId(Context context) {
|
||||
SharedPreferences preferences = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
|
||||
return preferences.getInt(PrefConstants.WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
|
||||
}
|
||||
|
||||
public static void removeWidgetFeed(Context context, int widgetId) {
|
||||
|
|
|
@ -16,20 +16,15 @@ import com.newsblur.util.FeedSet;
|
|||
|
||||
public class WidgetProvider extends AppWidgetProvider {
|
||||
|
||||
public static String ACTION_OPEN_STORY = "ACTION_OPEN_STORY";
|
||||
public static String EXTRA_ITEM_ID = "EXTRA_ITEM_ID";
|
||||
public static String EXTRA_FEED_ID = "EXTRA_FEED_ID";
|
||||
public static String EXTRA_WIDGET_ID = "EXTRA_WIDGET_ID";
|
||||
|
||||
private static String TAG = "WidgetProvider";
|
||||
|
||||
// Called when the BroadcastReceiver receives an Intent broadcast.
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.d(TAG, "onReceive");
|
||||
if (intent.getAction().equals(ACTION_OPEN_STORY)) {
|
||||
String storyHash = intent.getStringExtra(EXTRA_ITEM_ID);
|
||||
String feedId = intent.getStringExtra(EXTRA_FEED_ID);
|
||||
if (intent.getAction().equals(WidgetUtils.ACTION_OPEN_STORY)) {
|
||||
String storyHash = intent.getStringExtra(WidgetUtils.EXTRA_ITEM_ID);
|
||||
String feedId = intent.getStringExtra(WidgetUtils.EXTRA_FEED_ID);
|
||||
FeedSet fs = FeedSet.singleFeed(feedId);
|
||||
Intent i = new Intent(context, FeedReading.class);
|
||||
i.putExtra(Reading.EXTRA_FEEDSET, fs);
|
||||
|
@ -78,7 +73,7 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
// Set the action for the intent.
|
||||
// When the user touches a particular view, it will have the effect of
|
||||
// broadcasting ACTION_OPEN_STORY.
|
||||
touchIntent.setAction(WidgetProvider.ACTION_OPEN_STORY);
|
||||
touchIntent.setAction(WidgetUtils.ACTION_OPEN_STORY);
|
||||
touchIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
|
||||
PendingIntent touchIntentTemplate = PendingIntent.getBroadcast(context, 0, touchIntent,
|
||||
|
|
|
@ -79,6 +79,8 @@ public class WidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsF
|
|||
FeedUtils.offerInitContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
WidgetUtils.setUpdateAlarm(context, appWidgetId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,8 +113,8 @@ public class WidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsF
|
|||
// set fill-intent which is used to fill in the pending intent template
|
||||
// set on the collection view in WidgetProvider
|
||||
Bundle extras = new Bundle();
|
||||
extras.putString(WidgetProvider.EXTRA_ITEM_ID, story.storyHash);
|
||||
extras.putString(WidgetProvider.EXTRA_FEED_ID, story.feedId);
|
||||
extras.putString(WidgetUtils.EXTRA_ITEM_ID, story.storyHash);
|
||||
extras.putString(WidgetUtils.EXTRA_FEED_ID, story.feedId);
|
||||
Intent fillInIntent = new Intent();
|
||||
fillInIntent.putExtras(extras);
|
||||
|
||||
|
@ -185,6 +187,7 @@ public class WidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsF
|
|||
@Override
|
||||
public void onDestroy() {
|
||||
com.newsblur.util.Log.d(TAG, "onDestroy");
|
||||
WidgetUtils.removeUpdateAlarm(context);
|
||||
PrefsUtils.removeWidgetFeed(context, appWidgetId);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package com.newsblur.widget;
|
||||
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.newsblur.R;
|
||||
import com.newsblur.util.Log;
|
||||
|
||||
public class WidgetUpdateReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, @Nullable Intent intent) {
|
||||
if (intent != null && intent.getAction() != null &&
|
||||
intent.getAction().equals(WidgetUtils.ACTION_UPDATE_WIDGET)) {
|
||||
Log.d(this.getClass().getName(), "Received " + WidgetUtils.ACTION_UPDATE_WIDGET);
|
||||
int widgetId = intent.getIntExtra(WidgetUtils.EXTRA_WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
|
||||
if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
|
||||
AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
|
||||
widgetManager.notifyAppWidgetViewDataChanged(widgetId, R.id.widget_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.newsblur.widget;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import com.newsblur.util.Log;
|
||||
import com.newsblur.util.PrefsUtils;
|
||||
|
||||
public class WidgetUtils {
|
||||
|
||||
private static String TAG = "WidgetUtils";
|
||||
|
||||
public static String ACTION_UPDATE_WIDGET = "ACTION_UPDATE_WIDGET";
|
||||
public static String ACTION_OPEN_STORY = "ACTION_OPEN_STORY";
|
||||
public static String EXTRA_ITEM_ID = "EXTRA_ITEM_ID";
|
||||
public static String EXTRA_FEED_ID = "EXTRA_FEED_ID";
|
||||
public static String EXTRA_WIDGET_ID = "EXTRA_WIDGET_ID";
|
||||
public static int RC_WIDGET_UPDATE = 1;
|
||||
|
||||
static void setUpdateAlarm(Context context, int appWidgetId) {
|
||||
Log.d(TAG, "setUpdateAlarm");
|
||||
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
Intent intent = getUpdateIntent(context);
|
||||
intent.putExtra(EXTRA_WIDGET_ID, appWidgetId);
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, RC_WIDGET_UPDATE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
int widgetUpdateInterval = 1000 * 60 * 5;
|
||||
long startAlarmAt = SystemClock.currentThreadTimeMillis() + widgetUpdateInterval;
|
||||
alarmManager.setInexactRepeating(AlarmManager.RTC, startAlarmAt, widgetUpdateInterval, pendingIntent);
|
||||
}
|
||||
|
||||
static void removeUpdateAlarm(Context context) {
|
||||
Log.d(TAG, "removeUpdateAlarm");
|
||||
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, RC_WIDGET_UPDATE, getUpdateIntent(context), PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
alarmManager.cancel(pendingIntent);
|
||||
}
|
||||
|
||||
public static void resetUpdateAlarm(Context context) {
|
||||
int widgetId = PrefsUtils.getWidgetId(context);
|
||||
if (widgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
|
||||
WidgetUtils.setUpdateAlarm(context, widgetId);
|
||||
}
|
||||
}
|
||||
|
||||
private static Intent getUpdateIntent(Context context) {
|
||||
Intent intent = new Intent(context, WidgetUpdateReceiver.class);
|
||||
intent.setAction(ACTION_UPDATE_WIDGET);
|
||||
return intent;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue