web-dev-qa-db-fra.com

Détecter les changements de connectivité sur Android 7.0 Nougat lorsque l'application est au premier plan

Nougat a changé la façon dont il gère les intentions de CONNECTIVITY_CHANGED (en l'ignorant, obligeant les développeurs à utiliser le planificateur de travaux), cela me laisse perplexe:

Si j'ai une application qui est en train de récupérer des données (et que j'ai vérifié si le téléphone était en ligne au moment où j'ai fait la demande mais que l'utilisateur est en déplacement et que le téléphone se connecte à un autre point d'accès wifi, par exemple ) et en cas d’échec, comment puis-je détecter que la connexion a été restaurée et que je peux réessayer de récupérer les données?

Donc, dans ce cas, mon application est au premier plan, je pense que Chrome (pour Android) a une fonction similaire. 

Dois-je le consulter moi-même? Ou y a-t-il un événement autorisé à ce moment-là?

9
REJH

Les applications en cours d'exécution peuvent toujours écouter CONNECTIVITY_CHANGE sur leur thread principal si elles demandent une notification avec BroadcastReceiver.

https://developer.Android.com/about/versions/nougat/Android-7.0-changes.html

4
Andromeda

Bien que la réponse d'Andromeda puisse être utilisée, cette solution n'est pas le choix de Google. Votre question était de savoir quoi faire lorsqu'une connexion est perdue et vous devez reprendre l'opération lorsque le service réseau est rétabli.

Bien que CONNECTIVITY_CHANGE fonctionne techniquement, il a toujours été un peu un piratage pour ce besoin spécifique et il cessera de fonctionner dans Nougat dès que votre application sera en arrière-plan. Ce que vous devriez vraiment utiliser est une API de planificateur de travaux. Google nous a offert de nombreuses options avec des exigences et des fonctionnalités différentes.

  1. JobScheduler

JobScheduler a été ajouté à Lollipop et ajoute un planificateur qui peut attendre la connectivité réseau pour planifier un travail. Cela peut même dépendre du type de connexion, en recherchant des connexions non mesurées ou non itinérantes. Cette option n'a pas de compatibilité ascendante, mais fonctionne sans les services Google Play.

  1. Gestionnaire de réseau GCM

GcmNetworkManager est un portage direct de la fonctionnalité JobScheduler vers les versions antérieures à Lollipop, mais il nécessite les services Google Play. GcmNetworkManager est en grande partie obsolète par Firebase Job Dispatcher.

  1. Répartiteur de tâches Firebase

Firebase JobDispatcher fournit un autre moyen de planifier les travaux pour les versions antérieures à Lollipop, qui utilise les services Google Play par défaut, mais peut être configuré pour ne pas nécessiter cette dépendance.

Les trois options satisferont vos besoins de manière conviviale, et vos tâches seront toujours planifiées, même si l'appareil quitte brièvement le mode Doze.

Voici plus d'informations sur les différentes options avec des exemples fournis par Google:

https://developer.Android.com/topic/performance/scheduling.htmlhttps://developer.Android.com/topic/performance/background-optimization.html#sched-jobs

10
colintheshots

Selon doc :

Les applications ciblant Android 7.0 (API de niveau 24) et les versions ultérieures ne reçoivent pas les diffusions CONNECTIVITY_ACTION si elles déclarent leur récepteur de diffusion dans le manifeste. Les applications recevront toujours les émissions CONNECTIVITY_ACTION si elles enregistrent leur BroadcastReceiver avec Context.registerReceiver() et que ce contexte est toujours valide.

5
Amir Rezazadeh

Dans mon cas, je suis abonné à broadcast avec le filtre CONNECTIVITY_CHANGE dans Service et tout fonctionne.

Comment garder Service vivant est une autre histoire :)

2
Penzzz
public class ConnectivityReceiver
{

public static boolean getWifiStatus(Context context)
{
    // To get System Connectivity status
    ConnectivityManager cm = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);


    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    if (null != activeNetwork)
    {
        // Check For Wifi Status
        if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
            return true;
        else
            return false;
    }

    return false;
}

public class NetworkMgr extends BroadcastReceiver {

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

    ConnectivityReceiver cf = new ConnectivityReceiver();
    boolean status = cf.getWifiStatus(context);

    if(status)
    {
        Toast.makeText(context,"Wifi Connection is On.", Toast.LENGTH_SHORT).show();
    }
    else
    {
        Toast.makeText(context,"Wifi Connection is Off.", Toast.LENGTH_SHORT).show();
    }
  }
}
0