使用报警管理器调度服务
Scheduling service with alarm manager
我写了一些简单的 classes 来安排服务的开始和结束日期。
我得到以下信息:
- ServiceTest:一个简单的服务,记录onStart、onDestroy和
运行。
- ServiceSchedulerTest: 安排ServiceTest的开始和结束
日期,使用 AlarmManager
- ServiceStopBroadcastReceiverTest: BroadcasteReceiver 用于停止服务。
- ScheduleUnit: 保存调度开始和结束日期的记录。
我通过简单地调用测试了我的服务:
Intent intent = new Intent(this, ServiceTest.class);
startService(intent);
它工作正常...但是,我无法使用警报管理器进行调度。
这里是 classes:
日程单位:
public class ScheduleUnit {
public String id;
public Date dateStart, dateEnd; // Start and end date for a scheduling
public ScheduleUnit(String id, String dateStart, String dateEnd) {
this.id = id;
this.dateStart = stringToDate(dateStart);
this.dateEnd = stringToDate(dateEnd);
}
public Date stringToDate(String dateStr) {
Date date = null;
try {
date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
服务测试:
/**
*
* Simple test service, logging starting, running and destroying.
*/
public class ServiceTest extends Service {
private final String TAG = "MyDebug_Service_Test";
private final boolean DEBUG = true;
private Handler handler;
private Runnable runnable = new Runnable() {
@Override
public void run() {
log("Service is actually still alive.");
handler.postDelayed(this, 5000);
}
};
private void log(Object o) {
if (DEBUG) {
Log.i(TAG, o.toString());
FileLogger.appendToLog(o);
}
}
@Override
public void onCreate() {
log("onCreate");
handler = new Handler();
handler.post(runnable);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
log("onStartCommand");
return START_REDELIVER_INTENT;
}
@Override
public void onDestroy() {
log("onDestroy");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
ServiceStopBroadcastReceiverTest:
/**
* Simple broadcast receiver for catching a broadcast to stop the service.
*
*
*/
public class ServiceStopBroadcastReceiverTest extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("MyDebug_ServiceStopBroadcastReceiverTest", "onReceive ran, Calling stopService now.");
context.stopService(new Intent(context, ServiceTest.class));
}
}
ServiceSchedulerTest:
public class ServiceSchedulerTest {
private static ServiceSchedulerTest mInstance;
private AlarmManager alarmManager;
private Context ctx;
private static String TAG = "MyDebug_ServiceSchedulerTest";
private static boolean DEBUG = true;
private static void log(Object o) {
if (DEBUG) {
Log.i(TAG, o.toString());
}
}
// Singleton pattern
private ServiceSchedulerTest(Context ctx) {
this.ctx = ctx.getApplicationContext();
alarmManager = (AlarmManager) this.ctx.getSystemService(Context.ALARM_SERVICE);
}
// Singleton pattern
public static ServiceSchedulerTest getInstance(Context ctx) {
if (mInstance == null) {
mInstance = new ServiceSchedulerTest(ctx);
}
return mInstance;
}
public void scheduleService(ScheduleUnit scheduleUnit) {
/**
* First part, scheduling START service
*/
// unique Id for Start
int uniqueIdForStart = (int) Calendar.getInstance().getTimeInMillis();
log("Scheduling to START service at date: " + scheduleUnit.dateStart + " with request code: " + uniqueIdForStart);
// StartDate in millis
long millisToStartDate = scheduleUnit.dateStart.getTime();
log("Scheduling start in millis: "+millisToStartDate);
// Start intent for service
Intent startIntent = new Intent(ctx, ServiceSchedulerTest.class);
// Pending intent, with uniqueId and intent parameter for alarmManager's set function
PendingIntent startPendingIntent = PendingIntent.getService(ctx, uniqueIdForStart, startIntent, 0);
// Setting the actual alarm with the start PendingIntent
alarmManager.set(AlarmManager.RTC_WAKEUP, millisToStartDate, startPendingIntent);
// /////////////////////////////////
/**
* Second part, scheduling STOP service
*/
// unique Id for Start
int uniqueIdForEnd = (int) Calendar.getInstance().getTimeInMillis();
//Increment to make sure it is different from uniqueIdForStart
uniqueIdForEnd++;
log("Scheduling to STOP service at date: " + scheduleUnit.dateEnd + " with request code: " + uniqueIdForEnd);
// EndDate in millis
long millisToEndDate = scheduleUnit.dateEnd.getTime();
log("Scheduling end in millis: "+millisToEndDate);
// End intent for service -> calling a broadcast reciver to actually stop the service
Intent endIntent = new Intent(ctx, ServiceStopBroadcastReceiverTest.class);
// Penidng intent, with the uniqueId and the intent paramter for alarmManager'set function
PendingIntent endPendingIntent = PendingIntent.getBroadcast(ctx, uniqueIdForEnd, endIntent, 0);
// Setting alarm manager to call the Service stopping
alarmManager.set(AlarmManager.RTC_WAKEUP, millisToEndDate, endPendingIntent);
}
}
记录:
04-08 15:13:46.681: I/MyDebug_ServiceSchedulerTest(27581): Scheduling
to START service at date: Wed Apr 08 15:15:00 CEST 2015 with request
code: -1725282887
04-08 15:13:46.682: I/MyDebug_ServiceSchedulerTest(27581): Scheduling
start in millis: 1428498900000
04-08 15:13:46.687: I/MyDebug_ServiceSchedulerTest(27581): Scheduling
to STOP service at date: Wed Apr 08 15:16:00 CEST 2015 with request
code: -1725282881
04-08 15:13:46.687: I/MyDebug_ServiceSchedulerTest(27581): Scheduling
end in millis: 1428498960000
问题是:
该服务实际上从未被调用过,它从未运行过。
如果可以的话,请帮助我。
编辑:
正如下面提到的 ci_ 我不小心 在我的 pendingIntent 的 getService 方法中添加了错误的 class。 将其更改为 实际服务工作正常
在 ServiceSchedulerTest
中,您正在尝试为 ServiceSchedulerTest
获取服务 PendingIntent
,这很可能是错字,应该是 ServiceTest
Intent startIntent = new Intent(ctx, ServiceSchedulerTest.class);
最有可能是:
Intent startIntent = new Intent(ctx, ServiceTest.class);
我写了一些简单的 classes 来安排服务的开始和结束日期。
我得到以下信息:
- ServiceTest:一个简单的服务,记录onStart、onDestroy和 运行。
- ServiceSchedulerTest: 安排ServiceTest的开始和结束 日期,使用 AlarmManager
- ServiceStopBroadcastReceiverTest: BroadcasteReceiver 用于停止服务。
- ScheduleUnit: 保存调度开始和结束日期的记录。
我通过简单地调用测试了我的服务:
Intent intent = new Intent(this, ServiceTest.class);
startService(intent);
它工作正常...但是,我无法使用警报管理器进行调度。
这里是 classes:
日程单位:
public class ScheduleUnit {
public String id;
public Date dateStart, dateEnd; // Start and end date for a scheduling
public ScheduleUnit(String id, String dateStart, String dateEnd) {
this.id = id;
this.dateStart = stringToDate(dateStart);
this.dateEnd = stringToDate(dateEnd);
}
public Date stringToDate(String dateStr) {
Date date = null;
try {
date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
服务测试:
/**
*
* Simple test service, logging starting, running and destroying.
*/
public class ServiceTest extends Service {
private final String TAG = "MyDebug_Service_Test";
private final boolean DEBUG = true;
private Handler handler;
private Runnable runnable = new Runnable() {
@Override
public void run() {
log("Service is actually still alive.");
handler.postDelayed(this, 5000);
}
};
private void log(Object o) {
if (DEBUG) {
Log.i(TAG, o.toString());
FileLogger.appendToLog(o);
}
}
@Override
public void onCreate() {
log("onCreate");
handler = new Handler();
handler.post(runnable);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
log("onStartCommand");
return START_REDELIVER_INTENT;
}
@Override
public void onDestroy() {
log("onDestroy");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
ServiceStopBroadcastReceiverTest:
/**
* Simple broadcast receiver for catching a broadcast to stop the service.
*
*
*/
public class ServiceStopBroadcastReceiverTest extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("MyDebug_ServiceStopBroadcastReceiverTest", "onReceive ran, Calling stopService now.");
context.stopService(new Intent(context, ServiceTest.class));
}
}
ServiceSchedulerTest:
public class ServiceSchedulerTest {
private static ServiceSchedulerTest mInstance;
private AlarmManager alarmManager;
private Context ctx;
private static String TAG = "MyDebug_ServiceSchedulerTest";
private static boolean DEBUG = true;
private static void log(Object o) {
if (DEBUG) {
Log.i(TAG, o.toString());
}
}
// Singleton pattern
private ServiceSchedulerTest(Context ctx) {
this.ctx = ctx.getApplicationContext();
alarmManager = (AlarmManager) this.ctx.getSystemService(Context.ALARM_SERVICE);
}
// Singleton pattern
public static ServiceSchedulerTest getInstance(Context ctx) {
if (mInstance == null) {
mInstance = new ServiceSchedulerTest(ctx);
}
return mInstance;
}
public void scheduleService(ScheduleUnit scheduleUnit) {
/**
* First part, scheduling START service
*/
// unique Id for Start
int uniqueIdForStart = (int) Calendar.getInstance().getTimeInMillis();
log("Scheduling to START service at date: " + scheduleUnit.dateStart + " with request code: " + uniqueIdForStart);
// StartDate in millis
long millisToStartDate = scheduleUnit.dateStart.getTime();
log("Scheduling start in millis: "+millisToStartDate);
// Start intent for service
Intent startIntent = new Intent(ctx, ServiceSchedulerTest.class);
// Pending intent, with uniqueId and intent parameter for alarmManager's set function
PendingIntent startPendingIntent = PendingIntent.getService(ctx, uniqueIdForStart, startIntent, 0);
// Setting the actual alarm with the start PendingIntent
alarmManager.set(AlarmManager.RTC_WAKEUP, millisToStartDate, startPendingIntent);
// /////////////////////////////////
/**
* Second part, scheduling STOP service
*/
// unique Id for Start
int uniqueIdForEnd = (int) Calendar.getInstance().getTimeInMillis();
//Increment to make sure it is different from uniqueIdForStart
uniqueIdForEnd++;
log("Scheduling to STOP service at date: " + scheduleUnit.dateEnd + " with request code: " + uniqueIdForEnd);
// EndDate in millis
long millisToEndDate = scheduleUnit.dateEnd.getTime();
log("Scheduling end in millis: "+millisToEndDate);
// End intent for service -> calling a broadcast reciver to actually stop the service
Intent endIntent = new Intent(ctx, ServiceStopBroadcastReceiverTest.class);
// Penidng intent, with the uniqueId and the intent paramter for alarmManager'set function
PendingIntent endPendingIntent = PendingIntent.getBroadcast(ctx, uniqueIdForEnd, endIntent, 0);
// Setting alarm manager to call the Service stopping
alarmManager.set(AlarmManager.RTC_WAKEUP, millisToEndDate, endPendingIntent);
}
}
记录:
04-08 15:13:46.681: I/MyDebug_ServiceSchedulerTest(27581): Scheduling to START service at date: Wed Apr 08 15:15:00 CEST 2015 with request code: -1725282887
04-08 15:13:46.682: I/MyDebug_ServiceSchedulerTest(27581): Scheduling start in millis: 1428498900000
04-08 15:13:46.687: I/MyDebug_ServiceSchedulerTest(27581): Scheduling to STOP service at date: Wed Apr 08 15:16:00 CEST 2015 with request code: -1725282881
04-08 15:13:46.687: I/MyDebug_ServiceSchedulerTest(27581): Scheduling end in millis: 1428498960000
问题是:
该服务实际上从未被调用过,它从未运行过。
如果可以的话,请帮助我。
编辑:
正如下面提到的 ci_ 我不小心 在我的 pendingIntent 的 getService 方法中添加了错误的 class。 将其更改为 实际服务工作正常
在 ServiceSchedulerTest
中,您正在尝试为 ServiceSchedulerTest
获取服务 PendingIntent
,这很可能是错字,应该是 ServiceTest
Intent startIntent = new Intent(ctx, ServiceSchedulerTest.class);
最有可能是:
Intent startIntent = new Intent(ctx, ServiceTest.class);