Start Service schedule without reboot? Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of Start Service schedule without reboot? without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I’m coding my first app that uses a service, following the tutorial/guide here http://www.vogella.com/articles/AndroidServices/article.html I’ve got my service working and it describes making a broadcast receiver for BOOT_COMPLETED which works and allows me to run the service every few minutes.

The problem I have is that it doesn’t work until the user reboots their phone. The service starts with the activity, but seems to die with the activity as well unless the device has been rebooted.

Is there any way to start the scheduler from the activity when it’s first run without rebooting?

My code for the scheduler is as follows:

public class ScheduleReceiver extends BroadcastReceiver {

    // Restart service every 30 seconds
    private static final long REPEAT_TIME = 1000 * 60; // check every minute.  

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("schedulereceiver", "starting schedule");
        AlarmManager service = (AlarmManager) context
                .getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(context, StartServiceReceiver.class);
        PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
                PendingIntent.FLAG_CANCEL_CURRENT);
        Calendar cal = Calendar.getInstance();
        // Start 30 seconds after boot completed
        cal.add(Calendar.SECOND, 30);
        //
        // Fetch every 30 seconds
        // InexactRepeating allows Android to optimize the energy consumption
        service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                cal.getTimeInMillis(), REPEAT_TIME, pending);

        // service.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
        // REPEAT_TIME, pending);

    }
}

My Manifest file looks like this:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >

        <activity
            android:name=".ProximityActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".ProximityService"
            android:enabled="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/service_name" >
        </service>

        <receiver android:name="ScheduleReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
        <receiver android:name="StartServiceReceiver" >
        </receiver>
    </application>

</manifest>

Answer

The basic issue here is that you’d like to set up the timer in two different scenarios.

You’d like to set it up on boot — and you’d like to set it up when the user first launches the application. (You can’t do it on install, I’m afraid).

The best way I’ve found to do this, is to simply record in the filesystem that you’ve set up the timer, the first time you set it up.

In ScheduleReceiver, create two public static methods:

public static void startupActions(Context ctx) {
    setupTimer();
    try {
        ctx.openFileOutput(".inited", Context.MODE_PRIVATE).close();
    } catch (IOException e) {
        throw new Error(e);
    }
}

Call the method above from your onReceive() method. We’ll reuse it again in a moment.

public static boolean hasStartupRun(Context ctx) {
    try {
        ctx.openFileInput(".inited").close();
        return true;
    } catch (IOException e) {
        return false;
    }
}

Use these in your main activity’s onCreate() method to tell whether you need to start the timers:

    if (! ScheduleReceiver.hasStartupRun(this)) {
        ScheduleReceiver.startupActions(this);
    }

It appears that reinstalling does not clear the timers, so the only other glitch you’d need to worry about is if you need to modify the timer (or other set of startup actions) somehow. To handle that, you could modify the intent so the old one is not handled, and rename the file, so the new one is scheduled.

You could use any other persistent flag, such as database creation, a preferences file, etc., but creating a file this way is the simplest way I could think of to do from a BroadcastReceiver.

One thing I found a little puzzling in your question is that your service “starts” and “dies” with the activity.

I realize this question is several months old, but for the sake of other readers who may be in similar shoes… That sounds a bit confused. Do you mean, the service’s onCreate() method is called when the activity starts, and onDestroy() method is called when the activity “dies”? Or that your activity starts it or binds to it, but it goes away and never comes back when the process is killed?

The reason I bring this up is, depending on what your service does, you may want to remove whatever other code is starting your service, and rely just on the timer.

Service and Activity lifecycles are quite different and unrelated, and the process lifetime is quite different from either one. If you want to interact with your service from your activity, you may want to bind to it, as well as start it from a timer. It’s perfectly OK to do both! (Though it’s often better to have two services — a background or timer-based one, and a control/configuration one that both the background service and the activity bind to).

Just to be sure to match every bind with an unbind, and every start with either a Service.stopSelfResult(int) (if the service does a unit of work each time it’s started) or a Context.stopService(Intent) (if the service is continuous as needed by the caller), so the system knows when you’re done with the service.

And if you’re using startService, be sure to select carefully the flag to return from onStartCommand(…).

We are here to answer your question about Start Service schedule without reboot? - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji