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?
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 ...
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);
}
}
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;
}