简体   繁体   中英

Scheduling service with alarm manager

I wrote some simple classes to schedule a service's start and end date.

I got the following:

  • ServiceTest : A simple service, logging onStart, onDestroy, and running.
  • ServiceSchedulerTest : Scheduling ServiceTest's start and end date, using AlarmManager
  • ServiceStopBroadcastReceiverTest : BroadcasteReceiver for stopping service.
  • ScheduleUnit : A record for holding a start and end date for a scheduling.

I tested my service with simply calling:

    Intent intent = new Intent(this, ServiceTest.class);
    startService(intent);

And it works fine... however, i cannot make scheduling work with alarm manager.

Here are the classes:

ScheduleUnit:

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;
}
}

ServiceTest:

/**
 * 
 * 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);

    }

}

Logging:

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

Problem is:

The service actually never gets called, it never runs.

Help me if you can.

EDIT:

As ci_ mentioned below i accidentally added wrong class to my pendingIntent's getService method. Changing it to the actual Service it is working fine

In ServiceSchedulerTest you're trying to get a service PendingIntent for ServiceSchedulerTest , which is most likely a typo and should have been ServiceTest

Intent startIntent = new Intent(ctx, ServiceSchedulerTest.class);

should most likely be:

Intent startIntent = new Intent(ctx, ServiceTest.class);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM