Stockage de données sous Android



Documents pareils
Bases de données et fournisseurs de contenu

OpenPaaS Le réseau social d'entreprise

1. Base de données SQLite

1. Qu'est-ce que SQL? La maintenance des bases de données Les manipulations des bases de données... 5

COMMANDES SQL... 2 COMMANDES DE DEFINITION DE DONNEES... 2

Création et Gestion des tables

Langage SQL (1) 4 septembre IUT Orléans. Introduction Le langage SQL : données Le langage SQL : requêtes

Bases de Données relationnelles et leurs systèmes de Gestion

Le Langage De Description De Données(LDD)

Les BASES de DONNEES dans WampServer

Le langage SQL pour Oracle - partie 1 : SQL comme LDD

Le Langage SQL version Oracle

SQL Historique

Introduction à JDBC. Accès aux bases de données en Java

Langage SQL : créer et interroger une base

PHP 5. La base de données MySql. A. Belaïd 1

ECR_DESCRIPTION CHAR(80), ECR_MONTANT NUMBER(10,2) NOT NULL, ECR_SENS CHAR(1) NOT NULL) ;

Quelques patterns pour la persistance des objets avec DAO DAO. Principe de base. Utilité des DTOs. Le modèle de conception DTO (Data Transfer Object)

CREATION WEB DYNAMIQUE

Le langage SQL (première partie) c Olivier Caron

Cours: Administration d'une Base de Données

Outils, langage et approche Android Une introduction. Nicolas Stouls lyon.fr

Création d'un site dynamique en PHP avec Dreamweaver et MySQL

PHP et mysql. Code: php_mysql. Olivier Clavel - Daniel K. Schneider - Patrick Jermann - Vivian Synteta Version: 0.9 (modifié le 13/3/01 par VS)

Développement sous Android

Bases de données relationnelles

Encryptions, compression et partitionnement des données

PHP. Bertrand Estellon. 26 avril Aix-Marseille Université. Bertrand Estellon (AMU) PHP 26 avril / 214

Historisation des données

TD : Requêtes SQL (BDR.TD2-1) INSA 3IF

Partie 0 : Gestion des tablespace et des utilisateurs... 3

Projet Android (LI260) Cours 2

Olivier Mondet

Projet Viticulture - TP 3 : bases de données distantes BTS Services informatiques aux organisations

La persistance des données dans les applications : DAO, JPA, Hibernate... COMPIL 2010 francois.jannin@inp-toulouse.fr 1

TP Contraintes - Triggers

Application web de gestion de comptes en banques

TP3 : Creation de tables 1 seance

Compétences Business Objects

Guide de l'utilisateur de l'application mobile

Android 4 Les fondamentaux du développement d'applications Java

Procédures Stockées WAVESOFT ws_sp_getidtable Exemple : ws_sp_getnextsouche Exemple :... 12

Compte-rendu de projet de Système de gestion de base de données

Introduction aux Bases de Données 2004/2005

FileMaker 13. Guide de référence SQL

Cyberclasse L'interface web pas à pas

Introduction au Système de Gestion de Base de Données et aux Base de Données

SQL Server Administration d'une base de données transactionnelle avec SQL Server Management Studio (édition enrichie de vidéos)

Programme détaillé. Administrateur de Base de Données Oracle - SQLServer - MySQL. Objectifs de la formation. Les métiers

Modélisation PHP Orientée Objet pour les Projets Modèle MVC (Modèle Vue Contrôleur) Mini Framework

Stockage du fichier dans une table mysql:

Les bases de données

Java DataBaseConnectivity

Devoir Data WareHouse

14/04/2014. un ensemble d'informations sur un sujet : exhaustif, non redondant, structuré, persistant. Gaëlle PERRIN SID2 Grenoble.

Langage propre à Oracle basé sur ADA. Offre une extension procédurale à SQL

Configurer la supervision pour une base MS SQL Server Viadéis Services

Corrigé de l'atelier pratique du module 3 : Récupération d'urgence

