BroadcastReceiver
public class RebootBroadcastReceiver extends BroadcastReceiver {
AlarmReceiver alarm = new AlarmReceiver();
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
alarm.setAlarm(context);
}
}
}
AndroidManifest:
<service android:name=".alarm.UpdateRemoteConfigIntentService" />
<receiver android:name=".alarm.AlarmReceiver" />
<receiver
android:name=".alarm.RebootBroadcastReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
IntentServices:
public class UpdateRemoteConfigIntentService extends IntentService {
private static final String TAG = "UpdateRemoteConfigIntentService";
public UpdateRemoteConfigIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
KayakoLogger.d(TAG, "Update remote config values");
try {
// Fetch remote config in background
RemoteConfig.getInstance().fetchNewValuesSync();
} finally {
// Intent may be null if the service is being restarted after its process has gone away, and it had previously returned anything except START_STICKY_COMPATIBILITY.
// if your service gets killed and restarted while in the middle of such work (so the Intent gets re-delivered to perform the work again), it will at that point no longer be holding a wake lock
if (intent == null) {
return;
}
// Release the wake lock
AlarmReceiver.completeWakefulIntent(intent);
}
}
}
AlarmManager
public class AlarmReceiver extends WakefulBroadcastReceiver {
private static final String TAG = "AlarmReceiver";
private AlarmManager alarmManager;
private PendingIntent alarmIntent; // The pending intent that is triggered when the alarm fires.
private int mUniqueCode = 1; // ensure that whenenver the alarm is set, it will update (replace) the existing PendingIntent (instead of starting a new separate one).
@Override
public void onReceive(Context context, Intent intent) {
// start Update Remote Config service with wakelock
Intent updateRemoteConfigService = new Intent(context, UpdateRemoteConfigIntentService.class);
startWakefulService(context, updateRemoteConfigService);
}
/**
* Sets a repeating alarm that runs at regular periods. When the
* alarm fires, the app broadcasts an Intent to this WakefulBroadcastReceiver.
* <p/>
* Also, according to: http://developer.android.com/reference/android/app/AlarmManager.html
* - If there is already an alarm scheduled for the same IntentSender, that previous alarm will first be canceled.
* - If there is already an alarm for this Intent scheduled (with the equality of two intents being defined by filterEquals(Intent)), then it will be removed and replaced by this one.
*
* @param context
*/
public void setAlarm(Context context) {
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, mUniqueCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Set the alarm to fire every 1 hour (session-timeout on server is 6 hours)
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
AlarmManager.INTERVAL_HOUR, AlarmManager.INTERVAL_HOUR, alarmIntent);
// Enable {@code RebootBroadcastReceiver} to automatically restart the alarm when the
// device is rebooted.
ComponentName receiver = new ComponentName(context, RebootBroadcastReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
public void cancelAlarm(Context context) {
// If the alarm has been set, cancel it.
if (alarmManager != null) {
alarmManager.cancel(alarmIntent);
}
// Disable {@code RebootBroadcastReceiver} so that
// it doesn't automatically restart the alarm when the device is rebooted.
ComponentName receiver = new ComponentName(context, RebootBroadcastReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
}
build.gradle
compile 'com.firebase:firebase-jobdispatcher:0.8.5'
AndroidManifest
<service
android:name=".alarm2.UpdateRemoteConfigJob"
android:exported="false">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
</intent-filter>
</service>
JobDispatcher
public class MyJobManager {
private static final String TAG = "MyJobManager";
FirebaseJobDispatcher mDispatcher;
public MyJobManager(Context context) {
// Create a new dispatcher using the Google Play driver.
mDispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
}
public void enableJob() {
Job myJob = mDispatcher.newJobBuilder()
.setService(UpdateRemoteConfigJob.class)
.setTag(UpdateRemoteConfigJob.TAG)
.setRecurring(true) // repeat indefinitely until disabled
.setLifetime(Lifetime.FOREVER)
.setTrigger(Trigger.executionWindow(0, 60)) // trigger anytime once per day (24hours)
//.setTrigger(Trigger.executionWindow(0, 24 * 60 * 60 * 60)) // trigger anytime once per day (24hours)
.setReplaceCurrent(true)
.setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
.build();
mDispatcher.mustSchedule(myJob);
}
public void disableJob() {
mDispatcher.cancel(UpdateRemoteConfigJob.TAG);
}
}
JobService
public class UpdateRemoteConfigJob extends JobService {
public static final String TAG = "UpdateRemoteConfigJob";
private Call call;
@Override
public boolean onStartJob(final JobParameters job) {
call = RemoteConfig.getInstance().fetchNewValuesAsync(new RemoteConfig.OnValuesFetched() {
@Override
public void onValuesFetched() {
jobFinished(job, true);
}
});
return false; // Answers the question: "Is there still work going on?"
}
@Override
public boolean onStopJob(JobParameters job) {
if (call != null) {
call.cancel();
call = null;
}
return false; // Answers the question: "Should this job be retried?"
}
}