android:allowBackup
Vous ne le connaissiez pas ?

Vous allez pourtant le détester !
Marty, d’abord tu rentres dans la voiture !
!
En mai 2010, Google annonce une nouvelle
version de son système d’exploitation.
Android 2.2 (FroYo)
2
Parmi les nouveautés : la possibilité de
synchroniser les données d’une application
dans le cloud.
Building 44
Mountain View
HISTORIQUE
Framework Android
ARCHITECTURE
3
Backup service
Backup transport
BACKUP TRANSPORT
4
Permission : android.permission.BACKUP
Créer son Backup Transport
Un service obligatoire qui intercepte l’Intent :
android.intent.action.START_RESTORE
BACKUP TRANSPORT
5
L’utilisateur peut décider de désactiver la
synchronisation.
Utilisateur
ARCHITECTURE
6
Framework
Android
Application
Backup Agent
7
CÔTÉ CODE
Dans l’AndroidManifest.xml :
Accepter le mode backup :
android:backupAgent=“.MyBackupAgent”
android:allowBackup=“true”
Et donner un BackupAgent :
8
CÔTÉ CODE
Dans l’AndroidManifest.xml :
Deux autres attributs utiles.
Tuer l’application lorsque les données sont restaurées :
android:restoreAnyVersion=“true”
android:killAfterRestore=“true”
Restaurer n’importe quelle version :
9
CÔTÉ CODE
Backup Transport de Google
10
CÔTÉ CODE
Backup Transport de Google
Obtenir une clé sur le service
… et l’ajouter dans l’AndroidManifest.xml :
<meta-data
android:name="com.google.android.backup.api_key"
android:value=“…” />
11
BACKUP AGENT
Choix 1 : Etendre BackupAgent
onBackup(ParcelFileDescriptor oldState,
BackupDataOutput data,
ParcelFileDescriptor newState)
onRestoreFile(ParcelFileDescriptor data,
long size,
File destination,
int type,
long mode,
long mtime)
12
BACKUP AGENT
onBackup (1/2)
FileInputStream instream = new
FileInputStream(oldState.getFileDescriptor());
DataInputStream in = new DataInputStream(instream);
try {
long stateModified = in.readLong();
long fileModified = mDataFile.lastModified();
if (stateModified != fileModified) {
// Il faut faire un backup
} else {
// Rien à changer
}
} catch (IOException e) {}
13
BACKUP AGENT
onBackup (2/2)
ByteArrayOutputStream bufStream = new ByteArrayOutputStream();
DataOutputStream outWriter = new DataOutputStream(bufStream);
// Données à sauvegarder
outWriter.writeUTF(mPlayerName);
outWriter.writeInt(mPlayerScore);
// On les envoie
byte[] buffer = bufStream.toByteArray();
int len = buffer.length;
data.writeEntityHeader(APP_BACKUP_KEY, len);
data.writeEntityData(buffer, len);
14
BACKUP AGENT
onRestoreFile (1/2)
while (data.readNextHeader()) {
String key = data.getKey();
int dataSize = data.getDataSize();
// Nos données
if (APP_BACKUP_KEY.equals(key)) {
byte[] dataBuf = new byte[dataSize];
data.readEntityData(dataBuf, 0, dataSize);
ByteArrayInputStream baStream = new ByteArrayInputStream(dataBuf);
DataInputStream in = new DataInputStream(baStream);
String name = in.readUTF();
} else {
data.skipEntityData();
}
}
15
BACKUP AGENT
onRestoreFile (2/2)
// On renvoie les données que l’on a récupéré
FileOutputStream outstream = new
FileOutputStream(newState.getFileDescriptor());
DataOutputStream out = new DataOutputStream(outstream);
out.writeUTF(…);
16
BACKUP AGENT
Choix 2 : Etendre BackupAgentHelper
Sauvegarde uniquement des fichiers ou des préférences
void onCreate() {
FileBackupHelper fileHelper = new FileBackupHelper(context, file1, file2);
addHelper(FILE_KEY, fileHelper)
SharedPreferencesBackupHelper preferencesHelper = new
SharedPreferencesBackupHelper(context, file1, file2);
addHelper(SHARED_PREFS_KEY, preferencesHelper);
}
17
INCONVÉNIENTS
Fonctionnalité peu utilisée aujourd’hui
• Ecrire un BackupAgent n’est pas simple

• Ne fonctionne qu’entre les terminaux Google / Amazon…

