Android : Stocker des données

16 novembre 2012 rdorigny 0 commentaires

Il existe plusieurs solutions pour enregistrer des données: les shared preferences, le stockage interne ou externe, la base de données SQLite, les données réseaux, les services web...

Nous allons étudier les solutions simples qui peuvent être rapidement mises en oeuvre, les méthodes plus complexes feront l'objet d'un chapitre dédié.


1) Les préférences partagées (Shared Preferences)

Cette méthodologie permet de sauvegarder des informations dans un fichier via le framework Android. Ces informations sont accessibles aux différents processus de l'application. Ce sont des données primitives (entier, booléen, ...) qui sont stockées par paire clé-donnée. On les utilise beaucoup pour sauvegarder des données de sessions ou de configuration.

Ces informations sont stockées sous /data/data/package_name/shared_prefs. Par défaut, root et l'application sont les seuls autorisés à accéder à ces informations.

1.1)Lecture de préférences

Il existe deux méthodes pour créer une préférence:
  • getSharedPreferences(String,int): renvoit une instance des préférences de la classe SharedPreferences. Le string correspond au nom de l'ensemble de préférence,
  • getPreferences(int): Dans la plupart des cas, et par convention, le nom de l'ensemble des préférences est le nom de l'activité courante, et donc il est inutile de préciser le string. Un seul ensemble est généralement suffisant.

  • L'entier passé en paramètre précise le mode d'accès aux préférences. On distingue:
  • MODE_PRIVATE: l'ensemble n'est accessible que par l'application,
  • MODE_WORLD_READABLE: les autres applications peuvent lire l'ensemble,
  • MODE_WORLD_WRITEABLE: les autres applications peuvent modifier l'ensemble,
  • MODE_MULTI_PROCESS: plusieurs processus peuvent accéder à l'ensemble.

  • Dés que nous disposons d'une instance de l'ensemble de préférences, on utilisera des méthodes pour accéder aux informations pour chaque type basique :
  • getString(variable,valeur): Cette méthode renvoit le contenu de la variable demandé, si elle n'existe pas , elle renverra la valeur passée en second paramètre,
  • getInt(variable,valeur): Idem pour un entier,
  • getFloat(variable,valeur): Idem pour un réel,
  • getLong(variable,valeur): Idem pour un entier long,
  • getBoolean(variable,valeur): Idem pour un booléen,
  • getAll(variable,valeur): Renvoit une collection Map(String,?).
  • 1.2)Ecriture de préférences

    L'interface Editor de la classe SharedPreferences dispose de toutes les méthodes pour écrire: putInt, putString, putFloat, putBoolean et putLong. Les paramétres seront la clé puis la valeur.

    Il ne faut pas oublier d'appliquer l'écriture par la méthode commit() de façon synchrone ou apply() (copie immédiate en mémoire mais asynchrone sur le disque).

    1.3)Exemple

    Pour activity_main.xml:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Appuyez pour afficher la préférence" tools:context=".MainActivity" /> <Button android:id="@+id/bouton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="OK" /> </LinearLayout>

    Pour MainActivity.java:
    package com.example.preferenceshared; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; public class MainActivity extends Activity implements OnClickListener { private String texte="Ceci est un test"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SharedPreferences prefs=getPreferences(Context.MODE_PRIVATE); //Création de l'éditeur SharedPreferences.Editor editor=prefs.edit(); editor.putString("S1", texte); editor.commit(); Button bt =(Button) findViewById(R.id.bouton); bt.setOnClickListener(this); } @Override public void onClick(View v) { SharedPreferences prefs=getPreferences(Context.MODE_PRIVATE); String test=prefs.getString("S1", null); Toast toast=Toast.makeText(this,test,Toast.LENGTH_LONG); toast.show(); } }


    Ce qui donnera:

    A noter qu'il existe une méthodologie pour réagir aux évènements sur les modifications des préférences. On enregistre par l'écouteur .registerOnSharedPeferenceChangeLitener() et en surchargeant la méthode onSharedPreferenceChanged .

    2)Utiliser des fichiers pour stocker des données

    2.1)Généralités

    Il est possible d'utiliser la classe java.io,néanmoins le framework Android propose des outils pour manipuler les fichiers.

    Les méthodes disponibles pour le traitement des fichiers:
  • openFileOutput() de la classe OutputStream ouvre le fichier en écriture avec le nom du fichier et le mode d'ouverture du fichier,
  • openFileInput() de la classe InputStream ouvre le fichier en lecture,
  • utilisez la méthode read() pour lire les données,
  • write() pour remplir le buffer que la méthode openFileOutput() nous a fourni,
  • close() qui permet de fermer le fichier en s'assurant que tout ce qui a été écrit est bien sauvegardé.

  • Les modes d'ouvertures sont:
  • MODE_PRIVATE: pour créer un fichier privé à votre application.
  • MODE_APPEND: possède le même principe que MODE_PRIVATE mais possible d'écrire à la fin du fichier plutôt que de l'écraser,
  • MODE_WORLD_READABLE: permet de lire ce fichier,
  • MODE_WORLD_WRITEABLE: permet de lire ce fichier.
  • 2.2)Stockage statique

    Android propose de stocker des fichiers dans le fichier *.apk du package de l'application. Il suffit de copier vos fichiers sous res/raw/monfic.* .

    Le fichier sera intégré comme une ressource par le framework (en lecture). Et par la méthode getRessources() associé à openRawRessource(), on obtient un InputStream sur notre fichier et donc on ne pourra modifier ce fichier. Il proposera des données statiques.

    Dans l'exemple très simple qui suit, nous affichons la première ligne d'un fichier texte.

    Le fichier text.txt:
    Je lis dans le fichier.

    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" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="OK"/> </RelativeLayout>

    Le fichier MainActivity.java:
    package fr.doritique.filedemo; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import android.os.Bundle; import android.app.Activity; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { public TextView montextview; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); montextview=(TextView) findViewById(R.id.text); try { InputStream in=getResources().openRawResource(R.raw.test); //On créé un reader pour lire dedans InputStreamReader tmp=new InputStreamReader(in); BufferedReader reader = new BufferedReader(tmp); String str=reader.readLine(); montextview.setText(str); } catch (Exception e) { Toast.makeText(this, "Marche pas", Toast.LENGTH_LONG); } } }

    2.3)Stockage interne

    Il est possible de stocker des informations dans un fichier interne sur la mémoire du téléphone.
    package fr.doritique.filedemo; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { public TextView montextview; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); montextview=(TextView) findViewById(R.id.text); String FILE_NAME = "monfic"; String string = "hello world! It's me."; //Ecriture dans un fichier try { FileOutputStream fo = openFileOutput(FILE_NAME, Context.MODE_PRIVATE); fo.write(string.getBytes()); fo.close(); } catch (Exception e) { Toast.makeText(this, "Marche pas", Toast.LENGTH_LONG); } //Lecture de la premiére ligne try { FileInputStream fo = openFileInput(FILE_NAME); InputStreamReader tmp=new InputStreamReader(fo); BufferedReader reader = new BufferedReader(tmp); montextview.setText(reader.readLine()); fo.close(); } catch (Exception e) { Toast.makeText(this, "Marche pas", Toast.LENGTH_LONG); } } }



    Le fichier sera stocké sur la mémoire interne du mobile sous /data/app/data/nom_package/files . Il est possible d'explorer les fichiers avec l'outil de debug DDMS (Dalvik Debug Monitor Server). Sous Eclipse, faire par le menu Windows -> Open Perspectives -> Others... Sélectionner DDMS puis OK. Ensuite choisir l'onglet File explorer.

    A noter qu'il est possible d'utiliser les boutons de menus pour récupérer le fichier et vérifier son contenu.

    2.4)Stockage externe

    Il s'agit de stocker un fichier dans une mémoire de masse externe à l'appareil comme par exemple avec une carte mémoire. Rappelons que le système Android est basé sur Linux, et donc il est possible d'accéder à la SDCARD par /mnt/sdcard .

    Le framework Android propose des méthodes pour tester si le stockage est disponible, ainsi que de connaitre son état (lecture & écriture). Environment.getExternalStorageState() renvoit le chemin du stockage externe, soit généralement /mnt/sdcard.
    String etat=Environment.getExternalStorageState(); //Toast.makeText(this, etat, Toast.LENGTH_LONG).show(); if (Environment.MEDIA_MOUNTED.equals(etat)){ montextview.setText("Le stockage est accessible en lecture écriture."); } else { if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(etat)){ montextview.setText("Le stockage est accessible uniquement en écriture."); } else montextview.setText("Le stockage n'est pas accessible."); }

    Pour autoriser l'écriture sur le stockage, il est nécessaire d'ajouter la ligne suivante au fichier manifest :
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    Ensuite, il est possible d'écrire sur la sdcard en utilisant le java classique.
    File directory=Environment.getExternalStorageDirectory(); //directory sera probablement /mnt/sdcard/ //montextview.setText(directory.toString()); File file=new File(directory+"/myfile.txt"); try { //Création du fichier if (!file.exists()){ file.createNewFile(); } //Ecriture dans le fichier FileWriter fw=new FileWriter(file); BufferedWriter writer = new BufferedWriter(fw); writer.newLine(); writer.write("Ca marche!!rnr"); writer.newLine(); writer.close(); fw.close(); // // //Lecture du fichier // FileReader fr=new FileReader(file); // BufferedReader reader = new BufferedReader(fr); // String str=reader.readLine(); // montextview.setText(str); // Toast.makeText(this, str, Toast.LENGTH_LONG).show(); // reader.close(); // fr.close(); // } catch (IOException e) { // TODO Auto-generated catch block Toast.makeText(this, "Impossible de créer le fichier.", Toast.LENGTH_LONG).show(); } }

    On trouvera le fichier sur la sdcard:

    Conclusion

    Nous avons vu dans ce chapitre les méthodes simples pour stocker des données. Nous verrons dans les prochains chapitre des solutions avancées comme l'utilisation de la base de données SQLite. A noter que le framework Android propose la facilité des menus préférences, qui facilitent la vie du développeur pour stocker les choix de configuration de l'utilisateur de l'application mobile.








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




    © 2017 www.doritique.fr par Robert DORIGNY