web-dev-qa-db-fra.com

Android pour le changement d'état de la connectivité Internet

Je crée une application où un utilisateur télécharge des informations et des fichiers sur mon serveur sur une base assez fréquente. Cela se fait dans de nouveaux threads via un service de téléchargement dédié.

Je sais de ce fil

Détectez si une connexion Internet est disponible sur Android

que vous pouvez vérifier s'il existe une connexion Internet relativement facilement. Vous pouvez également obtenir socketTimeoutExceptions pour détecter les problèmes de connectivité Internet. Tout cela est bien, et me permet de mettre en cache mes téléchargements assez facilement lorsque la connexion n'a pas fonctionné pour une raison quelconque.

Ma question est cependant de savoir comment savoir quand réessayer le téléchargement? Un événement est-il déclenché lorsque la connexion est rétablie? Ou suis-je coincé à créer un nouveau fil qui dort puis vérifie la connectivité Internet toutes les 30 secondes ou quelque chose?

Toute idée serait appréciée!

54
akhalsa

très vieux poste mais je voudrais partager mon récepteur

pas besoin de mettre la main sur des manifestes ou autres ressources ennuyeuses :)

USAGE

VOTRE ACTIVITÉ:

/*
 * You need to implement NetworkStateReceiverListener.
 * This interface is described inside the NewtworkStateReceiver class
 */
public class MyActivity implements NetworkStateReceiverListener {
    /* ... */
    private NetworkStateReceiver networkStateReceiver;
}

DANS VOTRE ACTIVITÉ: INSTANTIER LE RÉCEPTEUR

public void onCreate(Bundle savedInstanceState) {
    /* ... */
    networkStateReceiver = new NetworkStateReceiver();
    networkStateReceiver.addListener(this);
    this.registerReceiver(networkStateReceiver, new IntentFilter(Android.net.ConnectivityManager.CONNECTIVITY_ACTION));
}

public void onDestroy() {
    super.onDestroy();
    networkStateReceiver.removeListener(this);
    this.unregisterReceiver(networkStateReceiver);
}

DANS VOTRE ACTIVITÉ: METTRE EN ŒUVRE LES MÉTHODES REQUISES

@Override
public void networkAvailable() {
    Log.d("tommydevall", "I'm in, baby!");
    /* TODO: Your connection-oriented stuff here */
}

@Override
public void networkUnavailable() {
    Log.d("tommydevall", "I'm dancing with myself");
    /* TODO: Your disconnection-oriented stuff here */        
}

LE RÉCEPTEUR

il suffit de copier et coller dans votre projet en tant que NetworkStateReceiver.Java

public class NetworkStateReceiver extends BroadcastReceiver {

    protected Set<NetworkStateReceiverListener> listeners;
    protected Boolean connected;

    public NetworkStateReceiver() {
        listeners = new HashSet<NetworkStateReceiverListener>();
        connected = null;
    }

    public void onReceive(Context context, Intent intent) {
        if(intent == null || intent.getExtras() == null)
            return;

        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = manager.getActiveNetworkInfo();

        if(ni != null && ni.getState() == NetworkInfo.State.CONNECTED) {
            connected = true;
        } else if(intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,Boolean.FALSE)) {
            connected = false;
        }

        notifyStateToAll();
    }

    private void notifyStateToAll() {
        for(NetworkStateReceiverListener listener : listeners)
            notifyState(listener);
    }

    private void notifyState(NetworkStateReceiverListener listener) {
        if(connected == null || listener == null)
            return;

        if(connected == true)
            listener.networkAvailable();
        else
            listener.networkUnavailable();
    }

    public void addListener(NetworkStateReceiverListener l) {
        listeners.add(l);
        notifyState(l);
    }

    public void removeListener(NetworkStateReceiverListener l) {
        listeners.remove(l);
    }

    public interface NetworkStateReceiverListener {
        public void networkAvailable();
        public void networkUnavailable();
    }
}

PRENDRE PLAISIR ;)

109
Tommaso Resti

Si vous voulez simplement faire quelque chose de simple lorsque la connectivité change, il existe une solution beaucoup plus simple.

Dans votre activité, créez un récepteur de diffusion:

private BroadcastReceiver networkStateReceiver=new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = manager.getActiveNetworkInfo();
        doSomethingOnNetworkChange(ni);
    }
};

Puis dans onResume et onPause faites l'enregistrement:

@Override
public void onResume() {
    super.onResume();
    registerReceiver(networkStateReceiver, new IntentFilter(Android.net.ConnectivityManager.CONNECTIVITY_ACTION));
}

@Override
public void onPause() {
    unregisterReceiver(networkStateReceiver);
    super.onPause();
}
23
Xmister

Je ne sais pas trop ce qui se passait dans le récepteur de diffusion de Tommaso mais cela ne fonctionnait pas pour moi, voici mon implémentation. Il ne notifie que les changements de connectivité disponibles/indisponibles.

Je l'enregistre également dans onResume() et désenregistre dans onPause(). Sinon, c'est la même chose que ci-dessus.

public class NetworkStateReceiver extends BroadcastReceiver {

    private ConnectivityManager mManager;
    private List<NetworkStateReceiverListener> mListeners;
    private boolean mConnected;

    public NetworkStateReceiver(Context context) {
        mListeners = new ArrayList<NetworkStateReceiverListener>();
        mManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        checkStateChanged();
    }

    public void onReceive(Context context, Intent intent) {
        if (intent == null || intent.getExtras() == null)
            return;

        if (checkStateChanged()) notifyStateToAll();
    }

    private boolean checkStateChanged() {
        boolean prev = mConnected;
        NetworkInfo activeNetwork = mManager.getActiveNetworkInfo();
        mConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
        return prev != mConnected;
    }

    private void notifyStateToAll() {
        for (NetworkStateReceiverListener listener : mListeners) {
            notifyState(listener);
        }
    }

    private void notifyState(NetworkStateReceiverListener listener) {
        if (listener != null) {
            if (mConnected) listener.onNetworkAvailable();
            else listener.onNetworkUnavailable();
        }
    }

    public void addListener(NetworkStateReceiverListener l) {
        mListeners.add(l);
        notifyState(l);
    }

    public void removeListener(NetworkStateReceiverListener l) {
        mListeners.remove(l);
    }

    public interface NetworkStateReceiverListener {
        public void onNetworkAvailable();

        public void onNetworkUnavailable();
    }
}
11
darnmason

Android Nougat & O (API 24+) - État du réseau

Modifie la réponse en @darnmason (constructeur) pour le faire fonctionner API 24 +.

public NetworkStateReceiver(Context context) {
    mListeners =  new ArrayList<>();
    mManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
    context.registerReceiver(NetworkStateReceiver.this, intentFilter);

    checkStateChanged();
}
9
HKoncept