Tutoriel pour apprendre à stocker des préférences et des fichiers sous Android

Persistance basée sur fichiers dans Android

Ce tutoriel explique comment enregistrer des paires clé-valeur en utilisant l'API préférence dans Android. Il explique aussi comment lire et écrire des fichiers dans Android. Il est basé sur Eclipse 4.3, Java 1.6 et Android 4.3.

Nous remercions Lars Vogel qui nous a aimablement autorisé à traduire et héberger cet article.

N'hésitez pas à commenter cet article ! Commentez Donner une note à l'article (5)

Article lu   fois.

Les deux auteur et traducteur

Site personnel

Traducteur :

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

1 Persistance basée sur fichiers

1.1 Méthodes de persistance locale de données

Android permet de persister les données des applications via le système de fichiers. Pour chaque application, le système Android crée un répertoire data/data/[paquetage application].

Android prend en charge les méthodes suivantes de stockage de données dans le système de fichiers local :
• fichiers : vous pouvez créer et mettre à jour des fichiers ;
• préférences : Android vous permet de sauvegarder et de récupérer des paires clé-valeur persistantes de type de données primitif ;
• base de données SQLite : des instances de bases de données SQLite sont stockées sur le système de fichiers local.
Les fichiers sont enregistrés dans le dossier files et les paramètres de l'application sont enregistrés sous forme de fichiers XML dans le dossier shared_prefs.

Si votre application crée une base de données SQLite, cette dernière est enregistrée dans le répertoire principal de l'application dans le dossier databases.

La capture d'écran ci-dessous montre un système de fichiers qui contient des fichiers, des fichiers en cache et des préférences :

Image non disponible

Seule l'application peut écrire dans son répertoire. Elle peut y créer des sous-répertoires supplémentaires pour lesquels, l'application peut accorder des autorisations de lecture ou d'écriture à d'autres applications.

1.2 Stockage interne versus externe

Android dispose de stockage interne et externe. Le stockage externe n'est pas privé et peut ne pas être toujours disponible. Si par exemple l'appareil Android est connecté à un ordinateur, l'ordinateur peut monter le système externe via le port USB, ce qui rend ce stockage externe indisponible pour les applications Android.

1.3 Application avec stockage externe

Au niveau du SDK 8 Android, il est possible de définir si l'application peut ou doit être stockée en externe. Pour cela, configurez la valeur android:installLocation à preferExternal ou auto.

Dans ce cas, certains composants de l'application peuvent être stockés sur un point de montage externe crypté. La base de données et autres données privées seront toujours stockées dans le système de stockage interne.

2 Préférences

2.1 Stockez des paires clé-valeur

Android prend en charge l'utilisation de la classe SharedPreferences pour persister des paires clé-valeur (préférences) de types primitifs de données dans le système de fichiers Android.

La définition de ces préférences peut se faire via une ressource XML.

La classe PreferenceManager fournit des méthodes pour accéder aux préférences stockées dans un fichier donné. Le code suivant montre comment accéder à des préférences dans un fichier :

 
Sélectionnez
# getting preferences from a specified file
SharedPreferences settings = getSharedPreferences("Test", Context.MODE_PRIVATE);

Les préférences sont généralement créées en tant que données privées et peuvent être consultées par tous les composants de l'application. Le partage de données avec d'autres applications via un fichier de préférences world readable ou writable est rarement utilisé, car le composant externe aurait besoin de connaître le nom exact du fichier et son emplacement.

Les préférences par défaut sont disponibles à partir de n'importe quel composant via l'appel à la méthode PreferenceManager.getDefaultSharedPreferences(this).

Les valeurs des préférences sont accessibles via la clé et l'instance de la classe SharedPreferences, comme démontré ci-dessous :

 
Sélectionnez
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity()); 
String url = settings.getString("url", "n/a");

Pour créer ou modifier des préférences, vous devez appeler la méthode edit()sur l'objet SharedPreferences. Une fois la valeur modifiée, vous devez appeler la méthode apply() pour l'appliquer de façon asynchrone au système de fichiers. L'utilisation de la méthode commit() est déconseillée, car elle écrit de façon synchrone les changements apportés au système de fichiers.

 
Sélectionnez
Editor edit = preferences.edit();
edit.putString("username", "new_value_for_user");
edit.apply();

2.2 Preference Listener

Vous pouvez écouter les changements dans les préférences via l'appel de la méthode registerOnSharedPreferenceChangeListener() sur SharedPreferences.

 
Sélectionnez
SharedPreferences prefs = 
    PreferenceManager.getDefaultSharedPreferences(this);