Plan. Accès aux données dans le framework.net. ADO.NET Entity Framework LINQ ADO.NET ADO.NET. 1. ADO.NET Mode connecté Mode non connecté

I. MySQL : Serveur et SGBD

Mysql. Les requêtes préparées Prepared statements

SGBDR. Systèmes de Gestion de Bases de Données (Relationnelles)

SQL Server 2014 Administration d'une base de données transactionnelle avec SQL Server Management Studio

Création d objet imbriqué sous PowerShell.

MySQL. (Administrateur) (Dernière édition) Programme de formation. France, Belgique, Suisse, Roumanie - Canada

SQL Server et Active Directory

Plan. Bases de Données. Sources des transparents. Bases de SQL. L3 Info. Chapitre 4 : SQL LDD Le langage de manipulation de données : LMD

Symantec Backup Exec Remote Media Agent for Linux Servers

SQL. Oracle. pour. 4 e édition. Christian Soutou Avec la participation d Olivier Teste

Auto-évaluation Oracle: cours de base

Septembre 2012 Document rédigé avec epsilonwriter

MySQL / SQL EXEMPLES

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

Notion de base de données

Corrigés détaillés des exercices

BIRT (Business Intelligence and Reporting Tools)

SAP Lumira Version du document : Guide de l'utilisateur de SAP Lumira

MODE OPERATOIRE OPENOFFICE BASE

I4 : Bases de Données

Installation et prise en main

SQL Serveur Programme de formation. France Belgique Suisse - Canada. Formez vos salariés pour optimiser la productivité de votre entreprise

Chapitre 10. Les interfaces Comparable et Comparator 1

Tutoriel: Création d'un Web service en C++ avec WebContentC++Framework

Présentation du SC101

La base de données XML exist. A. Belaïd

Module Administration BD Chapitre 1 : Surcouche procédurale dans les SGBDS

Notes de cours : bases de données distribuées et repliquées

Paginer les données côté serveur, mettre en cache côté client

PRODIGE V3. Manuel utilisateurs. Consultation des métadonnées

Système de Gestion de Bases de Données Relationnelles. MySQL. Youssef CHAHIR

MODE OPERATOIRE CORIM PROGRESS / SECTION MEI. Exploitation Informatique

NFA 008. Introduction à NoSQL et MongoDB 25/05/2013

Tutorial pour une application simple

Vincent Augusto

Sybase Adaptive Server Enterprise 15

Transcription:

Stockage de données sous Android Master 2 informatique 2012-2013 Michel Chilowicz <chilowi at univ-mlv.fr> (sous licence CC By-NC-SA)

Données temporaires d'une activité Une activité peut être détruite : En cas de changement de géométrie de l'écran En cas de pénurie de mémoire centrale Avant destruction, sauvegarde manuelle des structures de données temporaires utiles --> restauration de l'état de l'activité lors de la réinstantiation onsaveinstancestate(bundle outstate) : sauvegarde des données dans le Bundle oncreate(bundle state) : restauration des données Procédé de sauvegarde temporaire sans persistance au redémarrage du système chilowi at univ-mlv.fr (CC By-NC-SA) 2

Stockage de données persistantes Stockage de fichiers Sur le système de fichier principal de la mémoire flash interne Sur une carte SD ou un périphérique de stockage USB connecté En ligne sur une machine distante Stockage de données structurées Dans une base de données SQLite3 Stockage de préférences (couples de clé-valeur) En utilisant l'interface SharedPreferences chilowi at univ-mlv.fr (CC By-NC-SA) 3

