Android : Gestion du réseau

07 aout 2013 rdorigny 0 commentaires

Difficile d'évoquer Android sans parler des technologies réseaux tellement les applications mobiles les utilisent. Voyons un peu, ce que l'on peut faire avec le framework Android.




1)Tester si le réseau est disponible

La première chose à faire lorsque l'on veut réaliser une application réseau est de tester si le réseau est bien présent! Android propose la classe ConnectivityManager. Voici un exemple simple qui affiche la connectivité du réseau. Le layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <Button android:text="Afficher l'état de connectivité" android:id="@+id/MyBtn" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button> </RelativeLayout>

Pour le programme principale:
package fr.doritique.rzo1; import android.app.Activity; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.State; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { public Toast toast; public static final String TAG ="coucou"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button) findViewById(R.id.MyBtn); btn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { connex_rzo(); } }); } public void connex_rzo(){ ConnectivityManager connectivityManager=(ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); NetworkInfo networkInfo=connectivityManager.getActiveNetworkInfo(); int networkType=networkInfo.getType(); State networkstate=networkInfo.getState(); if (networkstate.compareTo(State.CONNECTED)==0){ toast=Toast.makeText(this,"Le réseau est disponible.",Toast.LENGTH_LONG); toast.show(); } else{ toast=Toast.makeText(this,"Le réseau n'est pas disponible.", Toast.LENGTH_LONG); toast.show(); } } }

Et surtout ne pas oublier dans le fichier manifest d'autoriser l'application à accéder à l'état du réseau!
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="fr.doritique.rzo1" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="fr.doritique.rzo1.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>

2)Envoyer et recevoir une requête http

Nous allons voir comment envoyer et recevoir une requête web. Cela peut être utile pour afficher des données ou réaliser un service web ultra-simpliste.
Google a réadapté le client http d'Apache, nous allons l'utiliser pour faire une requête http GET.

package fr.doritique.rzo1; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URI; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import android.app.Activity; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.State; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { public Toast toast; public static final String TAG ="coucou"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button) findViewById(R.id.MyBtn); btn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { //connex_rzo(); Affiche(); } }); } public void Affiche(){ //fonctionne avec Android 2.3.3 String str=http_get("http://www.doritique.fr/test.html"); toast=Toast.makeText(this,str,Toast.LENGTH_LONG); toast.show(); } public String http_get(String url){ StringBuffer stringbuffer=new StringBuffer(""); BufferedReader bufferedReader=null; try { HttpClient httpclient=new DefaultHttpClient(); HttpGet httpget=new HttpGet(); URI uri=new URI(url); httpget.setURI(uri); //Log.i(TAG,"coucou1"); HttpResponse httpresponse=httpclient.execute(httpget); //Log.i(TAG,"coucou2"); InputStream inputstream=httpresponse.getEntity().getContent(); bufferedReader=new BufferedReader(new InputStreamReader(inputstream)); String laligne=bufferedReader.readLine(); while (laligne!=null) { stringbuffer.append(laligne); stringbuffer.append("n"); laligne=bufferedReader.readLine(); } } catch (Exception e) { Log.e("",e.getMessage()); } finally { if (bufferedReader!=null){ try { bufferedReader.close(); } catch (IOException e) { Log.e("",e.getMessage()); } } } return stringbuffer.toString(); } }

Encore une fois, il est impératif de signaler dans le fichier manifest que l'application est autorisée à accéder au web.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="fr.doritique.rzo1" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="fr.doritique.rzo1.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>




Mais voilà, le code ci-dessus ne fonctionne qu'avec Android 2.X. Ma compréhension est que le fonctionnement des accès a changé depuis la version 3 d'Android. En effet, un accès réseau est potentiellement source de lenteur, ce qui n'est pas acceptable dans le programme principal. Donc, pour pallier à cela, il faudra utiliser une tâche asynchrone afin de désolidariser la réception de la requête du programme principal.
package fr.doritique.rzo4; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import android.app.Activity; public class MainActivity extends Activity { public Toast toast; public static final String TAG ="coucou"; public TextView letexte; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); letexte= (TextView) findViewById(R.id.letexte); Button btn = (Button) findViewById(R.id.MyBtn); btn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Affiche(); } }); } public void Affiche(){ new RequestTask2().execute("http://www.doritique.fr/test.html"); } private class RequestTask2 extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... urls) { String response = ""; for (String url : urls) { DefaultHttpClient client = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url); try { HttpResponse execute = client.execute(httpGet); InputStream content = execute.getEntity().getContent(); BufferedReader buffer = new BufferedReader(new InputStreamReader(content)); String s = ""; while ((s = buffer.readLine()) != null) { response += s; } } catch (Exception e) { e.printStackTrace(); } } return response; } @Override protected void onPostExecute(String result) { letexte.setText(result); } } }


Conclusion

Le framework Android simplifie largement le code à produire pour disposer de fonctionnalités réseaux dans vos applications.
Attention aux deux pièges classiques:
  • Pensez à modifier le fichier manifest pour autoriser votre application à accéder au réseau Internet,
  • Depuis Android 3.X, il est nécessaire d'utiliser une tâche asynchrone pour les fonctions réseaux, pas de code réseau directement dans le programme principal.


  • Le chapitre suivant sera dédié aux Web Service, avec un exemple de code pour un service restfull/json.






    Pseudonyme (obligatoire) :
    Adresse mail (obligatoire) :
    Site web :




    © 2017 www.doritique.fr par Robert DORIGNY