Accueil / Articles PiApplications. / La plate-forme Android / Partage de données.

Données : la base de données SQLite.

Android ne se contente pas de fournir un système d'exploitation pour périphériques mobiles, il dote ce système de nombreux services au nombre desquels on trouve un petit moteur de base de données qui repose sur le célèbre SGBDR SQLite. Nous allons voir comment accéder à ce moteur pour enregistrer puis lire des données. Bien entendu, cet article suppose que vous maîtrisez les base du langage SQL.

Il ne s'agit pas de faire ici un tour exhaustif de l'API SQLite mais de donner les clefs qui permettent le démarrage des développements qui souhaitent l'utiliser.

Traditionnellement, l'accès à un SGBDR se fait après s'y être connecté. Il faut ensuite émettre une commande SQL et interpréter les résultats retournés via un "curseur" (classe Cursor) qui lit pas-à-pas (fetch) les lignes du résultats.

Les instances de bases de données SQLite sont des données privées. Contrairement au "préférences partagées", il n'est pas possible de rendre une instance de base de données "publique" (WORLD_READABLE). Une base de données n'est accessible que depuis le package qui l'a créée. Si vous devez partager entre applications des données issues d'une même instance de base, vous devrez utiliser les liaisons AIDL/Binder ou créer un pourvoyeur de données (ContentProvider).

Une base de données est créée sur le chemin /data/data/{nom du package}/database/{nom de l'instance de base}. L'uid de ces instances est "SQLite". Le SDK fournit l'outil sqlite3 pour créer et travailler avec les base de données (ce programme est un "client" du SGBDR). La commande sqlite3 /data/data/{nom du package}/database/{nom de l'instance de base} vous accédez à l'instance {nom de l'instance de base} d'un package donné. sqlite3 est un outil en mode console. La commande .help donne des indications sur son fonctionnement et une documentation détaillée est disponible ici.

Fort heureusement, Android fournit la classe SQLiteOpenHelper pour simplifier le travail d'accès au modèle de données supporté par une instance de base. Cette classe est généralement dérivée pour vous permettre de créer (ou recréer) votre modèle de données. Android fournit également la classe SQLiteDatabase qui dispose des méthodes permettant l'exécution des commandes SQL. Voici un exemple d'emploi de ces deux classes. La classe DatabaseHelper dérive de la classe SQLiteOpenHelper et permet la création d'un modèle avec une seule table :

public class DatabaseHelper extends SQLiteOpenHelper
{
  private static final String DATABASE_NAME = "DBName";
  private static final int DATABASE_VERSION = 3;
  // Instruction de création de la base de données
  private static final String DATABASE_CREATE = "CREATE TABLE t_city ";
    + "(c_id INTEGER PRIMARY KEY,c_zip TEXT UNIQUE NOT NULL,c_city TEXT, c_region TEXT);";

  public DatabaseHelper(Context context)
  {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
  }

  /**
   * Méthode invoquée lors de la création de l'instance de base.
   */
  @Override
  public void onCreate(SQLiteDatabase sdb)
  {
    sdb.execSQL(DATABASE_CREATE);
  }

  /**
   * Méthode invoquée lors d'une mise à jour de l'instance de base.
   * Ici on supprime l'ancienne table t_city et on en créé une vide.
   */
  @Override
  public void onUpgrade(SQLiteDatabase sdb, int iOldVersion, int iNewVersion)
  {
    sdb.execSQL("DROP TABLE IF EXISTS t_city");
    onCreate(sdb);
  }
}

Voici une exemple d'emploi de cette classe. Notez qu'il s'agit là d'un modèle d'accès mais qu'il peut y en avoir de nombreux autres en fonction de la complexité du modèle.

public class DbEngine
{
  public final static String CITY_TABLE = "t_city";
  public final static String CITY_ID = "c_id";
  public final static String CITY_NAME = "c_city";

  private DatabaseHelper dbh;
  private SQLiteDatabase sdb;

  /**
   * Constructeur.
   * @param cnt Contexte de l'application.
   */
  public DbEngine(Context cnt)
  {
    dbh = new DatabaseHelper(context);
    sdb = dbh.getWritableDatabase();
  }

  /**
   * Ajout d'un tuple (une ville).
   */
  public long createRecords(String sID, String sCity)
  {
    ContentValues cvl = new ContentValues();
    cvl.put(CITY_ID, sID);
    cvl.put(CITY_NAME, sCity);
    return sdb.insert(CITY_TABLE, null, values);
  }

  /**
   * Retour d'un curseur qui permet de lire l'ensemble des couples
   * (identifiant, nom de ville).
   */
  public Cursor selectRecords()
  {
    String[] asCols = new String[] {CITY_ID, CITY_NAME};
    Cursor crs = sdb.query(true, CITY_TABLE, asCols, null, null, null, null, null, null);
    if (crs != null)
      crs.moveToFirst();
    return crs;
  }
}

(c) PiApplications 2016