Manipulation de fichiers internes Chaque application dispose d'un répertoire réservé pour stocker ses fichiers (noms de fichier en UTF-8) récupérable avec File Context.getFilesDir() (ce répertoire est détruit lors de la désinstallation de l'application) Le système de fichiers interne peut être chiffré à l'aide du mot de passe de déverrouillage Opérations (chemins relatifs au répertoire de l'application) sur instance de Context : FileInputStream openfileinput(string name) FileOutputStream openfileoutput(string name, int mode) File getdir(string name, int mode) : ouverture (création si nécessaire) d'un répertoire File deletefile(string name) String[] filelist() : liste des fichiers privés sauvés par l'application Modes de création de fichier et répertoire (combinables par ou binaire) : MODE_PRIVATE : accessibilité réservée à l'application (ou d'autres applications avec le même user ID) MODE_APPEND : ajout en fin de fichier (par défaut écrasement du fichier) MODE_WORLD_{READABLE, WRITABLE} : accessibilité en lecture, écriture pour toutes les applications. À bannir : si des données doivent être lisibles ou écrites depuis d'autres applications, elles doivent l'être depuis une API publique chilowi at univ-mlv.fr (CC By-NC-SA) 4

Manipulation de fichiers externes Les fichiers sur support externes sont toujours publics et non chiffrés Obtention de répertoires racines externes : File Context.getExternalFilesDir(String type) : répertoire racine réservé à l'application (détruit à la désinstallation), par exemple /sdcard/android/data/fr.upemlv.helloworld/files/ ; type peut être null File Environment.getExternalStorageDirectory() : répertoire racine externe global File Environment.getExternalStoragePublicDirectory(String type) : répertoire racine externe global pour un type de fichier spécifié Les fichiers de mêmes types doivent être regroupés dans des sous-répertoires : DIRECTORY_MUSIC, DIRECTORY_PODCASTS, DIRECTORY_RINGTONES, DIRECTORY_ALARMS, DIRECTORY_NOTIFICATIONS, DIRECTORY_PICTURES, DIRECTORY_MOVIES, DIRECTORY_DOWNLOADS, DIRECTORY_DCIM chilowi at univ-mlv.fr (CC By-NC-SA) 5

Répertoires cache Obtention des chemins vers les répertoires cache spécifiques à l'application courante : File getcachedir() File getexternalcachedir() (retourne null si le stockage externe n'est pas disponible) Utile pour y stocker des données temporaires (issues de calculs, de récupération de données sur Internet...) Les données stockées peuvent être effacées par le système : En cas de désinstallation de l'application En cas de pénurie de mémoire de stockage Nécessité pour chaque application d'être raisonnable pour l'espace utilisé par le cache (partage par toutes les applications) chilowi at univ-mlv.fr (CC By-NC-SA) 6

Sauvegarde des fichiers d'application Propriétés de l'application android:allowbackup android:backupagent : classe de backup Implantation d'une classe dérivée de BackupAgent : void onbackup(parcelfiledescriptor oldstate, BackupDataOutput data, ParcelFileDescriptor newstate) : réalise une sauvegarde incrémentale depuis oldstate vers newstate en écrivant des données binaires dans data void onrestore(backupdatainput data, int appversioncode, ParcelFileDescriptor newstate) : restaure une sauvegarde incrémentale ; appversioncode est la version de l'application ayant réalisée le backup Il existe des BackupAgentHelper pour aider à la sauvegarde/restauration de données courantes (fichiers, préférences...) Attention à ne pas modifier des données concurremment à leur sauvegarde (utiliser un verrou) Lorsque des données utilisateur sont modifiées, l'application peut demander une sauvegarde incrémentale avec BackupManager.dataChanged() L'implantation du transport de backup dépend de la distribution Android (par exemple un système de backup utilisant le nuage de Google) chilowi at univ-mlv.fr (CC By-NC-SA) 7

Préférences d'application (couples clé/valeur) SharedPreferences Context.getSharedPreferences(String name, int mode) getpreferences(int mode) récupère les préférences du nom de l'activité courante Plusieurs applications peuvent accéder aux mêmes préférences si mode = MODE_WORLD_READABLE ou MODE_WORLD_WRITABLE Récupération d'une valeur avec get{boolean, Float, Int, Long, String}(String key, X defaultvalue) Modification d'entrées : en obtenant l'éditeur (edit()) sur lequel on réalise des opérations putx(string key, X value) en validant atomiquement les changements avec commit() Possibilité d'ajouter un listener appelé lors de la modification d'une entrée : registeronsharedpreferencechangelistener() chilowi at univ-mlv.fr (CC By-NC-SA) 8

