Programmation Nomade (Android)
Dominique Archambault
Master “Technologie et Handicap”
Université Paris 8
Sauvegarder de données
1 Introduction 2.3. Lire dans un objet SharedPreferences
– On utilise les méthodes de type :
3 situations int getInt (String key, int defValue)
ou String getString(...).
– Paires clé/valeur de type simple, dans un fichier de préférence
Attention une valeur par défaut doit être donnée.
partagées.
long highscore = [Link](
– Sauvegarder des fichiers dans le système de fichier
getString([Link].saved_high_score),
– Utiliser la base SQLite
default_highscore);
Exemple
2 Fichier de préférence partagées SharedPreferences sharedPref=getActivity()
.getPreferences(Context.MODE_PRIVATE);
2.1. Récupérer une référence vers un objet
SharedPreferences def_highscore=getResources()
.getInteger([Link].high_score_default));
def_HS_name=getResources()
2 méthodes .getString([Link].HS_name_default));
– SharedPreferences getSharedPreferences(String
highscore=[Link](
name, int mode)
getString([Link].highscore_val),
Si plusieurs fichiers de préférences sont nécessaires. def_highscore);
– SharedPreferences getPreferences(int mode) HS_name=[Link](
getString([Link].highscore_name),
Si on a besoin d’un seul fichier de préférences. def_HS_name);
Dans les 2 cas le mode permet de contrôler les permissions,
le mode principal est MODE_PRIVATE, 2 autres possibilités :
MODE_WORLD_READABLE et MODE_WORLD_WRITEABLE. 3 Sauvegarder dans le système de fichiers
1. Choisir entre stockage “Interne” ou “Externe”
Context context = getActivity();
SharedPreferences sharedPref = 2. Obtenir les permissions pour le stockage “Externe”
[Link](
getString([Link].preference_file_key), 3. Enregistrer un fichier sur le stockage “Interne” ou “Ex-
Context.MODE_PRIVATE); terne”
4. Connaître l’espace disponible
ex. de nom de fichier
[Link].PREFERENCE_FILE_KEY 5. Effacer un fichier
SharedPreferences sharedPref =
getActivity().getPreferences(
3.1. Stockage “Interne” ou “Externe”
Context.MODE_PRIVATE);
Stockage Interne
– Toujours présente
– Fichiers réservés à notre l’application (par défaut)
2.2. Écrire dans un objet SharedPreferences – Fichiers supprimés quand un désinstalle l’application
– Créer un Editor sur cet objet
[Link] editor = [Link](); Stockage Externe
– Passer les paires clé/valeur en utilisant des méthodes de type – Pas forcément présente, peut être démontée (et physiquement
putInt(String key, int value) ou retirée), peut aussi avoir été changée.
putString(String key, String value). – Pas de contrôle de droits de lecture : toutes les applications y
[Link](getString([Link].saved_high_score), ont accès.
newHighScore); – en cas de désinstallation, ne sont supprimées que si elles sont
– Appeler la méthode commit() pour sauvegarder les modifi- dans le répertoire prévu (getExternalFilesDir()).
cations.
[Link](); 3.2. Obtenir des permission
Exemple
Stockage Externe
SharedPreferences sharedPref; Pour écrire sur le stockage externe il est nécessaire d’en obtenir
sharedPref=getActivity() la permission, via le manifest.
.getPreferences(Context.MODE_PRIVATE);
<manifest ...>
[Link] editor=[Link](); <uses-permission android:name=
"[Link].WRITE_EXTERNAL_STORAGE" />
[Link](getString([Link].highscore_val), ...
newHighScore); </manifest>
[Link](getString([Link].highscore_name),
newHighScoreName);
[Link](); Stockage Interne
Aucune permission n’est nécessaire.
Dominique Archambault – Master Handi, Université Paris 8
3.3a. Enregistrer sur le stockage Interne 2 types de fichiers
Récupérer le répertoire de l’application – Fichiers publics
– File getFilesDir() – Fichiers privés
Renvoie un objet File représentant un répertoire interne. File getExternalStoragePublicDirectory (String
– File getCacheDir() type) renvoie un répertoire pour les fichiers publics. Où type
Renvoie un objet File représentant un répertoire interne correspond au type de fichier qu’on veut stocker :
– Environment.DIRECTORY_MUSIC
pour des fichiers temporaires. – Environment.DIRECTORY_PODCASTS
– Environment.DIRECTORY_RINGTONES
– Environment.DIRECTORY_ALARMS
Créer un fichier (1) – Environment.DIRECTORY_NOTIFICATIONS
Utiliser le constructeur File(File dir, String name) – Environment.DIRECTORY_PICTURES
pour créer un objet de type fichier. – Environment.DIRECTORY_MOVIES
– Environment.DIRECTORY_DOWNLOADS
par exemple : – Environment.DIRECTORY_DCIM
File f = new File([Link](), nomfich); Exemple
Créer un fichier (2) public File getAlbumStorageDir(String albumName) {
File f=new File(Environment.
On peut aussi utiliser getExternalStoragePublicDirectory(
FileOutputStream openFileOutput(String name, Environment.DIRECTORY_PICTURES),
int mode) albumName);
if (![Link]()) {
pour récupérer un flux d’écriture sur un fichier. Log.e(LOG_TAG, "Le dossier n’a pas été créé");
Le système décide de l’emplacement du fichier (en fonction du }
return f;
mode). }
Modes :
– MODE_APPEND File getExternalFilesDir (String type) renvoie un
– MODE_PRIVATE répertoire pour les fichiers privés. Où type correspond au type
– MODE_WORLD_READABLE de fichier qu’on veut stocker, ou bien null.
– MODE_WORLD_WRITEABLE
Exemple 3.4. Connaître l’espace disponible
String nomfich = "[Link]"; Pour éviter de causer une IOException, on peut utiliser les
String machaine = "Hello world!"; méthodes suivantes de la classe File :
FileOutputStream outstream;
– long getFreeSpace()
try { renvoie l’espace disponible sur le volume correspondant au
outstream=openFileOutput(nomfich,
Context.MODE_PRIVATE);
dossier courant.
[Link]([Link]()); – long getTotalSpace()
[Link](); renvoie l’espace total sur ce volume.
}
catch (Exception e) {
...
} 3.5. Effacer un fichier
Exemple – Appeler la méthode delete() sur l’objet à détruire :
[Link]();
public File getTempFile(Context cx, String url) {
File f;
– si le fichier est sur le stockage interne :
try { deleteFile(String name)
String fnme = [Link](url) [Link](fileName);
.getLastPathSegment();
f = [Link](fname, null,
[Link]()); Lors de la désinstallation de l’application, le système efface :
} – Les fichiers installés sur le stockage interne
catch (IOException e) {
// Erreur lors de la création du fichier
– Les fichiers installés sur le stockage externe créés avec
} getExternalFilesDir()
return f;
}
4 Utiliser la base SQLite
3.3b. Enregistrer sur le stockage Externe 1. Définir un schéma et un contrat
Toujours vérifier l’état du stockage 2. Créer la base à l’aide d’un “SQL Helper”
public boolean isExternalStorageWritable() { 3. Enregistrer des données dans la base
String state=[Link]();
if ([Link](Environment.MEDIA_MOUNTED)) { 4. Lire des données de la base
return true;
} 5. Effacer des données de la base
return false;
}
4.1. Définir un schéma et un contrat
public boolean isExternalStorageReadable() {
String state=[Link]();
if ([Link](Environment.MEDIA_MOUNTED) || Schéma
[Link](Environment.MEDIA_MOUNTED_READ_ONLY)) { L’organisation de la base de données.
return true;
}
– Les tables
return false; – Les champs
} – (Éventuellement) les relations
2
Programmation nomade (Android)
Contrat
public void onUpgrade(SQLiteDatabase db,
Le schéma est constitué d’un ensemble de clauses SQL, que int oldVersion, int newVersion) {
l’on va regrouper dans une classe Contrat, qui contiendra des // Ici on efface tout et on recommence (pas top!)
constantes correspondant aux noms des tables et des champs. [Link](SQL_DELETE_ENTRIES);
onCreate(db);
Si plusieurs tables sont nécessaires, on pourra utiliser des sous }
classes pour leurs champs. public void onDowngrade(SQLiteDatabase db,
int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
public static class EntryContract }
implements BaseColumns {
public static final String TABLE_NAME = "entry";
public static final String FIELD_ENTRY_ID = Accéder à la base
"entryid";
public static final String FIELD_TITLE = "title"; Il suffit maintenant de créer une instace de notre SQLiteOpen-
public static final String FIELD_SUBTITLE = Helper.
"subtitle";
...
MyAppDbHelper mDbHelper=new MyAppDbHelper(getContext());
// Pour eviter de l’instancier par erreur
private EntryContract() {} Utiliser la base
... Selon qu’on veut lire ou écire on utilisera l’une des méthodes
getReadableDatabase() ou getWritableDatabase() :
4.2. Créer la base : un SQL Helper SQLiteDatabase db = [Link]();
SQL helper ou
Il s’agit d’une classe dans laquelle on va encapsuler les appels
à la base de données. SQLiteDatabase db = [Link]();
– Des chaînes constantes pour les requêtes SQL
– Des méthodes pour créer/retrouver la base
4.3. Enregistrer des données dans la base
On peut la faire dériver de SQLiteOpenHelper qui fournit des
méthodes pour ouvrir la base : Enregistrer
– SQLiteDatabase getWritableDatabase() – Créer un objet ContentValues
– SQLiteDatabase getReadableDatabase(). – L’insérer dans la base en le passant à la méthode
insert(String table, String nullColumnHack,
Utilisation de SQLiteOpenHelper ContentValues values)
Il faut implémenter les méthodes :
– void onCreate(SQLiteDatabase db) // Creer l’objet ContentValues
– void onUpgrade(SQLiteDatabase db, int oldVersion, ContentValues values = new ContentValues();
[Link](EntryContract.FIELD_ENTRY_ID, id);
int newVersion) [Link](EntryContract.FIELD_TITLE, title);
– void onOpen (SQLiteDatabase db) [Link](EntryContract.FIELD_CONTENT, content);
et (facultatif)
– void onDowngrade(SQLiteDatabase db, int // Inserer la nouvelle entree, en renvoyant la cle
oldVersion, int newVersion) // primaire
long newRowId;
Exemple newRowId = [Link](
EntryContract.TABLE_NAME,
public class MyAppDbHelper extends SQLiteOpenHelper { EntryContract.FIELD_NULLABLE,
// A chaque fois que le schema change, values);
// incrementer le numero de version.
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "[Link]";
4.4. Lire des données de la base
private static final String TEXT_TYPE = " TEXT";
private static final String COMMA_SEP = ","; Lire
On va utiliser la méthode query(...), qui renvoie un objet
private static final String SQL_CREATE_ENTRIES = Cursor. On va filtrer la requête, et ne récupérer que les champs
"CREATE TABLE " +EntryContract.TABLE_NAME +" (" qui nous intéressent.
+EntryContract._ID +" INTEGER PRIMARY KEY,"
+EntryContract.FIELD_ENTRY_ID +TEXT_TYPE +COMMA_SEP public Cursor query(
+EntryContract.FIELD_TITLE +TEXT_TYPE +COMMA_SEP
String table,
+... " )";
String[] columns, Liste des champs à retourner
String selection, filtre (clause SQL WHERE)
private static final String SQL_DELETE_ENTRIES =
String[] selectionArgs,
"DROP TABLE IF EXISTS " + EntryContract.TABLE_NAME;
String groupBy,
String having,
public MyAppDbHelper(Context cx) { // Constructeur
String orderBy)
super(cx, DATABASE_NAME, null, DATABASE_VERSION);
}
SQLiteDatabase db = [Link]();
public void onCreate(SQLiteDatabase db) {
[Link](SQL_CREATE_ENTRIES);
// Les champs dont on a besoin
}
String[] projection = {
public void onOpen(SQLiteDatabase db) {
EntryContract._ID,
// skip
EntryContract.FIELD_TITLE,
}
EntryContract.FIELD_UPDATED,
...
3
Dominique Archambault – Master Handi, Université Paris 8
}; 4.5. Effacer des données de la base
Pour effacer des entrées, il faut donner un critère de sélection
// Ordre de tri
String sortOrder = des entrées à effacer.
EntryContract.FIELD_UPDATED + " DESC";
String selection = EntryContract.FIELD_ENTRY_ID
+" LIKE ?";
Cursor c = [Link](
EntryContract.TABLE_NAME, String[] selelectionArgs = { [Link](rowId) };
projection,
selection, // a definir [Link](table_name, mySelection, selectionArgs);
selectionArgs, // idem
null, // pas de groupe de lignes
null, // pas de filtre sur les groupes de ligne
sortOrder
);