web-dev-qa-db-fra.com

Besoin d'un exemple de code sur la façon d'exécuter un service Android pour toujours en arrière-plan, même lorsque l'appareil est en veille, comme Whatsapp?

J'ai essayé différentes manières d'y parvenir, mais mon service finit par être tué.

Je veux utiliser AlarmManager pour déclencher une classe toutes les heures. Même si l'appareil est en veille, il doit envoyer une alerte LED clignotante, des vibrations ou du son. Dans tous les cas, il devrait fonctionner indéfiniment.

J'ai remarqué que Whatsapp est toujours en cours d'exécution, même si je tue toutes les applications en cours d'exécution et efface la mémoire, met l'appareil en veille et que Whatsapp reçoit toujours des messages et m'alerte. Comment le font-ils? Je veux faire de même avec mon application.

24
zeeshan

Depuis que j'ai posé cette question, j'ai mis en œuvre deux approches différentes de cette solution dans plusieurs applications.


APPROCHE 1

Cet extrait provient d'une application où j'utilise des notifications Push, qui nécessitent des appels de réveil instantanés pour l'appareil. Voici ce que je fais

  1. utiliser l'autorisation WAKE_LOCK et
  2. utiliser une classe abstraite Wakelocker
  3. l'utiliser dans une activité au besoin:

Manifeste:

<uses-permission Android:name="Android.permission.WAKE_LOCK" />

classe WakeLocker:

public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;

public static void acquire(Context context) {
    if (wakeLock != null) wakeLock.release();

    PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
            PowerManager.ACQUIRE_CAUSES_WAKEUP |
            PowerManager.ON_AFTER_RELEASE, "WakeLock");
    wakeLock.acquire();
}

public static void release() {
    if (wakeLock != null) wakeLock.release(); wakeLock = null;
}
}

Exemple de classe d'activité:

private final BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // Waking up mobile if it is sleeping
        WakeLocker.acquire(getApplicationContext());
        // do something
        WakeLocker.release();
}

APPROCHE 2

Idéal lorsque vous souhaitez donner Android contrôle sur le réveil, et pouvez vivre avec réveil périodique de votre code. Utilisez simplement un AlarmManager pour appeler une classe de service à intervalles réguliers. Voici un code de mon Application LifeLog24:

MainActivity

Intent ll24 = new Intent(context, AlarmReceiverLifeLog.class);
    PendingIntent recurringLl24 = PendingIntent.getBroadcast(context, 0, ll24, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    alarms.setRepeating(AlarmManager.RTC_WAKEUP, first_log.getTime(), AlarmManager.INTERVAL_HOUR, recurringLl24); // Log repetition

Classe d'alarme

public class AlarmReceiverLifeLog extends BroadcastReceiver {

    private static final String TAG = "LL24";
    static Context context;

    @Override
    public void onReceive(Context context, Intent intent) {

        Log.v(TAG, "Alarm for LifeLog...");

        Intent ll24Service = new Intent(context, LifeLogService.class);
        context.startService(ll24Service);
    }
    }

et LifeLogService.class est l'endroit où je fais mes affaires. L'alarme se réveille toutes les heures dans ce cas et déclenche le BroadcastReceiver qui en retour exécute le service. Il y a plus, pour vous assurer que le service n'est pas exécuté deux fois et ainsi de suite, mais vous comprenez comment il est fait. Et AlarmManager est en fait le meilleur moyen de le faire puisque vous ne vous inquiétez pas de l'utilisation de la batterie, etc. et Android s'occupe de réveiller votre service à intervalles réguliers.

25
zeeshan

C'est très simple.
pas:
1.créer une classe de service.
2.créer une classe BroadcastReceiver
3.call BroadReceiver dans onDestroy méthode de service
4.In onReceive méthode de service de démarrage de classe BroadReceiver encore une fois.

Voici le code

Fichier manifeste: `

<application
    Android:allowBackup="true"
    Android:icon="@mipmap/ic_launcher"
    Android:label="@string/app_name"
    Android:roundIcon="@mipmap/ic_launcher_round"
    Android:supportsRtl="true"
    Android:theme="@style/AppTheme">

    <activity Android:name=".LauncherActivity">
        <intent-filter>
            <action Android:name="Android.intent.action.MAIN" />

            <category Android:name="Android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <service
        Android:name=".utilities.NotificationService"
        Android:enabled="true">

    </service>

    <receiver
        Android:name=".utilities.RestartService"
        Android:enabled="true"
        Android:exported="true"
        Android:label="RestartServiceWhenStopped"
        Android:permission="Android.permission.RECEIVE_BOOT_COMPLETED">
        <intent-filter>
            <action Android:name="RestartService" />
        </intent-filter>
    </receiver>
</application>

"

Classe de service

public class NotificationService extends Service {
    public NotificationService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

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

   @Override
   public void onDestroy() {
       super.onDestroy();
       Intent restartService = new Intent("RestartService");
       sendBroadcast(restartService);
  }
}

classe BroadcastReceiver

public class RestartService extends BroadcastReceiver {

     @Override
     public void onReceive(Context context, Intent intent) {

         context.startService(new Intent(context,NotificationService.class));
     }
 }
8
Vignesh VRT

Suivez ces étapes faciles pour garder le service en vie pour toujours dans Android. 1. Appelez un service à l'aide du gestionnaire d'alarmes. 2. renvoyez START_STICKY dans la méthode onStart. 3. Dans la destruction, appelez le gestionnaire d'alarmes et redémarrez le service à l'aide de la méthode startService 4. (Facultatif) Répétez le point numéro 3 dans la méthode onTaskRemoved.

1
Syed Danish Haider

Demander un WakeLock partiel.

<uses-permission Android:name="Android.permission.WAKE_LOCK" />

 PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "My Tag");
mWakeLock.acquire();

onStartCommand retrun START_STICKY:

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