0

with a BroadCastReceiver, I execute a service at the smartphone boot:

public class BootReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
    Intent startServiceIntent = new Intent(context, MyService.class);
    context.startService(startServiceIntent);
}
}

MyService:

private Runnable myRunnable = new Runnable() {
    public void run() {
        parsing.cancel(true);
        parsing = new Parsing();
        parsing.execute();
        handler.postDelayed(this, timeoutUpdate);
    }
};

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    handler.removeCallbacks(myRunnable);
    handler.postDelayed(myRunnable, 1000); 
   return Service.START_STICKY;
}

The service is really executed at the boot, but if I set a timeout of 1 hour between executions, service is not executed (maybe the system is killing it). Otherwise, if I set 60 sec between repetition, all works. How can I do it? Thanks.

helloimyourmind
  • 994
  • 4
  • 14
  • 30

3 Answers3

1

You may run the service in the foreground using startForeground().

A foreground service is a service that's considered to be something the user is actively aware of and thus not a candidate for the system to kill when low on memory.

But bear in mind that a foreground service must provide a notification for the status bar (read here), and that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.

Note: This still does not absolutely guarantee that the service won't be killed under extremely low memory conditions. It only makes it less likely to be killed.

OR

If you dont want to run the service in the foreground then you can run service in a periodic intervals using AlarmManager

Intent intent = new Intent(context, MyService.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_HOUR, pintent);

Update

Cancel the registered event by using

    Intent intent = new Intent(context, MyService.class);
    PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
    AlarmManager alarm =     (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
   alarmManager.cancel(pintent);
Kartheek
  • 7,104
  • 3
  • 30
  • 44
  • Hi, your solution with Alarm Manager should be implemented in my Boot Receiver Class? – helloimyourmind Jun 13 '15 at 10:23
  • Yes it should be implemented in Receiver and MainActivity because when you install the application alarm manager is registered through your MainActivity – Kartheek Jun 13 '15 at 10:28
  • And how can I stop a service started in this way? If the user disable auto update from Main activity and the service is executing since boot, how can I stop it? – helloimyourmind Jun 13 '15 at 10:29
  • My friend, I'm testing your solution, if all work, I'll make this as answer. Instead of cal.getTimeInMillis(), I'm using System.currentTimeMillis(), is right? – helloimyourmind Jun 13 '15 at 11:28
  • yes you can use System.currentTimeMillis()+1000*60*60 four houly interval – Kartheek Jun 13 '15 at 11:44
  • I'm using: alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 60*60*1000, pintent); – helloimyourmind Jun 13 '15 at 12:10
  • One last thing, if I want to run a piece of code in NON-UI Thread in a Service, is right using AsyncTask? I don't need to update the UI, in fact I'm only using the "doInBackground" method. Do you think there are a better performance solution? – helloimyourmind Jun 14 '15 at 01:13
  • Yes you can use the AsyncTask, but asyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask. – Kartheek Jun 15 '15 at 04:41
1

To schedule a job use AlarmManager in BroadcastReciever.

Intent intent = new Intent(context, MyService.class);
PendingIntent pintent = PendingIntent.getService(context, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm. setRepeating(AlarmManager.RTC_WAKEUP, triggerInMillis, intervalMillis, pintent);

System will awake your service and then you will be able to execute task immediately.

klimat
  • 24,711
  • 7
  • 63
  • 70
  • Hi, in this way my service is always destroyed after all the executions and recreated every hour? – helloimyourmind Jun 13 '15 at 10:27
  • Read documentation about the Service. Every context.startService affects calling onStartCommand(). System will not destory the service if it's running. Will use exsisting instance. – klimat Jun 13 '15 at 10:36
0

set highest priority for your service

<intent-filter 
               android:priority="integer" >
</intent-filter>

The value must be an integer, such as "100". Higher numbers have a higher priority. The default value is 0. The value must be greater than -1000 and less than 1000.

balu b
  • 282
  • 2
  • 7