// Instance de l'écouteur
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    // Votre implémentation
  }
};

prefs.registerOnSharedPreferenceChangeListener(listener);

Il faut faire attention au fait que SharedPreferences garde les écouteurs dans une WeakHashMap et en conséquence, un écouteur peut être recyclé si votre code n'en garde pas une référence.

3 Tutoriel : prérequis

Le tutoriel suivant est basé sur l'exemple « de.vogella.android.socialapp » du tutoriel Android action bar.

4 Exercice : conditions préalables

L'exercice suivant nécessite la création d'un projet Android appelé com.example.android.rssfeed avec un élément nommé Settings dans la barre d'action.

5 Exercice : modifiez les préférences pour le flux RSS

5.1 Créez un fichier de préférences

Créez une ressource Android XML appelée mypreferences.xml de type PreferenceScreen :

Image non disponible

Après la création, l'éditeur Android approprié devrait ouvrir le fichier. Si ce n'est pas le cas, sélectionner le fichier, faites un clic droit dessus et sélectionnez Ouvrir avec → Android XML Resource Editor.

Appuyez sur le bouton « Ajouter » et ajoutez une préférence du type EditTextPreferences. Elle devrait s'appeler RSS feed URL et devrait utiliser la clé URL.

Image non disponible

Vous pouvez aussi saisir des valeurs pour d'autres propriétés de EditTextField, par exemple inputMethod.

5.2 Créez l'activité « settings activity »

Créez la classe SettingsActivity qui étend PreferenceActivity. Cette activité charge le fichier de préférences et permet à l'utilisateur d'en modifier les valeurs.

 
Sélectionnez
package com.example.android.rssfeed;

import android.os.Bundle;
import android.preference.PreferenceActivity;

public class SettingsActivity extends PreferenceActivity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.mypreferences);
  }
}

Enregistrez cette classe comme une activité dans votre fichier AndroidManifest.xml.

5.3 Connectez votre activité « settings activity »

Ouvrez l'activité de la préférence par la méthode onOptionsItemSelected() comme montré dans le code suivant :

 
Sélectionnez
@Override
public boolean onCreateOptionsMenu(Menu menu) {
  MenuInflater inflater = getMenuInflater();
  inflater.inflate(R.menu.mainmenu, menu);
  return true;
}

// Cette méthode est appelée quand le menu est sélectionné
@Override
public boolean onOptionsItemSelected(MenuItem item) {
  switch (item.getItemId()) {
  case R.id.preferences:
    // Lance settings activity
    Intent i = new Intent(this, SettingsActivity.class);
    startActivity(i);
    break;
    // plus de code...
  }
  return true;
}

5.4 Utilisez la valeur de la préférence pour charger le flux RSS

Pour faire usage de notre nouvelle activité de préférence (preference activity) et des valeurs de la préférence, nous ajustons la classe MyListFragment. L'extrait de code suivant montre comment accéder à la valeur de la préférence dans une méthode qui déclenche une AsyncTask pour charger le flux à partir d'Internet :

 
Sélectionnez
public void updateListContent() {
   if (parseTask == null) {
       parseTask = new ParseTask();
       parseTask.setFragment(this);
       SharedPreferences settings PreferenceManager.getDefaultSharedPreferences(getActivity());
       String url = settings.getString("url", "http://www.vogella.com/article.rss");
       parseTask.execute(url);
   }
}

5.5 Validez

Exécutez votre application. Sélectionnez dans votre barre d'action l'option « Paramètres » (Settings). Vous devriez être en mesure d'y entrer une URL. Si vous appuyez sur le bouton de retour et le bouton de rafraîchissement, veillez à ce que la valeur de la préférence URL soit utilisée dans votre activité.

5.6 Facultatif : affichez la valeur actuelle dans les paramètres

Le code suivant montre comment afficher la valeur actuelle dans l'écran des préférences :

 
Sélectionnez
package com.example.android.rssfeed;

import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;

public class SettingsActivity extends PreferenceActivity implements
    OnSharedPreferenceChangeListener {

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.mypreferences);
    
    // montre la valeur courrante sur l'écran des préférences
    for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
      initSummary(getPreferenceScreen().getPreference(i));
    }
  }

  @Override
  protected void onResume() {
    super.onResume();
    getPreferenceScreen().getSharedPreferences()
        .registerOnSharedPreferenceChangeListener(this);
  }

  @Override
  protected void onPause() {
    super.onPause();
    getPreferenceScreen().getSharedPreferences()
        .unregisterOnSharedPreferenceChangeListener(this);
   }

  @Override
  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
      String key) {
    updatePreferences(findPreference(key));
  }

  private void initSummary(Preference p) {
    if (p instanceof PreferenceCategory) {
      PreferenceCategory cat = (PreferenceCategory) p;
      for (int i = 0; i < cat.getPreferenceCount(); i++) {
        initSummary(cat.getPreference(i));
      }
    } else {
      updatePreferences(p);
    }
  }

  private void updatePreferences(Preference p) {
    if (p instanceof EditTextPreference) {
      EditTextPreference editTextPref = (EditTextPreference) p;
      p.setSummary(editTextPref.getText());
    }
  }
}
Image non disponible