• Aucune garantie que l’utilisateur a validé la synchronisation

• Ne gère que la restauration complète d’une application

• Des conditions qui enlèvent tout intérêt au service :
• Ne pas stocker des informations sensibles (nom d’utilisateur,
mot de passe…)
• Ne pas stocker des contenus sous licence
18
ANDROID 4.0
En novembre 2011, Google annonce une
nouvelle version de son système d’exploitation.
Android 4.0 (Ice Cream Sandwich)
Parmi les nouveautés : la possibilité de
synchroniser les données du système ou d’une
application en particulier avec adb.
Building 44
Mountain View
#holoyolo
!
19
ANDROID 4.0
Backup d’une application avec son nom de paquet :
Simple à utiliser :
adb backup com.example.app
Backup du système complet :
adb backup -all -apk -shared
20
ANDROID 4.0
Mais (relativement) sécurisé :
21
ANDROID 4.0
La restauration est aussi simple :
adb restore backup.ab
22
SOUS LE CAPOT
Que contient un fichier backup.ab ?
Il s’agit d’un fichier tar (compressé, avec éventuellement
un mot de passe) dont les entêtes ont été modifiés.
Il faut donc le convertir en fichier tar classique :
java -jar abe-all.jar pack backup.tar backup.ab
dd if=backup.ab bs=24 skip=1 | openssl zlib -d > backup.tar
… ou avec Android Backup Extractor :
23
SOUS LE CAPOT
Arborescence
apps
com.android.browser
com.android.email
com.google.android.quicksearchbox
shared
0
DCIM
Downloads
Music
24
SOUS LE CAPOT
Arborescence
apps
com.google.android.quicksearchbox
a : apk
c : cache
db : base de données
ef : “managed external”
f : fichiers
obb : extensions
r : root
sp : préférences
25
LE PROBLÈME
Android Studio
Sur Android Studio, tous les nouveaux
projets utilisent
android:allowBackup=“true”
Des milliers d’applications ont donc
cette “fonctionnalité” sans que les
développeurs ne le sachent.
26
LE PROBLÈME
Application
Si l’attribut n’est pas défini, c’est alors sa valeur par défaut qui est
utilisée.
Dans notre cas, allowBackup est à true par défaut.
… mais Lint va nous hurler dessus
27
LE PROBLÈME
Lint
Un peu plus ?
Il faudra attendre le prochain numéro

Android BackupManager

  • 1.
    android:allowBackup Vous ne leconnaissiez pas ?
 Vous allez pourtant le détester !
  • 2.
    Marty, d’abord turentres dans la voiture ! ! En mai 2010, Google annonce une nouvelle version de son système d’exploitation. Android 2.2 (FroYo) 2 Parmi les nouveautés : la possibilité de synchroniser les données d’une application dans le cloud. Building 44 Mountain View HISTORIQUE
  • 3.
  • 4.
    BACKUP TRANSPORT 4 Permission :android.permission.BACKUP Créer son Backup Transport Un service obligatoire qui intercepte l’Intent : android.intent.action.START_RESTORE
  • 5.
    BACKUP TRANSPORT 5 L’utilisateur peutdécider de désactiver la synchronisation. Utilisateur
  • 6.
  • 7.
    7 CÔTÉ CODE Dans l’AndroidManifest.xml: Accepter le mode backup : android:backupAgent=“.MyBackupAgent” android:allowBackup=“true” Et donner un BackupAgent :
  • 8.
    8 CÔTÉ CODE Dans l’AndroidManifest.xml: Deux autres attributs utiles. Tuer l’application lorsque les données sont restaurées : android:restoreAnyVersion=“true” android:killAfterRestore=“true” Restaurer n’importe quelle version :
  • 9.
  • 10.
    10 CÔTÉ CODE Backup Transportde Google Obtenir une clé sur le service … et l’ajouter dans l’AndroidManifest.xml : <meta-data android:name="com.google.android.backup.api_key" android:value=“…” />
  • 11.
    11 BACKUP AGENT Choix 1: Etendre BackupAgent onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) onRestoreFile(ParcelFileDescriptor data, long size, File destination, int type, long mode, long mtime)
  • 12.
    12 BACKUP AGENT onBackup (1/2) FileInputStreaminstream = new FileInputStream(oldState.getFileDescriptor()); DataInputStream in = new DataInputStream(instream); try { long stateModified = in.readLong(); long fileModified = mDataFile.lastModified(); if (stateModified != fileModified) { // Il faut faire un backup } else { // Rien à changer } } catch (IOException e) {}
  • 13.
    13 BACKUP AGENT onBackup (2/2) ByteArrayOutputStreambufStream = new ByteArrayOutputStream(); DataOutputStream outWriter = new DataOutputStream(bufStream); // Données à sauvegarder outWriter.writeUTF(mPlayerName); outWriter.writeInt(mPlayerScore); // On les envoie byte[] buffer = bufStream.toByteArray(); int len = buffer.length; data.writeEntityHeader(APP_BACKUP_KEY, len); data.writeEntityData(buffer, len);
  • 14.
    14 BACKUP AGENT onRestoreFile (1/2) while(data.readNextHeader()) { String key = data.getKey(); int dataSize = data.getDataSize(); // Nos données if (APP_BACKUP_KEY.equals(key)) { byte[] dataBuf = new byte[dataSize]; data.readEntityData(dataBuf, 0, dataSize); ByteArrayInputStream baStream = new ByteArrayInputStream(dataBuf); DataInputStream in = new DataInputStream(baStream); String name = in.readUTF(); } else { data.skipEntityData(); } }
  • 15.
    15 BACKUP AGENT onRestoreFile (2/2) //On renvoie les données que l’on a récupéré FileOutputStream outstream = new FileOutputStream(newState.getFileDescriptor()); DataOutputStream out = new DataOutputStream(outstream); out.writeUTF(…);
  • 16.
    16 BACKUP AGENT Choix 2: Etendre BackupAgentHelper Sauvegarde uniquement des fichiers ou des préférences void onCreate() { FileBackupHelper fileHelper = new FileBackupHelper(context, file1, file2); addHelper(FILE_KEY, fileHelper) SharedPreferencesBackupHelper preferencesHelper = new SharedPreferencesBackupHelper(context, file1, file2); addHelper(SHARED_PREFS_KEY, preferencesHelper); }
  • 17.
    17 INCONVÉNIENTS Fonctionnalité peu utiliséeaujourd’hui • Ecrire un BackupAgent n’est pas simple
 • Ne fonctionne qu’entre les terminaux Google / Amazon…
 • Aucune garantie que l’utilisateur a validé la synchronisation
 • Ne gère que la restauration complète d’une application
 • Des conditions qui enlèvent tout intérêt au service : • Ne pas stocker des informations sensibles (nom d’utilisateur, mot de passe…) • Ne pas stocker des contenus sous licence
  • 18.
    18 ANDROID 4.0 En novembre2011, Google annonce une nouvelle version de son système d’exploitation. Android 4.0 (Ice Cream Sandwich) Parmi les nouveautés : la possibilité de synchroniser les données du système ou d’une application en particulier avec adb. Building 44 Mountain View #holoyolo !
  • 19.
    19 ANDROID 4.0 Backup d’uneapplication avec son nom de paquet : Simple à utiliser : adb backup com.example.app Backup du système complet : adb backup -all -apk -shared
  • 20.
  • 21.
    21 ANDROID 4.0 La restaurationest aussi simple : adb restore backup.ab
  • 22.
    22 SOUS LE CAPOT Quecontient un fichier backup.ab ? Il s’agit d’un fichier tar (compressé, avec éventuellement un mot de passe) dont les entêtes ont été modifiés. Il faut donc le convertir en fichier tar classique : java -jar abe-all.jar pack backup.tar backup.ab dd if=backup.ab bs=24 skip=1 | openssl zlib -d > backup.tar … ou avec Android Backup Extractor :
  • 23.
  • 24.
    24 SOUS LE CAPOT Arborescence apps com.google.android.quicksearchbox a: apk c : cache db : base de données ef : “managed external” f : fichiers obb : extensions r : root sp : préférences
  • 25.
    25 LE PROBLÈME Android Studio SurAndroid Studio, tous les nouveaux projets utilisent android:allowBackup=“true” Des milliers d’applications ont donc cette “fonctionnalité” sans que les développeurs ne le sachent.
  • 26.
    26 LE PROBLÈME Application Si l’attributn’est pas défini, c’est alors sa valeur par défaut qui est utilisée. Dans notre cas, allowBackup est à true par défaut. … mais Lint va nous hurler dessus
  • 27.
  • 28.
    Un peu plus? Il faudra attendre le prochain numéro