web-dev-qa-db-fra.com

Service qui fonctionne toutes les minutes

J'ai un service que je veux exécuter une tâche toutes les minutes en arrière-plan. Il n'a pas besoin d'exécuter la tâche lorsque le téléphone est en veille, mais uniquement lorsque l'utilisateur l'utilise activement. J'essaie de le faire avec un IntentService qui est configuré comme suit:

public class CounterService extends IntentService{

    public CounterService() {
        super("CounterService");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
       return super.onStartCommand(intent,flags,startId);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Toast.makeText(this, "onhandleintent", Toast.LENGTH_SHORT).show();
        while(true)
        {
            //one minute is 60*1000
            try {
                Thread.sleep(5 * 1000);
                Toast.makeText(getApplicationContext(), "getting app count", Toast.LENGTH_LONG).show();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

En ce moment, pour que la fonctionnalité fonctionne, je veux simplement qu'elle affiche un toast toutes les 5 secondes, je la changerai en une minute plus tard. Si j'ai la while(true) mise en commentaire, le message "onhandleintent" s'affiche. Cependant, si j'ai le code suivant exécuté, aucun des toasts ne s'affiche. Comment puis-je réparer cela?

18
AggieDev

Cela enverra une intention à votre service chaque minute sans utiliser de temps processeur dans votre activité entre les deux.

  Intent myIntent = new Intent(context, MyServiceReceiver.class);
  PendingIntent pendingIntent = PendingIntent.getBroadcast(context,  0, myIntent, 0);

  AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
  Calendar calendar = Calendar.getInstance();
  calendar.setTimeInMillis(System.currentTimeMillis());
  calendar.add(Calendar.SECOND, 60); // first time
  long frequency= 60 * 1000; // in ms 
  alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), frequency, pendingIntent);           

Ajustez MyServiceReceiver.class pour correspondre à votre service ou activité cible. Le documentation fournit plus de détails pour affiner vos appels, comme si vous voulez un timing précis, une exécution à un moment précis de la journée ...

21
Android Newbie

Vous devez quitter le thread principal pour éviter de risquer un ANR.

Ajoutez plutôt un gestionnaire

Handler mHandler = new Handler();

...

@Override
protected void onHandleIntent(Intent intent) {
    Toast.makeText(this, "onhandleintent", Toast.LENGTH_SHORT).show();
    mHandler.postDelayed( ToastRunnable, 5000);
    //while(true)
    //{

        //one minute is 60*1000
        //try {
        //    Thread.sleep(5 * 1000);
        //    Toast.makeText(getApplicationContext(), "getting app count",          
        //Toast.LENGTH_LONG).show();
        //} catch (InterruptedException e) {
            // TODO Auto-generated catch block
        //    e.printStackTrace();
        //}
    //}
}
final Runnable ToastRunnable = new Runnable(){
    public void run(){
         Toast.makeText(getApplicationContext(), "getting app count",          
               Toast.LENGTH_LONG).show();
         mHandler.postDelayed( ToastRunnable, 5000);
    }
}
6
jeremyvillalobos

Fais-le comme ça

    private void ping() {
    try {
        //Your code here or call a method
    } catch (Exception e) {
        Log.e("Error", "In onStartCommand");
        e.printStackTrace();
    }
      scheduleNext();
    }

    private void scheduleNext() {
      mHandler.postDelayed(new Runnable() {
        public void run() { ping(); }
      }, 60000);
    }

    public int onStartCommand(Intent intent, int x, int y) {
      mHandler = new Android.os.Handler();
      ping();
      return START_STICKY;
    }
2
Prashant Yadav