6 L'API Android File

6.1 L'utilisation de l'API fichier

L'accès au système de fichiers est effectué via les classes standard java.io.

Android fournit également des classes auxiliaires utiles pour créer des fichiers et répertoires ou pour y accéder. Par exemple, la méthode getDir(String, int) créerait ou accéderait à un répertoire. La méthode openFileInput(String s) ouvrirait un fichier en écriture et openFileOutput(String s, Context.MODE_PRIVATE) créerait un fichier.

Android prend en charge les fichiers world readable ou writable, mais c'est une bonne pratique de conserver les fichiers privés de l'application et d'utiliser le fournisseur de contenu si vous voulez partager des données avec d'autres applications.

L'exemple suivant montre l'utilisation de l'API :

 
Sélectionnez
public void writeFileToInternalStorage(String fileName) {
  String eol = System.getProperty("line.separator");
  BufferedWriter writer = null;
  try {
    writer = 
      new BufferedWriter(new OutputStreamWriter(openFileOutput(fileName, 
        Context.MODE_PRIVATE)));
    writer.write("This is a test1." + eol);
    writer.write("This is a test2." + eol);
  } catch (Exception e) {
      e.printStackTrace();
  } finally {
    if (writer != null) {
    try {
      writer.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    }
  }
}
 
Sélectionnez
public void readFileFromInternalStorage(String fileName) {
  String eol = System.getProperty("line.separator");
  BufferedReader input = null;
  try {
    input = new BufferedReader(new InputStreamReader(openFileInput(fileName)));
    String line;
    StringBuffer buffer = new StringBuffer();
    while ((line = input.readLine()) != null) {
    buffer.append(line + eol);
    }
  } catch (Exception e) {
     e.printStackTrace();
  } finally {
  if (input != null) {
    try {
    input.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
    }
  }
}

6.2 Stockage externe

Android prend également en charge l'accès à un système de stockage externe, par exemple la carte SD. Tous les fichiers et répertoires du système de stockage externe sont lisibles pour toutes les applications ayant la permission appropriée.

Pour lire à partir du stockage externe, votre application doit avoir la permission android.permission.READ_EXTERNAL_STORAGE.

Pour écrire dans le système de stockage externe, votre application a besoin de la permission android.permission.WRITE_EXTERNAL_STORAGE. Vous obtenez le chemin d'accès au système de stockage externe par l'intermédiaire de la méthode Environment.getExternalStorageDirectory().

Par l'appel de méthode suivant, vous pouvez vérifier l'état du système de stockage externe. Si le dispositif est relié par USB à un ordinateur, une carte SD susceptible d'être utilisée pour le système de mémoire externe n'est pas disponible.

 
Sélectionnez
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)

Ce qui suit montre un exemple de lecture à partir du système de stockage externe :

 
Sélectionnez
private void readFileFromSDCard() {
  File directory = Environment.getExternalStorageDirectory();
  // suppose qu'un fichier article.rss soit disponible sur la carte SD 
  File file = new File(directory + "/article.rss");
  if (!file.exists()) {
    throw new RuntimeException("File not found");
  }
  Log.e("Testing", "Starting to read");
  BufferedReader reader = null;
  try {
    reader = new BufferedReader(new FileReader(file));
    StringBuilder builder = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
      builder.append(line);
    }
  } catch (Exception e) {
    e.printStackTrace();
  } finally {
    if (reader != null) {
      try {
        reader.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
}

8 Liens et littérature

9 Remerciements Developpez

Vous pouvez retrouver l'article original ici : Android Persistence with preferences and files - Tutorial. Nous remercions Lars Vogel qui nous a aimablement autorisé à traduire et héberger ses articles.

Nous remercions aussi Mishulyna pour sa traduction, ainsi que milkoseck pour sa relecture orthographique.

N'hésitez pas à commenter cet article ! Commentez Donner une note à l'article (5)

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Licence Creative Commons
Le contenu de cet article est rédigé par Lars Vogel et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2013 Developpez.com.