Base de données SQLite3 SQLite3 : moteur de base de données sur fichiers sans support de concurrence ; supporte les requêtes SQL ; pas de typage fort Permet la persistance de données structurées en tables (définies par des colonnes) Relations possibles entre différentes tables (jointure de tables) Maintenance d'index de tri sur les enregistrements : requêtes de sélection rapides chilowi at univ-mlv.fr (CC By-NC-SA) 9

Gestion de tables SQLite Création de table avec CREATE TABLE : CREATE TABLE IF NOT EXISTS gpstrace(date INTEGER PRIMARY KEY, latitude REAL NOT NULL, longitude REAL NOT NULL, altitude REAL) ; Création d'index avec CREATE INDEX : CREATE INDEX IF NOT EXISTS latitude ON gpstrace (latitude) Renommage de table avec ALTER TABLE : ALTER TABLE gpstrace RENAME TO newgpstrace Effacement de table avec DROP TABLE : DROP TABLE gpstrace chilowi at univ-mlv.fr (CC By-NC-SA) 10

Requêtes SQL sur enregistrements Requêtes : Sélection : SELECT col1,col2,...,coln FROM table WHERE expr GROUP BY expr HAVING expr {UNION, INTERSECT, EXCEPT} SELECT... Insertion : INSERT INTO table (col1,col2,...,coln) VALUES (val1,val2,...,valn) Mise à jour : UPDATE table SET col1=val1, col2=val2,...,coln=valn WHERE expr Suppression : DELETE FROM table WHERE expr Expressions : Opérateurs classiques : * / % + - << >> & < <= > >= ==!= NOT colname LIKE x : suit le format de la chaîne x ( %: joker 0, 1 ou plusieurs caractères, _ : joker 1 caractère) ; exploite les index colname REGEXP x : valide l'expression régulière x Penser aux index lors de l'écriture d'expressions (pour ne pas parcourir tous les enregistrements) chilowi at univ-mlv.fr (CC By-NC-SA) 11

SQLiteOpenHelper Classe à dériver pour l'ouverture de base SQLite Deux méthodes à redéfinir : oncreate(sqlitedatabase) : on y exécute le script de création de base (création des tables et index) onupgrade(sqlitedatabase, int, int) : pour mettre à jour le schéma d'une base d'une version i à une version j > i onopen(sqlitedatabase) peut également être redéfini pour agir lors de l'ouverture de la base Il faut expliciter un constructeur, par exemple : public static final String DB_NAME = "gpslog"; public static final int VERSION = 1; public GPSLogBaseHelper(Context context) { super(context, DB_NAME, null, VERSION); } chilowi at univ-mlv.fr (CC By-NC-SA) 12

SQLiteDatabase SQLiteDatabase = Instance représentant une base SQLite base ouvrable depuis un SQLiteOpenHelper Exemple : SQLiteDatabase base = new GPSLogBaseHelper(this).get{Readable, Writable}Database() base devant être fermée après utilisation : base.close() Requêtage avec méthode query() : Cursor query(string table, String[] columns, String selection, String[] selectionargs, String groupby, String having, String orderby, String limit) Exemple : récupération des 100 traces GPS les plus récentes de latitude supérieure à 45 Cursor c = db.query("gpstraces", new String[]{"date", "latitude", "longitude"}, "latitude >?", new String[]{"45"}, null, null, "date DESC", 100) Cursor c = db.rawquery("select date, latitude, longitude FROM gpstraces WHERE latitude >? ORDER BY date DESC limit 100", new String[]{"45"}) Ne jamais intégrer directement les arguments dans la requête (faille d'injection de commandes SQL) chilowi at univ-mlv.fr (CC By-NC-SA) 13

Cursor On parcourt les résultats d'une requête avec une instance de Cursor (thread unsafe) Méthode utiles : int getcount() : nombre d'éléments dans le Cursor X get{short, Int, Long, Float, Double, String, Blob}(int i) : valeur de la colonne #i de l'enregistrement courant boolean movetonext() : déplacement sur le prochain enregistrement (retourne false si fin des enregistrements) chilowi at univ-mlv.fr (CC By-NC-SA) 14

Ecriture d'enregistrements Insertion avec SQLiteDatabase.insert(String table, String nullcolumnhack, ContentValues values) ContentValues est une sorte de Map où les valeurs des colonnes sont insérées avec put(string key, X value) Mise à jour : int SQLiteDatabase.update(String table, ContentValues values, String whereclause, String[] whereargs) Suppression : SQLiteDatabase.delete(String table, String whereclause, String[] whereargs) chilowi at univ-mlv.fr (CC By-NC-SA) 15

ContentProvider Fournit une interface d'accès aux fichiers ou données structurées d'une application Les données sont identifiées par une URI, e.g. content://fr.upemlv.gpslogger.provider/log/id Opérations CRUD disponibles (à implanter de façon thread-safe) : Récupération de données avec query(...) Insertion d'enregistrement avec insert(...) Mise à jour d'enregistrements avec update(...) Suppression d'enregistrements avec delete(...) Autres méthodes à redéfinir : oncreate() appelé lors de la création du ContentProvider String gettype(uri uri) retourne le type MIME d'un contenu identifié par son Uri Il est conseillé de créer une classe compagnon contenant des sous-classes pour chaque table avec le nom des colonnes en constantes ainsi que l'uri vers la table. chilowi at univ-mlv.fr (CC By-NC-SA) 16

Types MIME d'uri ContentProvider.getType(Uri uri) : retourne le type MIME d'une table ou d'un enregistrement Table : vnd.android.cursor.dir/vnd.fr.upemlv.gpslog.provider.gpstrace Enregistrement d'une table : vnd.android.cursor.item/vnd.fr.upemlv.gpslog.provider.gpstrace ContentProvider.getStreamTypes(Uri uri, String mimetypefilter) : retourne les types MIME supportés pour un fichier dont l'uri est spécifié. Un filtre indique quels sont les types qui nous intéressent. Par exemple, on peut retourner {"image/jpeg", "image/png"} pour une image chilowi at univ-mlv.fr (CC By-NC-SA) 17

ContentProvider.query() query(uri uri, String[] projection, String selection, String[] selectionargs, String sortorder) Méthode implantée en appelant SQLiteDatabase.query() Il faut auparavant reconnaître quelle table ou enregistrement est concerné : on analyse pour cela l'uri ID indiqué en fin d'uri : on ne récupère que l'enregistrement demandé dans la table Sinon on requête la table avec les paramètres de sélection et de tri L'analyse de l'uri peut être aidée avec UriMatcher (on y enregistre les schémas des URIs chilowi at univ-mlv.fr (CC By-NC-SA) 18

ContentProvider.{insert(), update(), delete()} Uri insert(uri uri, ContentValues values) : ajoute un enregistrement (values contient les couples nom de colonne, valeur) ; retourne une URI avec l'identificateur de l'enregistrement int update(uri uri, ContentValues values, String selection, String[] selectionargs) : met à jour les enregistrements suivant selection avec selectionargs ; retourne le nombre d'enregistrements mis à jour int delete(uri uri, String selection, String[] selectionargs) : efface des enregistrements ; retourne le nombre d'enregistrements effacés chilowi at univ-mlv.fr (CC By-NC-SA) 19

Fournitures de méthodes et fichiers par un ContentProvider Mécanisme de RPC intégré : Redéfinition de Bundle call(string method, String arg, Bundle extras) Accès à des fichiers : Redéfinition de ParcelFileDescriptor openfile(uri uri, String mode) Mode = "r", "rw", "rwt" (troncature de fichier existant) Création d'un ParcelFileDescriptor à partir d'un fichier : ParcelFileDescriptor.open(File file, int mode) chilowi at univ-mlv.fr (CC By-NC-SA) 20

Les permissions Modèle de sécurité Android : chaque application est exécutée dans son propre processus avec son propre user ID Par défaut le ContentProvider peut être accédé uniquement par son application hôte Création de permissions dans le manifeste <permission android:name="fr.upemlv.gpslog.gps_trace_read" android:label="@string/perm_label_gpstraceread" android:description="@string/perm_desc_gpstraceread" android:permissiongroup="android.permission-group.pesonal_info" android:protectionlevel="dangerous" /> <permission android:name="fr.upemlv.gpslog.gps_trace_write" android:label="@string/perm_label_gpstracewrite" android:description="@string/perm_desc_gpstracewrite" android:permissiongroup="android.permission-group.pesonal_info" android:protectionlevel="dangerous" /> Pour être accédé d'une autre application, le ContentProvider doit également posséder la propriété android:exported="true" 3 niveaux de protection : normal : pas d'alerte spécifique de l'utilisateur dangerous : l'utilisateur peut être informé et refuser signature : seule une application signée avec le même certificat peut obtenir la permission chilowi at univ-mlv.fr (CC By-NC-SA) 21

Protection d'un composant par permission <{application, activity, service, receiver, provider} android:permission="p"...> Une application externe doit disposer de p pour interagir avec ce composant provider propose également deux propriétés plus précises : android:readpermission android:writepermission Permissions accordables avec une granularité fine sur un provider (en fonction de l'uri) : <provider...> <path-permission android:path="string" android:pathprefix="string" android:pathpattern="string" android:permission="string" android:readpermission="string" android:writepermission="string" /> </provider> chilowi at univ-mlv.fr (CC By-NC-SA) 22

Demande de permission Un composant nécessitant une permission la demande dans le manifeste de l'application <uses-permission android:name="nom.de.la.permission" /> Les permissions demandées doivent être visualisées avant l'installation : elles sont regroupées en PermissionGroup chilowi at univ-mlv.fr (CC By-NC-SA) 23

Permissions temporaires Autorisation de permissions temporaires avec <provider android:granturipermissions="true"...> Granularité sur URI avec <grant-uri-permission android:path="string" android:pathpattern="string" android:pathprefix="string" /> Permet à une application de déléguer temporairement une permission qu'elle possède (par exemple gpslog peut déléguer une permission de lecture à une application de cartographie pour visualiser les traces) chilowi at univ-mlv.fr (CC By-NC-SA) 24

ContentResolver L'accès à un ContentProvider est réalisé depuis un ContentResolver. Le ContentResolver du Context est récupérable avec getcontentresolver() Propose les méthodes CRUD query(), insert(), update() et delete() Propose des méthodes de requêtage et d'ajout en lots : applybatch() et bulkinsert() chilowi at univ-mlv.fr (CC By-NC-SA) 25

Élément dans le presse-papier ClipData représente des données dans le presse-papier ClipDescription ClipData.getDescription() : métadonnées avec les types MIME représentés Un ClipData contient généralement un ClipData.Item (getitemat(0)) qui peut être : Du texte pur (ou du texte HTML) : ClipData.new{Plain, Html}Text(CharSequence label, CharSequence text) ; ClipData.Item.get{Plain, Html}Text() Une URI : ClipData.newUri(ContentResolver resolver, CharSequence label, Uri uri) ; existe aussi en version newrawuri sans spécifier le résolver ; ClipData.Item.getUri() Un Intent : ClipData.newIntent(CharSequence label, Intent intent) chilowi at univ-mlv.fr (CC By-NC-SA) 26

Fonctionnement du copier-coller Récupération du ClipboardManager : ClipboardManager cbm = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE) On créé un nouveau ClipData (avec texte, URI ou Intent) On le copie dans le presse-papier : cbm.setprimaryclip(myclipdata) ;... On récupère l'item principal pour le coller ailleurs (on consulte ses getters) : ClipData.Item item = myclipdata.getitemat(0) Si une URI est présente, on utilise le ContentResolver pour récupérer les données et les mettre sous une forme adaptée On peut essayer de forcer la conversion en texte de tout type de données avec ClipData.Item.coerceToText(Context) chilowi at univ-mlv.fr (CC By-NC-SA) 27