Android, A Complete Course, From Basics to Enterprise Edition

Gérer les connexions réseau

Android, A Complete Course, From Basics to Enterprise Edition. 1

Gérer les connexions réseau. 1

Communiquer avec le système. 1

1.1         Gérer les connexions réseau. 1

 Cet article est extraie du livre « Android, A Complete Course », disponible sur Android2ee.com.

Les exemples ou les programmes présents dans cet ouvrage sont fournis pour illustrer les descriptions théoriques. Ce code est libre de toute utilisation mais n'est pas distribuable.

La distribution du code est reservée au site :

http://android2ee.com.

La propriété intellectuelle du code appartient à :

Mathias Séguy

L’utilisation de ces codes est sous votre unique responsabilité et personne d’autre que vous ne pourra être tenu responsable des préjudices ou dommages de quelques natures que ce soit pouvant résulter de son utilisation.

Tous les noms de produits ou marques cités dans cet ouvrage sont des marques déposés par leurs propriétaires respectifs.

Publié par http://android2ee.com

Titre Original : Android, A Complete Course, From Basics to Enterprise Edition. Édition Française.

ISBN : 979-10-90388-00-0

Copyright © 2011 by Mathias Séguy

 

Aucune représentation ou reproduction, même partielle, autre que celles prévues à l’article L. 122-5 2° et 3° a) du code de la propriété intellectuelle ne peut être faite sans l’autorisation expresse de Mathias Seguy ou, le cas échéant, sans le respect des modalités prévues à l’article L. 122-10 dudit code

Communiquer avec le système

1.1       Gérer les connexions réseau

1.1.1       Gérer les connexions réseau (GPRS, 3G, Wifi)

Il y a deux types de connexions différentes : le network  « mobile » et le wifi. Chacun possède ses propres méthodes et sa propre gestion.

Tout d’abord, dès que votre application doit communiquer avec internet, vous devez vous assurer de la préférence utilisateur concernant le transfert de données en tache de fond. En d’autre terme si votre activité est en pause, peut-elle continuer à utiliser le réseau. Si ce n’est pas le cas, vous ne devez en aucun cas l’utiliser.

Dans ce chapitre, nous expliquerons :

·         Comment connaitre la préférence réseau Wifi ou réseau mobile de l’utilisateur,

·         comment parcourir les réseaux mobiles et récupérer leurs informations,

·         comment parcourir les réseaux wifi, scanner ces réseaux et se connecter à l’un d’eux,

·         enfin comment écouter les changements d’états de changement de connexion à un réseau.

Les objets principaux de la manipulation des réseaux sont :

·         Le ConnectivtyManager pour gérer l’ensemble des réseaux,

·         Le NetworkInfo qui porte les informations associées à un réseau

·         Le WifiManager pour gérer les réseaux WIFI,

·         Le WifiInfo qui porte les informations associées à un réseau Wifi

·         Le ScanResult qui porte les informations associées à un réseau WIFI découvert suite à un scan de réseau Wifi

·         Le WifiConfiguration qui porte les informations associées aux réseaux Wifi déjà configurés sur l’appareil

Enfin pour pouvoir manipuler ces paramètres réseaux, il faut demander les permissions suivantes dans votre manifest.xml :

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission>

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>

<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>

1.1.1.1       Accéder aux préférences de l’utilisateur

Il y a deux types de préférences, le droit d’utiliser le réseau en tâche de fond et la préférence du réseau à utiliser.

1.1.1.1.1        Demander à l’utilisateur de modifier sa préférence sur le traitement en tâche de fond

Pour cela vous devez instancier le ConnectivityManager et récupérer le paramètre getBackgroundDataSetting. Si celui-ci est à faux, vous pouvez demander à l’utilisateur de changer ses préférences. Pour cela afficher lui un message lui demandant de le faire puis écouter le changement de préférence. Comme d’habitude cette écoute s’appuie sur la déclaration d’un BroadCastReceiver et l’enregistrement de ce receiver à l’intention ACTION_BACKGROUND_DATA_SETTING_CHANGED.

