Created
August 20, 2015 04:24
-
-
Save tanhauhau/0eadd4ec2bb523e200a5 to your computer and use it in GitHub Desktop.
Wakeful Scheduled Service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context; | |
import android.content.Intent; | |
import android.os.Bundle; | |
import android.support.v4.content.WakefulBroadcastReceiver; | |
import android.util.Log; | |
/** | |
* Created by lhtan on 20/8/15. | |
* Refer from: https://randling.wordpress.com/2013/12/29/wakeful-and-repeatable-background-service-on-android/#comment-690 | |
*/ | |
public abstract class AlarmReceiver extends WakefulBroadcastReceiver { | |
public static final String EXTRA_SERVICE = "extra-service"; | |
public static final String EXTRA_SERVICE_BUNDLE = "extra-bundle"; | |
private final String LOG_TAG = "AlarmReceiver"; | |
@Override | |
public void onReceive(Context context, Intent intent) { | |
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) { | |
BootListener bootListener = getBootListener(); | |
if (bootListener != null) { | |
bootListener.onBootCompleted(context, intent); | |
} | |
return; | |
} | |
Bundle extras = intent.getExtras(); | |
String className = extras.getString(EXTRA_SERVICE); | |
Bundle intentExtras = extras.getBundle(EXTRA_SERVICE_BUNDLE); | |
Log.i(LOG_TAG, "intent received to execute service: " + className); | |
try { | |
Class<?> serviceClass = Class.forName(className); | |
Intent serviceIntent = new Intent(context, serviceClass); | |
serviceIntent.putExtras(intentExtras); | |
startWakefulService(context, serviceIntent); | |
} catch (ClassNotFoundException e) { | |
e.printStackTrace(); | |
} | |
} | |
private abstract BootListener getBootListener(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> | |
<uses-permission android:name="android.permission.WAKE_LOCK"/> | |
<receiver android:name=".receiver.AlarmReceiver" > | |
<intent-filter> | |
<action android:name="android.intent.action.BOOT_COMPLETED"/> | |
</intent-filter> | |
</receiver> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.annotation.TargetApi; | |
import android.app.AlarmManager; | |
import android.app.Application; | |
import android.app.IntentService; | |
import android.app.PendingIntent; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.os.Build; | |
import android.util.Log; | |
import java.util.Date; | |
/** | |
* Created by lhtan on 20/8/15. | |
* Refer from: https://randling.wordpress.com/2013/12/29/wakeful-and-repeatable-background-service-on-android/#comment-690 | |
*/ | |
public abstract class ScheduledService extends IntentService{ | |
protected static final int REQUEST_CODE = 101; | |
private final String LOG_TAG = "ScheduledService"; | |
private String serviceName; | |
public ScheduledService(String name) { | |
super(name); | |
serviceName = name; | |
} | |
@Override | |
protected void onHandleIntent(Intent intent) { | |
try { | |
Log.i(LOG_TAG, "Starting service " + serviceName); | |
executeBackgroundService(intent); | |
Log.i(LOG_TAG, serviceName + " completed."); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
abstract protected long getNextScheduleTime(); | |
protected String getServiceName() { | |
return serviceName; | |
} | |
protected abstract Intent getServiceIntent(Context context); | |
protected abstract void executeBackgroundService(Intent intent) throws Exception; | |
public void scheduleService(Context context, boolean forceReshedule) { | |
if (isScheduled()) { | |
if (forceReshedule) { | |
cancelSchedule(); | |
}else { | |
Log.i(LOG_TAG, getServiceName() + " is already scheduled."); | |
return; | |
} | |
} | |
scheduleServiceImpl(context); | |
} | |
public void scheduleService(Context context) { | |
scheduleService(context, false); | |
} | |
protected void scheduleServiceImpl(Context context) { | |
Intent intent = getServiceIntent(context); | |
PendingIntent pendingIntent = PendingIntent.getService(context, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT); | |
AlarmManager am = (AlarmManager) context.getSystemService(ALARM_SERVICE); | |
scheduleAlarm(am, pendingIntent, getNextScheduleTime()); | |
} | |
@TargetApi(Build.VERSION_CODES.KITKAT) | |
protected void scheduleAlarm(AlarmManager am, PendingIntent pendingIntent, long time) { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
am.setExact(AlarmManager.RTC_WAKEUP, time, pendingIntent); | |
}else { | |
am.set(AlarmManager.RTC_WAKEUP, time, pendingIntent); | |
} | |
Log.i(LOG_TAG, "Scheduled " + getServiceName() + " to run at " + new Date(time)); | |
} | |
protected boolean isScheduled() { | |
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), REQUEST_CODE, | |
getServiceIntent(getApplicationContext()), PendingIntent.FLAG_NO_CREATE); | |
return (pendingIntent != null); | |
} | |
protected void cancelSchedule() { | |
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), REQUEST_CODE, | |
getServiceIntent(getApplicationContext()), PendingIntent.FLAG_NO_CREATE); | |
if (pendingIntent != null) { | |
Log.i(LOG_TAG, "Cancelling last schedule for " + getServiceName()); | |
AlarmManager am = (AlarmManager) getApplicationContext().getSystemService(ALARM_SERVICE); | |
am.cancel(pendingIntent); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.app.AlarmManager; | |
import android.app.Application; | |
import android.app.PendingIntent; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.net.Uri; | |
import android.os.Bundle; | |
import android.util.Log; | |
import java.util.Objects; | |
/** | |
* Created by lhtan on 20/8/15. | |
* Refer from: https://randling.wordpress.com/2013/12/29/wakeful-and-repeatable-background-service-on-android/#comment-690 | |
*/ | |
public abstract class WakefulScheduledService extends ScheduledService { | |
private final String LOG_TAG = "ScheduledService"; | |
public WakefulScheduledService(String name) { | |
super(name); | |
} | |
@Override | |
protected void onHandleIntent(Intent intent) { | |
try { | |
super.onHandleIntent(intent); | |
} finally { | |
AlarmReceiver.completeWakefulIntent(intent); | |
} | |
} | |
protected void scheduleServiceImpl(Context context) { | |
Intent intent = getAlarmReceiverIntent(context); | |
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT); | |
AlarmManager am = (AlarmManager) context.getSystemService(ALARM_SERVICE); | |
long time = getNextScheduleTime(); | |
scheduleAlarm(am, pendingIntent, time); | |
} | |
protected Intent getAlarmReceiverIntent(Context context) { | |
Intent intent = new Intent(context, AlarmReceiver.class); | |
Intent serviceIntent = getServiceIntent(context); | |
intent.setData(Uri.fromParts("execService", serviceIntent.getComponent().getClassName(), null)); | |
intent.putExtra(AlarmReceiver.EXTRA_SERVICE, serviceIntent.getComponent().getClassName()); | |
intent.putExtra(AlarmReceiver.EXTRA_SERVICE_BUNDLE, serviceIntent.getExtras()); | |
return intent; | |
} | |
protected boolean isScheduled() { | |
Intent intent = getAlarmReceiverIntent(getApplicationContext()); | |
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE, | |
intent, PendingIntent.FLAG_NO_CREATE); | |
return (pendingIntent != null); | |
} | |
protected void cancelSchedule() { | |
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE, | |
getAlarmReceiverIntent(getApplicationContext()), PendingIntent.FLAG_NO_CREATE); | |
if (pendingIntent != null) { | |
Log.i(LOG_TAG, "Cancelling last schedule for " + getServiceName()); | |
AlarmManager am = (AlarmManager) getApplicationContext().getSystemService(ALARM_SERVICE); | |
am.cancel(pendingIntent); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment