Garder le wifi actif dans le service de premier plan après que le téléphone s'est endormi

je veux recevoir des paquets de wifi quand mon téléphone est verrouillé. Le problème est que lorsque je ferme mon écran, mon service de premier plan cesse de recevoir des paquets. J'utilise le service de premier plan comme ceci:

public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
    var notification = new Notification.Builder(this)
        .SetContentTitle(Resources.GetString(Resource.String.app_name))
        .SetContentText(Resources.GetString(Resource.String.notification_text))
        .SetSmallIcon(Resource.Drawable.ic_stat_name)
        .SetContentIntent(BuildIntentToShowMainActivity())
        .SetOngoing(true)
        .AddAction(BuildRestartTimerAction())
        .AddAction(BuildStopServiceAction())
        .Build();


    // Enlist this instance of the service as a foreground service
    StartForeground(Constants.SERVICE_RUNNING_NOTIFICATION_ID, notification);

    /*DO THIS EVEN WHEN SCREEN IS LOCKED*/

    var powerManager = (PowerManager)GetSystemService(PowerService);
    _wakeLock = powerManager.NewWakeLock(WakeLockFlags.Partial, "WakeLockTag");
    _wakeLock.Acquire();

    var wifiManager = (WifiManager)GetSystemService(WifiService);
    _wifiLock = wifiManager.CreateWifiLock(WifiMode.FullHighPerf, "xamarin_wifi_lock");
    _wifiLock.Acquire();

    if (!powerManager.IsIgnoringBatteryOptimizations("com.xamarin.xample.foregroundservicedemo") ||
        !_wakeLock.IsHeld || !_wifiLock.IsHeld)
        throw new InvalidOperationException("OPTIMIZATIONS NOT ACTIVE");

    string msg = timestamper.GetFormattedTimestamp();
    Log.Debug(TAG, msg);
    Intent intent = new Intent(Constants.NOTIFICATION_BROADCAST_ACTION);
    intent.SetAction(Android.Provider.Settings.ActionIgnoreBatteryOptimizationSettings);
    intent.PutExtra(Constants.BROADCAST_MESSAGE_KEY, msg);
    LocalBroadcastManager.GetInstance(this).SendBroadcast(intent);
    Task.Run(() =>
    {
        using (var client = new UdpClient(12345))
        {
            while (true)
            {
                var result = client.ReceiveAsync().Result;
                Console.WriteLine($"RECEIVED: {result.Buffer.Length}");
            }
        }
    });

    return StartCommandResult.Sticky;
}

je fais les choses suivantes pour m'assurer que c'est pas tué:

  1. Démarrage Du Service De Premier Plan
  2. en utilisant StartCommandResult.Sticky
  3. Utilisant Le Verrouillage De Sillage
  4. Utilisant Le Wifi Lock
  5. réglage WifiSleepPolicy to Never (je l'ai d'installation dans mon téléphone les paramètres)
  6. ActionIgnoreBatteryOptimizationSettings dans l'intention
  7. liste Blanche de mon application par le biais de la bad invite de commande de débogage

Qu'est-ce que je rate d'autre? J'utilise Samsung A5 avec Android 6.0-API 23.

j'ai regardé dans les logs de l'invite de commande adb et j'ai vérifié que mon service fonctionne en fait comme service de premier plan et que toutes les serrures sont maintenues.

22
demandé sur Zaren Wienclaw 2018-08-04 13:04:04

1 réponses

Ce que vous faites est tout simplement génial, tout est bon. cependant!!

Laissez-nous jeter un oeil à devleport.android.composte:

les politiques de Google Play interdisent aux applications de demander une exemption directe des fonctionnalités de gestion de L'alimentation dans Android 6.0+ (Doze et L'application en veille) à moins que la fonction principale de l'application est affectée.

Vous avez dit:

J'utilise Samsung A5 avec Android 6.0-API 23.

ce qui veut dire que vous ne pourrez pas garder votre service avant-plan quand le téléphone s'endormira parce que la fonction principale de l'application estpas affecté négativement.

C'est la raison pour laquelle vous remarquez que vous avez cessé de recevoir des paquets lorsque le téléphone est endormi.

s'il vous plaît consulter le lien que j'ai joint ainsi que nous l' Gestionnaire D'Alimentation guide.

modifier: j'ai maintenant remarqué qu'en outre:

si un utilisateur laisse un appareil non branché et stationnaire pendant une période de temps, avec l'écran éteint, l'appareil entre en mode Doze. En mode Doze, le système tente de conserver la batterie en limitant l'accès des applis services à forte intensité de réseau et de CPU. Il empêche également les applications de l'accès au réseau et reporte leur emploi, les synchronisations et standard alarme.

Doze restrictions:

  • l'accès au Réseau est suspendu.
  • le système ignore les serrures de sillage.
  • alarmes AlarmManager Standard (y compris setExact() et setWindow()) sont reportés à la prochaine fenêtre de maintenance.
  • si vous avez besoin de mettre des alarmes qui s'allument pendant que vous êtes à Doze, utilisez setAndAllowWhileIdle () ou setExactAndAllowWhileIdle ().
  • les alarmes avec setAlarmClock () continuent à fonctionner normalement - le le système quitte le Doze peu de temps avant que les alarmes incendie.
  • le système n'effectue pas de balayages Wi-Fi.
  • le système ne permet pas aux adaptateurs sync de fonctionner.
  • le système ne permet pas à JobScheduler de fonctionner.

ceci terminera ma réponse à toutes vos questions.

EDIT 2:

j'ai étudié un peu plus loin, il y a tout un post concernant ce problème dans Xamarin.Android.

il y a aussi une solution pour réveiller le téléphone toutes les 10 minutes pour contourner ici.

5
répondu Barr J 2018-08-06 12:09:42