Le code ci-dessous montre comment si prendre :

  /**   * The connectivity Manager (for network)   */

  ConnectivityManager connectivityManager;

  /*   * (non-Javadoc)   *    * @see android.app.Activity#onCreate(android.os.Bundle)   */

  @Override

  protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    // First Instanciate the Wifi and Connectivity Managers:

    connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

    // Then detect user preference for network usage

    // Do i have the right to use network in background (when my activty is hidden)

    Boolean networkUsedInBackground = connectivityManager.getBackgroundDataSetting();

    // If you really need the exchange data in background using the network, ask user:

    if (!networkUsedInBackground) {

      // Instanciate the state changed listening using broadcast

      registerbackgroundExchangeOnNetWorkBroadcastReceiver();

      // Ask user to change its pereferences

      Toast.makeText(

          this,

          "Could you please change your preference for network usage "

              + "(Parameter>Account And syncronization>BackgroundData parameters)",

          Toast.LENGTH_SHORT).show();

      // normally you should wait the user to change its preference using a

      // while(atomicBoolean userChangeItsPrference)

      // or use a toast display a message with a yes||no

    }

  } 

  /*******************************************************************************/

  /** Asking user to exchange data in background using the network *************************/

  /********************************************************************************/

  /**   * Define the brodcast receiver that listen for background network usage   */

  private BroadcastReceiver backgroundExchangeOnNetWorkBroadCastReceiver = new BroadcastReceiver() {

    @Override

    public void onReceive(Context context, Intent intent) {

      // Find the cuurent state (you can also call EXTRA_PREVIOUS_STATE for the previous

      // state)

      if (connectivityManager.getBackgroundDataSetting()) {

        // the user change its preferences

      } else {

        // the user doesn't want you to use network in background, that's all

        // You then can kill your activity or find a workaround

      }

      // anyway, the answer is given

      unregisterReceiver(backgroundExchangeOnNetWorkBroadCastReceiver);

    }

  };

  /**   * To be call when asking the user to change its preference   */

  private void registerbackgroundExchangeOnNetWorkBroadcastReceiver() {

    // register the previous BroadCast associated to the Intent Action State Changed

    registerReceiver(backgroundExchangeOnNetWorkBroadCastReceiver, new IntentFilter(

        ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED));

  }

 

1.1.1.1.2        Récupérer la préférence du réseau Wifi ou Mobile de l’utilisateur

La méthode getNetworkPreference de l’objet ConnectivityManager est à utiliser :

  /**   * The connectivity Manager (for network)   */

  ConnectivityManager connectivityManager;

  /*   * (non-Javadoc)   *    * @see android.app.Activity#onCreate(android.os.Bundle)   */

  @Override

  protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    // First Instanciate the Wifi and Connectivity Managers:

    connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

    // Browse user preferences

    browseUserPreference();

  }

  /************************************************************************************/

  /** Managing User preference ***********************************************************/

  /**********************************************************************************/

  /** Browse user preferences */

  private void browseUserPreference() {

    switch (connectivityManager.getNetworkPreference()) {

    case ConnectivityManager.TYPE_WIFI:

    case ConnectivityManager.TYPE_MOBILE:

      break;

    }

    // And you can set the prefernce you want:

    connectivityManager.setNetworkPreference(ConnectivityManager.TYPE_WIFI);

  }

1.1.1.2       Parcourir les réseaux, récupérer les informations et écouter les changements d’états de connections

Pour récupérer l’ensemble des réseaux et leurs informations il faut appeler la méthode getAllNetworkInfo de l’objet ConnectivityManager. Cette méthode renvoie un ensemble de networkInfo qui porte les informations du réseau associé. Les informations principales sont décrites dans le code ci-dessous.

Pour écouter les changements d’états de la connexion réseau, l’utilisation d’un BroadCastReceiver et son enregistrement en tant qu’écouteur de l’événement CONNECTIVITY_ACTION  est à utiliser.

Le code ci-dessous présente ces deux aspects :

/** * The connectivity Manager (for network) */

ConnectivityManager connectivityManager;

/* * (non-Javadoc) *  * @see android.app.Activity#onCreate(android.os.Bundle) */

@Override

protected void onCreate(Bundle savedInstanceState) {

                // Browse mobile networks and retrieve their parameters

                browseMobileNetworks();

                // And Listen for Network state changed

                registerConnectivityStateChanged();

}

/**************************************************************************************/

/** Browsing the Mobile networks **********************************************************/

/**************************************************************************************/

/** * Browse network and detect their parameters */

private void browseMobileNetworks() {

                // retireve all the networks around

                NetworkInfo[] networksInfo = connectivityManager.getAllNetworkInfo();

                // Network Info

                NetworkInfo netWorkInfo;

                // Network type and subtype

                int networkType;

                // network state

                NetworkInfo.State state;

                for (int i = 0; i < networksInfo.length; i++) {

                               netWorkInfo = networksInfo[i];

                               // Retrieve network type

                               networkType = netWorkInfo.getType();

                               if (networkType == ConnectivityManager.TYPE_MOBILE) {

                                               // The different possible states for your network

                                               state = netWorkInfo.getState();

                                               switch (netWorkInfo.getState()) {

                                               case CONNECTING:

                                               case CONNECTED:

                                               case SUSPENDED:

                                               case DISCONNECTING:

                                               case DISCONNECTED:

                                               case UNKNOWN:

                                                               break;

                                               }

                                               // Others states vision:

                                               netWorkInfo.isAvailable();

                                               netWorkInfo.isConnected();

                                               netWorkInfo.isConnectedOrConnecting();

                                               netWorkInfo.isFailover();

                                               netWorkInfo.isRoaming();

                               } else {

                                               // others connections can be WIFI

                                               networkType = ConnectivityManager.TYPE_WIFI;

                                               // Cial Up Networking bridge

                                               networkType = ConnectivityManager.TYPE_MOBILE_DUN;

                                               // High Priority Mobile Data Connection

                                               networkType = ConnectivityManager.TYPE_MOBILE_HIPRI;

                                               // Multi Media Messaging Service

                                               networkType = ConnectivityManager.TYPE_MOBILE_MMS;

                                               // Secure User Plane Location

                                               networkType = ConnectivityManager.TYPE_MOBILE_SUPL;

                               }

 

                }

}

/***********************************************************************************/

/** Listen for connectivity changes *******************************************************/

/***********************************************************************************/

/** * Define the brodcast receiver that listen for connectivty changes */

private BroadcastReceiver connectivityChangesBroadCastReceiver = new BroadcastReceiver() {

                @Override

                public void onReceive(Context context, Intent intent) {

                               final String action = intent.getAction();

                               // insure you are listening for the right intent

                               if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {

                                               // Is there a connectivity?

                                               boolean noConnectivity = intent.getBooleanExtra(

                                                                              ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);

                                               // Is there a change in the connection from the prefered network to this one

                                               boolean isFailover = intent.getBooleanExtra(

ConnectivityManager.EXTRA_IS_FAILOVER,

                                                                              false);

                                               // Retrieve networkInfo

                                               NetworkInfo currentNetworkInfo = (NetworkInfo) intent.getParcelableExtra(

ConnectivityManager.EXTRA_NETWORK_INFO);

                                               // This is supplied when there is another network that it may be possible to connect

                                               // to.

                                               NetworkInfo otherNetworkInfo = (NetworkInfo) intent.getParcelableExtra(

ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);

                                               // string that indicates why an attempt to connect to a network failed

                                               String failureReason = intent.getStringExtra(

ConnectivityManager.EXTRA_REASON);

                                               // string that provides optionally supplied extra information about the network

                                               // state

                                               String extraInformations = intent.getStringExtra(

ConnectivityManager.EXTRA_EXTRA_INFO);

                               }

                }

};

 

/** And Listen for Connectivty state changed */

private void registerConnectivityStateChanged() {

// register the previous BroadCast associated to the Intent Action Connectivity Changed

registerReceiver(connectivityChangesBroadCastReceiver, new IntentFilter(

                                               ConnectivityManager.CONNECTIVITY_ACTION));

}