TL; DR: Comment Successy utilisez-vous les outils de ligne de commande (ou quoi que ce soit d'autre) pour tester le comportement de sauvegarde et de restauration d'Android 6.0, étant donné que je ne parviens pas à les faire restaurer?
Comme je rencontrais précédemment des problèmes avec un exemple d'application de mon livre essayant de faire fonctionner cela, j'ai commencé à partir de zéro pour les besoins de cette question.
J'ai créé un tout nouveau projet à partir de l'assistant de création de projet d'Android Studio 1.4.1, acceptant toutes les valeurs par défaut pertinentes, à l'exception du modèle "Activité vide" et de l'ajout d'un 2
à l'ID et au nom complet de l'application. J'ai ensuite ajouté un peu de code à l'activité pour me donner des données sur le stockage interne:
package com.commonsware.myapplication2;
import Android.os.Bundle;
import Android.preference.PreferenceManager;
import Android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PreferenceManager
.getDefaultSharedPreferences(this)
.edit()
.putBoolean("foo", true)
.apply();
}
}
J'ai exécuté l'application et confirmé en utilisant adb Shell run-as com.commonsware.myapplication2 ...
que le fichier SharedPreferences
existait.
J'ai ensuite exécuté adb Shell setprop log.tag.BackupXmlParserLogging VERBOSE
, conformément à la documentation. Pas de problèmes évidents.
J'ai ensuite lancé adb Shell bmgr run
, conformément à la documentation, ce qui a généré beaucoup de messages de journalisation, mais rien concernant mon application, comme prévu (et ne suggérant aucun problème particulier avec le moteur de sauvegarde).
J'ai ensuite lancé adb Shell bmgr fullbackup com.commonsware.myapplication2
, conformément à la documentation, ce qui a généré:
11-16 15:09:15.246 10372-10372/? D/AndroidRuntime: Calling main entry com.Android.commands.bmgr.Bmgr
11-16 15:09:15.248 783-793/? D/BackupManagerService: fullTransportBackup()
11-16 15:09:15.249 783-10419/? I/PFTBT: Initiating full-data transport backup of com.commonsware.myapplication2
11-16 15:09:15.250 1406-1418/? I/GmsBackupTransport: Attempt to do full backup on com.commonsware.myapplication2
11-16 15:09:15.251 783-10419/? I/AccountManagerService: getTypesVisibleToCaller: isPermitted? true
11-16 15:09:15.257 1325-1325/? V/GLSActivity: AuthDelegateWrapperCreated with selected intent: Intent { cmp=com.google.Android.gms/.auth.DefaultAuthDelegateService }
11-16 15:09:15.259 783-2127/? I/AccountManagerService: getTypesVisibleToCaller: isPermitted? true
11-16 15:09:15.262 1325-1325/? V/GLSActivity: AuthDelegateWrapperCreated with selected intent: Intent { cmp=com.google.Android.gms/.auth.DefaultAuthDelegateService }
11-16 15:09:15.264 1325-1325/? V/GLSActivity: AuthDelegateWrapperCreated with selected intent: Intent { cmp=com.google.Android.gms/.auth.DefaultAuthDelegateService }
11-16 15:09:15.284 1406-1418/? V/GmsBackupTransport: create full backup for : com.commonsware.myapplication2
11-16 15:09:15.286 1406-10421/? V/GmsBackupTransport: Start scotty uploading.
11-16 15:09:15.287 783-10422/? D/BackupManagerService: Binding to full backup agent : com.commonsware.myapplication2
11-16 15:09:15.291 783-10422/? D/BackupManagerService: awaiting agent for ApplicationInfo{75f37e2 com.commonsware.myapplication2}
11-16 15:09:15.292 783-1544/? D/BackupManagerService: agentConnected pkg=com.commonsware.myapplication2 agent=Android.os.BinderProxy@e073ad3
11-16 15:09:15.293 783-10422/? I/BackupManagerService: got agent Android.app.IBackupAgent$Stub$Proxy@f328610
11-16 15:09:15.299 783-1552/? D/VoldConnector: SND -> {8 volume mkdirs /storage/emulated/0/Android/data/com.commonsware.myapplication2/files/}
11-16 15:09:15.302 783-878/? D/VoldConnector: RCV <- {200 8 Command succeeded}
11-16 15:09:15.302 7953-7965/com.commonsware.myapplication2 V/BackupXmlParserLogging: Android:fullBackupContent - "true"
11-16 15:09:15.309 783-10422/? I/BackupRestoreController: Getting widget state for user: 0
11-16 15:09:15.312 783-10425/? I/file_backup_helper: Name: apps/com.commonsware.myapplication2/_manifest
11-16 15:09:15.313 783-10425/? D/BackupManagerService: Calling doFullBackup() on com.commonsware.myapplication2
11-16 15:09:15.320 7953-7967/com.commonsware.myapplication2 I/file_backup_helper: Name: apps/com.commonsware.myapplication2/sp/com.commonsware.myapplication2_preferences.xml
11-16 15:09:15.325 7953-7953/com.commonsware.myapplication2 I/Process: Sending signal. PID: 7953 SIG: 9
11-16 15:09:15.337 783-2131/? D/GraphicsStats: Buffer count: 4
11-16 15:09:15.337 783-2131/? I/WindowState: WIN DEATH: Window{d0be7fd u0 com.commonsware.myapplication2/com.commonsware.myapplication2.MainActivity}
11-16 15:09:15.357 783-2124/? I/ActivityManager: Process com.commonsware.myapplication2 (pid 7953) has died
11-16 15:09:15.357 783-2124/? W/ActivityManager: Force removing ActivityRecord{d9c7ab7 u0 com.commonsware.myapplication2/.MainActivity t1146}: app died, no saved state
11-16 15:09:15.374 783-2124/? I/ActivityManager: Config changes=480 {1.0 310mcc?mnc en_US ldltr sw360dp w360dp h568dp 480dpi nrml port finger -keyb/v/h -nav/h s.9}
11-16 15:09:15.414 783-876/? I/InputReader: Reconfiguring input devices. changes=0x00000004
11-16 15:09:15.414 783-876/? I/InputReader: Device reconfigured: id=4, name='touch_dev', size 1080x1920, orientation 0, mode 1, display id 0
11-16 15:09:15.441 917-1161/? E/Surface: getSlotFromBufferLocked: unknown buffer: 0x9cfd78f0
11-16 15:09:15.446 783-1649/? W/InputMethodManagerService: Got RemoteException sending setActive(false) notification to pid 7953 uid 10193
11-16 15:09:15.447 1477-1477/? I/Keyboard.Facilitator: onFinishInput()
11-16 15:09:15.513 3287-3287/? W/LocationOracle: Best location was null
11-16 15:09:15.551 3287-10448/? I/MicroRecognitionRnrImpl: Starting detection.
11-16 15:09:15.556 3287-10452/? I/MicrophoneInputStream: mic_starting com.google.Android.apps.gsa.speech.audio.aa@5e3e5da
11-16 15:09:15.564 783-801/? I/WindowManager: Screen frozen for +201ms due to Window{48728f7 u0 com.Android.systemui.ImageWallpaper}
11-16 15:09:15.566 199-10454/? I/AudioFlinger: AudioFlinger's thread 0xb2600000 ready to run
11-16 15:09:15.570 3287-10452/? I/MicrophoneInputStream: mic_started com.google.Android.apps.gsa.speech.audio.aa@5e3e5da
11-16 15:09:15.579 199-10454/? D/audio_hw_primary: select_devices: out_snd_device(0: none) in_snd_device(61: voice-rec-mic)
11-16 15:09:15.580 199-10454/? D/msm8974_platform: platform_send_audio_calibration: sending audio calibration for snd_device(61) acdb_id(62)
11-16 15:09:15.580 199-10454/? D/: Failed to fetch the lookup information of the device 0000003E
11-16 15:09:15.580 199-10454/? E/ACDB-LOADER: Error: ACDB AudProc vol returned = -19
11-16 15:09:15.580 199-10454/? D/audio_hw_primary: enable_snd_device: snd_device(61: voice-rec-mic)
11-16 15:09:15.583 199-10454/? D/audio_hw_primary: enable_audio_route: apply and update mixer path: audio-record
11-16 15:09:15.641 1406-1593/? D/GCoreFlp: FLP HAL exists but batch size is <= 0. Disabling FLP HAL.
11-16 15:09:15.649 783-2126/? D/WifiService: acquireWifiLockLocked: WifiLock{NlpWifiLock type=2 binder=Android.os.BinderProxy@6b83dff}
11-16 15:09:15.651 783-897/? D/wifi: Initialized common fields 10000, 16, 100, 10
11-16 15:09:15.651 783-897/? D/wifi: bucket[0] = 2:3:10000:2
11-16 15:09:15.670 3287-3287/? W/MicroDetectionWorkerImp: Tag [MicroDetectionWorkerImpl] is too long; truncated to [MicroDetectionWorkerImp]
11-16 15:09:15.670 3287-3287/? I/MicroDetectionWorkerImp: onReady
11-16 15:09:15.971 3456-3476/? W/OpenGLRenderer: Incorrectly called buildLayer on View: ShortcutAndWidgetContainer, destroying layer...
11-16 15:09:16.065 1406-10421/? V/GmsBackupTransport: Scotty response: res=200 raw=2560 up=2560
11-16 15:09:16.069 783-10419/? I/PFTBT: Transport suggested backoff=0
11-16 15:09:16.083 783-10419/? I/PFTBT: Full backup completed.
11-16 15:09:16.084 783-793/? D/BackupManagerService: Done with full transport backup.
Rien ne semble indiquer une erreur ou une autre défaillance de la sauvegarde.
J'ai ensuite supprimé le fichier SharedPreferences
manuellement, via:
adb Shell run-as com.commonsware.myapplication2 rm /data/data/com.commonsware.myapplication2/shared_prefs/com.commonsware.myapplication2_preferences.xml
et a confirmé que le fichier SharedPreferences
n'existe plus.
J'ai ensuite exécuté adb Shell bmgr restore com.commonsware.myapplication2
, conformément à la documentation. Cela a généré un autre ensemble de messages de journalisation, avec quelques erreurs apparentes:
11-16 15:13:01.692 10593-10593/? D/AndroidRuntime: Calling main entry com.Android.commands.bmgr.Bmgr
11-16 15:13:01.694 783-941/? V/BackupManagerService: beginRestoreSession: pkg=com.commonsware.myapplication2 transport=null
11-16 15:13:01.696 783-794/? V/RestoreSession: restorePackage pkg=com.commonsware.myapplication2 obs=Android.app.backup.IRestoreObserver$Stub$Proxy@b011dce
11-16 15:13:01.696 783-794/? V/RestoreSession: restorePackage pkg=com.commonsware.myapplication2 token=3dd6ad03f250d4cb
11-16 15:13:01.696 783-900/? D/BackupManagerService: MSG_RUN_RESTORE observer=Android.app.backup.IRestoreObserver$Stub$Proxy@b011dce
11-16 15:13:01.700 783-900/? I/AccountManagerService: getTypesVisibleToCaller: isPermitted? true
11-16 15:13:01.703 1325-1325/? V/GLSActivity: AuthDelegateWrapperCreated with selected intent: Intent { cmp=com.google.Android.gms/.auth.DefaultAuthDelegateService }
11-16 15:13:01.705 783-1552/? I/AccountManagerService: getTypesVisibleToCaller: isPermitted? true
11-16 15:13:01.707 1325-1325/? V/GLSActivity: AuthDelegateWrapperCreated with selected intent: Intent { cmp=com.google.Android.gms/.auth.DefaultAuthDelegateService }
11-16 15:13:01.708 1325-1325/? V/GLSActivity: AuthDelegateWrapperCreated with selected intent: Intent { cmp=com.google.Android.gms/.auth.DefaultAuthDelegateService }
11-16 15:13:01.991 1406-1682/? I/GmsBackupTransport: Http Response Code : 200
11-16 15:13:01.995 1406-1887/? I/GmsBackupTransport: Current restore package : PackageInfo{f7f23bd @pm@}
11-16 15:13:01.996 783-900/? D/BackupManagerService: initiateOneRestore packageName=@pm@
11-16 15:13:02.008 1406-1417/? I/GmsBackupTransport: Current restore package : PackageInfo{733fdb2 com.commonsware.myapplication2}
11-16 15:13:02.009 783-900/? I/BackupManagerService: Next restore package: RestoreDescription{com.commonsware.myapplication2 : STREAM}
11-16 15:13:02.023 783-10612/? I/AccountManagerService: getTypesVisibleToCaller: isPermitted? true
11-16 15:13:02.213 1406-1418/? I/GmsBackupTransport: Drive download http response status : 401
11-16 15:13:02.282 783-10612/? I/AccountManagerService: getTypesVisibleToCaller: isPermitted? true
11-16 15:13:02.311 783-10612/? I/AccountManagerService: getTypesVisibleToCaller: isPermitted? true
11-16 15:13:02.319 1325-1325/? V/GLSActivity: AuthDelegateWrapperCreated with selected intent: Intent { cmp=com.google.Android.gms/.auth.DefaultAuthDelegateService }
11-16 15:13:02.321 783-1552/? I/AccountManagerService: getTypesVisibleToCaller: isPermitted? true
11-16 15:13:02.516 783-884/? D/WifiStateMachine: starting scan for "cw"WPA_PSK with 2427,5180
11-16 15:13:02.517 783-886/? D/ConnectivityService: updateNetworkScore for NetworkAgentInfo [WIFI () - 100] to 60
11-16 15:13:02.517 783-886/? D/ConnectivityService: rematching NetworkAgentInfo [WIFI () - 100]
11-16 15:13:02.695 1406-1418/? I/GmsBackupTransport: Reading next chunk on full restore - IOException
11-16 15:13:09.611 783-10612/? I/AccountManagerService: getTypesVisibleToCaller: isPermitted? true
11-16 15:13:09.808 1406-1418/? I/GmsBackupTransport: Drive download http response status : 401
11-16 15:13:09.834 783-10612/? I/AccountManagerService: getTypesVisibleToCaller: isPermitted? true
11-16 15:13:09.884 783-10612/? I/AccountManagerService: getTypesVisibleToCaller: isPermitted? true
11-16 15:13:09.892 1325-1325/? V/GLSActivity: AuthDelegateWrapperCreated with selected intent: Intent { cmp=com.google.Android.gms/.auth.DefaultAuthDelegateService }
11-16 15:13:09.894 783-2126/? I/AccountManagerService: getTypesVisibleToCaller: isPermitted? true
11-16 15:13:09.897 1325-1325/? V/GLSActivity: AuthDelegateWrapperCreated with selected intent: Intent { cmp=com.google.Android.gms/.auth.DefaultAuthDelegateService }
11-16 15:13:09.898 1325-1325/? V/GLSActivity: AuthDelegateWrapperCreated with selected intent: Intent { cmp=com.google.Android.gms/.auth.DefaultAuthDelegateService }
11-16 15:13:10.110 1406-1418/? I/GmsBackupTransport: Reading next chunk on full restore - IOException
11-16 15:13:10.110 1406-1418/? E/GmsBackupTransport: HTTP reading error: Java.io.IOException: Unauthorized full data restore request
11-16 15:13:10.110 1406-1418/? E/GmsBackupTransport: Fail to read full backup data chunk : Java.io.IOException: Unauthorized full data restore request
11-16 15:13:10.112 783-10612/? E/StreamFeederThread: Error -1002 streaming restore for com.commonsware.myapplication2
11-16 15:13:10.119 783-10612/? I/ActivityManager: Force stopping com.commonsware.myapplication2 appid=10193 user=0: clear data
11-16 15:13:10.140 783-796/? I/ActivityManager: Start proc 10623:com.Android.documentsui/u0a36 for broadcast com.Android.documentsui/.PackageReceiver
11-16 15:13:10.174 10623-10623/? W/System: ClassLoader referenced unknown path: /system/app/DocumentsUI/lib/arm
11-16 15:13:10.198 1440-10637/? D/PackageBroadcastService: Received broadcast action=Android.intent.action.PACKAGE_DATA_CLEARED and uri=com.commonsware.myapplication2
11-16 15:13:10.198 1440-10637/? D/AccountUtils: Clearing selected account for com.commonsware.myapplication2
11-16 15:13:10.203 1440-10637/? I/LocationSettingsChecker: Removing dialog suppression flag for package com.commonsware.myapplication2
11-16 15:13:10.208 1440-2449/? I/Icing: doRemovePackageData com.commonsware.myapplication2
11-16 15:13:10.232 783-900/? V/BackupManagerService: No more packages; finishing restore
11-16 15:13:10.234 783-900/? I/BackupRestoreController: restoreFinished for 0
11-16 15:13:10.234 783-900/? I/BackupManagerService: Restore complete.
11-16 15:13:10.234 783-793/? D/RestoreSession: endRestoreSession
11-16 15:13:10.234 10593-10593/? D/AndroidRuntime: Shutting down VM
11-16 15:13:10.235 783-900/? V/BackupManagerService: Clearing restore session and halting timeout
11-16 15:13:10.279 783-1544/? I/ActivityManager: Start proc 10661:com.Android.externalstorage/u0a6 for content provider com.Android.externalstorage/.ExternalStorageProvider
11-16 15:13:10.301 10661-10661/? W/System: ClassLoader referenced unknown path: /system/priv-app/ExternalStorageProvider/lib/arm
11-16 15:13:10.307 10661-10661/? D/ExternalStorage: After updating volumes, found 1 active roots
11-16 15:13:10.336 783-1544/? I/ActivityManager: Start proc 10675:com.Android.Shell/2000 for content provider com.Android.Shell/.BugreportStorageProvider
11-16 15:13:10.360 10675-10675/? W/System: ClassLoader referenced unknown path: /system/priv-app/Shell/lib/arm
11-16 15:13:10.371 10623-10636/? D/Documents: Update found 7 roots in 156ms
11-16 15:13:10.377 10623-10674/? D/Documents: Update found 7 roots in 65ms
11-16 15:13:14.635 783-886/? D/ConnectivityService: updateNetworkScore for NetworkAgentInfo [WIFI () - 100] to 56
11-16 15:13:14.635 783-886/? D/ConnectivityService: rematching NetworkAgentInfo [WIFI () - 100]
11-16 15:13:17.617 783-2632/? D/NetlinkSocketObserver: NeighborEvent{elapsedMs=2866928, 192.168.3.1, [000DB9340C50], RTM_NEWNEIGH, NUD_STALE}
11-16 15:13:22.520 783-884/? D/WifiStateMachine: starting scan for "cw"WPA_PSK with 2427,5180
11-16 15:13:23.729 783-886/? D/ConnectivityService: updateNetworkScore for NetworkAgentInfo [WIFI () - 100] to 60
11-16 15:13:23.731 783-886/? D/ConnectivityService: rematching NetworkAgentInfo [WIFI () - 100]
Le sous-ensemble inquiétant de cela est:
11-16 15:13:10.110 1406-1418/? I/GmsBackupTransport: Reading next chunk on full restore - IOException
11-16 15:13:10.110 1406-1418/? E/GmsBackupTransport: HTTP reading error: Java.io.IOException: Unauthorized full data restore request
11-16 15:13:10.110 1406-1418/? E/GmsBackupTransport: Fail to read full backup data chunk : Java.io.IOException: Unauthorized full data restore request
11-16 15:13:10.112 783-10612/? E/StreamFeederThread: Error -1002 streaming restore for com.commonsware.myapplication2
Et, bien sûr, le fichier n'est pas restauré. Je n'ai aucune idée de ce qu'une "demande de restauration intégrale de données non autorisée" signifie.
J'ai donc désinstallé l'application (via gradle uninstallDebug
) et je l'ai réinstallée sans l'exécuter (via gradle installDebug
). Selon la documentation, "Vous pouvez tester la restauration automatique de votre application en désinstallant et en réinstallant votre application. Les données de l'application sont automatiquement restaurées à partir du cloud une fois l'installation de l'application terminée". Cependant, quelques minutes après sa réinstallation, le fichier SharedPreferences
n'existe toujours pas.
J'ai ensuite exécuté à nouveau adb Shell bmgr restore com.commonsware.myapplication2
et obtenu un ensemble similaire d'instructions de journalisation, avec le même message "Demande de restauration de données complètes non autorisées".
Y a-t-il des étapes dans ce processus qui me manquent ou qui sont autrement non documentées?
EDIT: J'avais testé sur du matériel réel (un Nexus 6). Selon les commentaires de MH, j'ai testé cette procédure sur un émulateur Android 6.0 (sans Play Services), et cela fonctionne. Cela suggère que la documentation n'est pas complètement mal, même si cela pose toujours la question de savoir pourquoi cela ne fonctionne pas avec le matériel.
Après avoir discuté et testé différents scénarios (voir commentaires sous la question), j'ai décidé de combiner et d'écrire ces résultats dans une réponse. En réalité, cela ne résout pas le problème présenté, mais cela répondra à la question "Comment utiliser avec succès les outils de ligne de commande (ou autre) pour tester le comportement de sauvegarde et de restauration Android 6.0?" Cela se fera sous la forme d’un guide détaillé décrivant ce qui a fonctionné pour moi et comment j’ai surmonté les divers problèmes que j’ai rencontrés en cours de route.
Voici. Si vous n'avez pas encore suivi la formation sur " Configuration de la sauvegarde automatique pour les applications ", je vous suggère de le faire en premier. Il documente la fonctionnalité de sauvegarde automatique et fait déjà un travail très décent de documentation des différentes étapes.
Commençons par le début: nous avons besoin d'une application pour tester! Tout comme CommonsWare, j'ai simplement utilisé Android Studio pour créer un nouveau projet avec une activité Vide. Assurez-vous de définir l'API 23 en tant que SDK cible. Ouvrez la MainActivity
générée automatiquement et ajoutez du code dans onCreate()
pour conserver une valeur dans les préférences partagées (ou copiez simplement l'extrait de code de la question):
PreferenceManager
.getDefaultSharedPreferences(this)
.edit()
.putBoolean("foo", true)
.apply();
Construisez, déployez et exécutez l'application. Cela devrait entraîner la persistance de foo
et entraînera la création d'un fichier xml sur le disque. Confirmez ceci avec:
adb Shell run-as <package_name> ls -al shared_prefs
Le paquet de mon application de test est com.example.mh.backuptest
(c'est ce que je vais utiliser dans les exemples de commandes à partir de maintenant), donc ma commande est la suivante:
adb Shell run-as com.example.mh.backuptest ls -al shared_prefs
Vous devriez voir une seule ligne de sortie listant tous les fichiers du dossier shared_prefs
, qui ne devrait en être qu'un:
com.example.mh.backuptest_preferences.xml
Cela signifie que le fichier de préférences a été créé avec succès et que foo
y a été écrit. Si vous le souhaitez, vous pouvez vérifier le contenu du fichier pour le confirmer.
Revenons maintenant au test de la sauvegarde automatique. Tout d'abord, assurez-vous que vous avez activé la sauvegarde automatique des applications. Sur votre appareil Android 6.0, accédez à:
Settings > Backup & reset > Back up my data > On
Après cela, activez la journalisation détaillée pour le transport et l’analyseur xml de sauvegarde afin que nous puissions voir ce qui se passe:
adb Shell setprop log.tag.GmsBackupTransport VERBOSE
adb Shell setprop log.tag.BackupXmlParserLogging VERBOSE
Ensuite, initialisez le gestionnaire de sauvegarde:
adb Shell bmgr run
Cela devrait générer un peu de sortie dans logcat. Vous devriez voir au moins quelque chose de similaire à ceci:
D/AndroidRuntime: Calling main entry com.Android.commands.bmgr.Bmgr
V/BackupManagerService: Scheduling immediate backup pass
V/BackupManagerService: Running a backup pass
V/BackupManagerService: clearing pending backups
V/PerformBackupTask: Beginning backup of 1 targets
D/PerformBackupTask: invokeAgentForBackup on @pm@
I/BackupRestoreController: Getting widget state for user: 0
D/PerformBackupTask: starting key/value backup of BackupRequest{pkg=com.google.Android.googlequicksearchbox}
D/BackupManagerService: awaiting agent for ApplicationInfo{9f9289c com.google.Android.googlequicksearchbox}
D/BackupManagerService: agentConnected pkg=com.google.Android.googlequicksearchbox agent=Android.os.BinderProxy@dcdbafd
I/BackupManagerService: got agent Android.app.IBackupAgent$Stub$Proxy@c3fe3f2
D/PerformBackupTask: invokeAgentForBackup on com.google.Android.googlequicksearchbox
D/BackupHelperDispatcher: handling existing helper 'L' com.Android.launcher3.LauncherBackupHelper@7e2dcc3
V/LauncherBackupHelper: lastBackupTime = 1448612678367
W/LauncherBackupHelper: empty intent on application favorite: 223
I/BackupRestoreController: Getting widget state for user: 0
V/GmsBackupTransport: starting new backup session
V/GmsBackupTransport: starting performBackup for com.google.Android.googlequicksearchbox
V/GmsBackupTransport: performBackup done for com.google.Android.googlequicksearchbox
V/GmsBackupTransport: sending request: 101667 bytes
I/GmsBackupTransport: Http Response Code : 200
V/GmsBackupTransport: backup finished for com.google.Android.googlequicksearchbox
I/BackupManagerService: Backup pass finished.
Ne vous inquiétez pas si votre sortie en contient beaucoup plus. J'ai volontairement supprimé les lignes non pertinentes pour la sauvegarde. Je n'ai que collé dans la sortie lorsque lorsqu'une application est en cours de sauvegarde; vous verrez probablement beaucoup plus d'entrées la première fois que vous exécuterez cette commande.
Si vous voyez plutôt quelque chose comme:
GmsBackupTransport: Scotty transfer exception. null
PFTBT : Error -1002 backing up com.example.mh.backuptest
Ou:
GmsBackupTransport: Rejecting full data backup. user has not seen up to date legal text
Assurez-vous que vous avez activé les sauvegardes automatiques des applications (voir ci-dessus). Si vous en avez et que vous voyez toujours ces messages - ce qui m'est arrivé aussi - essayez de basculer le réglage plusieurs fois et de redémarrer l'appareil. Toujours pas de chance? J'y suis allé ... Supprimez le compte Google de l'appareil, redémarrez, rajoutez-le et réactivez-le. D'autres ont ont signalé qu'une réinitialisation d'usine fonctionne également, mais cela me semble un peu exagéré. :)
Si vous en êtes à ce stade, il est temps de vous assurer que notre application de test est sauvegardée! Pour forcer une sauvegarde, exécutez:
adb Shell bmgr fullbackup com.example.mh.backuptest
Cela tue votre application si elle est toujours en cours d'exécution - ne vous inquiétez pas, c'est normal. Vous devriez voir pas mal de sorties du transport de sauvegarde:
D/AndroidRuntime: Calling main entry com.Android.commands.bmgr.Bmgr
D/BackupManagerService: fullTransportBackup()
I/PFTBT: Initiating full-data transport backup of com.example.mh.backuptest
V/GmsBackupTransport: create full backup for : com.example.mh.backuptest
V/GmsBackupTransport: Start scotty uploading.
D/BackupManagerService: Binding to full backup agent : com.example.mh.backuptest
I/ActivityManager: Start proc 22032:com.example.mh.backuptest/u0a491 for backup Android/FullBackupAgent
D/BackupManagerService: awaiting agent for ApplicationInfo{dd359cd com.example.mh.backuptest}
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] wait for avaible data.
BackupManagerService: agentConnected pkg=com.example.mh.backuptest agent=Android.os.BinderProxy@9e7e282
I/BackupManagerService: got agent Android.app.IBackupAgent$Stub$Proxy@14b3d93
V/BackupXmlParserLogging: Android:fullBackupContent - "true"
I/BackupRestoreController: Getting widget state for user: 0
I/file_backup_helper: Name: apps/com.example.mh.backuptest/_manifest
V/GmsBackupTransport: [Push] Push 512 bytes into pipe.
V/GmsBackupTransport: [Push] signal data available.
V/GmsBackupTransport: [Push] Wait for data been processed.
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ] signal data processed.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] wait for avaible data.
V/GmsBackupTransport: [Push] Push 2048 bytes into pipe.
V/GmsBackupTransport: [Push] signal data available.
V/GmsBackupTransport: [Push] Wait for data been processed.
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ] signal data processed.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] wait for avaible data.
D/BackupManagerService: Calling doFullBackup() on com.example.mh.backuptest
I/file_backup_helper: Name: apps/com.example.mh.backuptest/sp/com.example.mh.backuptest_preferences.xml
V/GmsBackupTransport: [Push] Push 512 bytes into pipe.
V/GmsBackupTransport: [Push] signal data available.
V/GmsBackupTransport: [Push] Wait for data been processed.
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ] signal data processed.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] wait for avaible data.
V/GmsBackupTransport: [Push] Push 512 bytes into pipe.
V/GmsBackupTransport: [Push] signal data available.
V/GmsBackupTransport: [Push] Wait for data been processed.
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] Read 256 bytes data.
V/GmsBackupTransport: [READ] signal data processed.
V/GmsBackupTransport: [READ]
V/GmsBackupTransport: [READ] wait for avaible data.
V/GmsBackupTransport: [FINISH] signal no more data.
I/Process: Sending signal. PID: 22032 SIG: 9
I/ActivityManager: Process com.example.mh.backuptest (pid 22032) has died
V/GmsBackupTransport: Scotty response: res=200 raw=3584 up=1047
I/PFTBT: Transport suggested backoff=0
I/PFTBT: Full backup completed.
D/BackupManagerService: Done with full transport backup.
Avec notre application de test sauvegardée, voyons si elle restaure également les données. Commençons par supprimer le fichier de préférences créé par notre application de test et faisant partie de la sauvegarde automatique par défaut:
adb Shell run-as com.example.mh.backuptest rm shared_prefs/com.example.mh.backuptest_preferences.xml
Confirmez que le fichier n'est plus là:
adb Shell run-as com.example.mh.backuptest ls -al shared_prefs
Si la commande s'exécute sans aucune sortie, cela signifie qu'il n'y avait aucun fichier dans le dossier shared_prefs
et que vous avez correctement supprimé les préférences.
Maintenant, déclenchez une restauration pour notre application de test:
adb Shell bmgr restore com.example.mh.backuptest
Encore une fois, le transport de sauvegarde générera un certain nombre de résultats:
V/BackupManagerService: beginRestoreSession: pkg=com.example.mh.backuptest transport=null
V/RestoreSession: restorePackage pkg=com.example.mh.backuptest obs=Android.app.backup.IRestoreObserver$Stub$Proxy@23829fa
V/RestoreSession: restorePackage pkg=com.example.mh.backuptest token=31eda3bdfd5fddb7
D/BackupManagerService: MSG_RUN_RESTORE observer=Android.app.backup.IRestoreObserver$Stub$Proxy@23829fa
V/GmsBackupTransport: New restore session, 2 apps
V/GmsBackupTransport: sending request: 471 bytes
I/GmsBackupTransport: Http Response Code : 200
V/GmsBackupTransport: @pm@: 109 keys
I/GmsBackupTransport: Current restore package : PackageInfo{195d280 @pm@}
V/GmsBackupTransport: A key/value pairs restore
D/BackupManagerService: initiateOneRestore packageName=@pm@
I/GmsBackupTransport: Current restore package : PackageInfo{1edd0b9 com.example.mh.backuptest}
V/GmsBackupTransport: A full restore : https://www.googleapis.com/drive/v2/files/XXXXXXXXXXXXXXXXXXXXXXXXXXXX?alt=media&sources=Android_BACKUP
I/BackupManagerService: Next restore package: RestoreDescription{com.example.mh.backuptest : STREAM}
V/GmsBackupTransport: Read first chunk for com.example.mh.backuptest
V/GmsBackupTransport: Create http connection for com.example.mh.backuptest
I/GmsBackupTransport: Drive download http response status : 200
V/GmsBackupTransport: ContentLength is 3584
V/GmsBackupTransport: Downloaded: 808 / 3584 bytes
V/GmsBackupTransport: Read 808 Bytes
V/GmsBackupTransport: Read next chunk for com.example.mh.backuptest
V/GmsBackupTransport: Downloaded: 2197 / 3584 bytes
V/GmsBackupTransport: Read 1389 Bytes
I/RestoreEngine: Sig + version match; taking data
V/GmsBackupTransport: Read next chunk for com.example.mh.backuptest
V/GmsBackupTransport: Downloaded: 3584 / 3584 bytes
V/GmsBackupTransport: Read 1387 Bytes
V/GmsBackupTransport: Read next chunk for com.example.mh.backuptest
V/GmsBackupTransport: Read -1 Bytes
D/RestoreEngine: Need to launch agent for com.example.mh.backuptest
D/RestoreEngine: Clearing app data preparatory to full restore
I/ActivityManager: Force stopping com.example.mh.backuptest appid=10491 user=0: clear data
V/GmsBackupTransport: Reach end of http content -- NO MORE DATA
D/PackageBroadcastService: Received broadcast action=Android.intent.action.PACKAGE_DATA_CLEARED and uri=com.example.mh.backuptest
D/AccountUtils: Clearing selected account for com.example.mh.backuptest
I/LocationSettingsChecker: Removing dialog suppression flag for package com.example.mh.backuptest
I/Icing: doRemovePackageData com.example.mh.backuptest
I/ActivityManager: Start proc 22708:com.example.mh.backuptest/u0a491 for backup Android/FullBackupAgent
D/BackupManagerService: awaiting agent for ApplicationInfo{dd359cd com.example.mh.backuptest}
D/BackupManagerService: agentConnected pkg=com.example.mh.backuptest agent=Android.os.BinderProxy@7875d75
I/BackupManagerService: got agent Android.app.IBackupAgent$Stub$Proxy@9aa10a
D/VoldConnector: SND -> {14 volume mkdirs /storage/emulated/0/Android/data/com.example.mh.backuptest/files/}
D/VoldConnector: RCV <- {200 14 Command succeeded}
V/BackupXmlParserLogging: Android:fullBackupContent - "true"
V/BackupManagerService: No more packages; finishing restore
V/GmsBackupTransport: restore finished
D/RestoreSession: endRestoreSession
I/BackupRestoreController: restoreFinished for 0
I/BackupManagerService: Restore complete.
Si tout se passe comme ci-dessus, vérifions si notre fichier de préférences est de retour tel qu'il devrait être:
adb Shell run-as com.example.mh.backuptest ls -al shared_prefs
Le résultat devrait correspondre à ce que vous avez vu la première fois que vous avez exécuté la commande (au début de cette histoire plutôt longue). Si c'est le cas, c'est le moment des félicitations! Vous avez réussi à sauvegarder et à restaurer votre application à l'aide de la fonction de sauvegarde automatique pour applications de Google!
Heureux? Alors faisons encore un test! Désinstallez l'application:
adb uninstall com.example.mh.backuptest
Même si nous voyons le «succès», confirmez qu'il est parti:
adb Shell run-as com.example.mh.backuptest
Production attendue:
run-as: Package 'com.example.mh.backuptest' is unknown
Maintenant, réinstallez l’application (mais ne démarrez pas it):
adb install backuptest.apk
Regardez logcat:
V/BackupManagerService: restoreAtInstall pkg=com.example.mh.backuptest token=3 restoreSet=31eda3bdfd5fddb7
D/BackupManagerService: MSG_RUN_RESTORE observer=null
V/GmsBackupTransport: New restore session, 2 apps
V/GmsBackupTransport: sending request: 471 bytes
I/GmsBackupTransport: Http Response Code : 200
V/GmsBackupTransport: @pm@: 109 keys
I/GmsBackupTransport: Current restore package : PackageInfo{2981234 @pm@}
V/GmsBackupTransport: A key/value pairs restore
D/BackupManagerService: initiateOneRestore packageName=@pm@
I/GmsBackupTransport: Current restore package : PackageInfo{883c85d com.example.mh.backuptest}
V/GmsBackupTransport: A full restore : https://www.googleapis.com/drive/v2/files/XXXXXXXXXXXXXXXXXXXXXXXXXXXX?alt=media&sources=Android_BACKUP
I/BackupManagerService: Next restore package: RestoreDescription{com.example.mh.backuptest : STREAM}
V/GmsBackupTransport: Read first chunk for com.example.mh.backuptest
V/GmsBackupTransport: Create http connection for com.example.mh.backuptest
I/GmsBackupTransport: Drive download http response status : 200
V/GmsBackupTransport: ContentLength is 3584
V/GmsBackupTransport: Downloaded: 808 / 3584 bytes
V/GmsBackupTransport: Read 808 Bytes
V/GmsBackupTransport: Read next chunk for com.example.mh.backuptest
V/GmsBackupTransport: Downloaded: 2197 / 3584 bytes
V/GmsBackupTransport: Read 1389 Bytes
I/RestoreEngine: Sig + version match; taking data
V/GmsBackupTransport: Read next chunk for com.example.mh.backuptest
V/GmsBackupTransport: Downloaded: 3584 / 3584 bytes
V/GmsBackupTransport: Read 1387 Bytes
V/GmsBackupTransport: Read next chunk for com.example.mh.backuptest
V/GmsBackupTransport: Read -1 Bytes
D/RestoreEngine: Need to launch agent for com.example.mh.backuptest
D/RestoreEngine: Clearing app data preparatory to full restore
I/ActivityManager: Force stopping com.example.mh.backuptest appid=10493 user=0: clear data
V/GmsBackupTransport: Reach end of http content -- NO MORE DATA
D/PackageBroadcastService: Received broadcast action=Android.intent.action.PACKAGE_DATA_CLEARED and uri=com.example.mh.backuptest
D/AccountUtils: Clearing selected account for com.example.mh.backuptest
I/LocationSettingsChecker: Removing dialog suppression flag for package com.example.mh.backuptest
I/Icing: doRemovePackageData com.example.mh.backuptest
I/ActivityManager: Start proc 31545:com.example.mh.backuptest/u0a493 for backup Android/FullBackupAgent
D/BackupManagerService: awaiting agent for ApplicationInfo{a84d42d com.example.mh.backuptest}
D/BackupManagerService: agentConnected pkg=com.example.mh.backuptest agent=Android.os.BinderProxy@b023d62
I/BackupManagerService: got agent Android.app.IBackupAgent$Stub$Proxy@a742ef3
D/VoldConnector: SND -> {17 volume mkdirs /storage/emulated/0/Android/data/com.example.mh.backuptest/files/}
D/VoldConnector: RCV <- {200 17 Command succeeded}
V/BackupXmlParserLogging: Android:fullBackupContent - "true"
D/BackupManagerService: Restore complete, killing Host process of com.example.mh.backuptest
V/BackupManagerService: No more packages; finishing restore
I/Process: Sending signal. PID: 31545 SIG: 9
V/GmsBackupTransport: restore finished
I/BackupRestoreController: restoreFinished for 0
I/BackupManagerService: Restore complete.
Cela semble prometteur! At-il vraiment restauré notre fichier de préférences sauvegardé lors de la réinstallation de l'application?
adb Shell run-as com.example.mh.backuptest ls -al shared_prefs
Si vous voyez le résultat qui devrait être familier maintenant, alors la réponse est oui!
Notes finales: J'ai testé avec succès les étapes ci-dessus sur différents appareils:
Si je me souviens bien, sans les services Google Play installés sur l'appareil, le gestionnaire de sauvegarde ne se connecte pas à Google Drive (ce qui ne serait pas surprenant), mais n'hésitez pas à me corriger à ce sujet.
Sources:
J'ai rencontré un bogue dans Android 6.0, qui peut parfois tuer même un sticky foreground service pour exécuter doFullBackup()
et ne pas le redémarrer pendant des heures. Cela pose problème si votre application doit fonctionner sans interruption pendant le chargement du téléphone (Chroma Doze étant un générateur de bruit blanc, il s'exécute donc souvent lorsque l'utilisateur est endormi):
01-22 03:01:00.303 879 25791 I PFTBT : Initiating full-data transport backup of net.pmarks.chromadoze
01-22 03:01:00.470 879 25793 D BackupManagerService: Binding to full backup agent : net.pmarks.chromadoze
01-22 03:01:00.470 879 25793 D BackupManagerService: awaiting agent for ApplicationInfo{8ab9ee7 net.pmarks.chromadoze}
01-22 03:01:00.482 879 8822 D BackupManagerService: agentConnected pkg=net.pmarks.chromadoze agent=Android.os.BinderProxy@3428a8a
01-22 03:01:00.482 879 25793 I BackupManagerService: got agent Android.app.IBackupAgent$Stub$Proxy@a4738fb
01-22 03:01:00.525 879 25793 I BackupRestoreController: Getting widget state for user: 0
01-22 03:01:00.527 879 25796 D BackupManagerService: Calling doFullBackup() on net.pmarks.chromadoze
01-22 03:01:00.554 879 8821 I WindowState: WIN DEATH: Window{7b1ddb4 u0 net.pmarks.chromadoze/net.pmarks.chromadoze.ChromaDoze}
01-22 03:01:00.570 879 3721 I ActivityManager: Process net.pmarks.chromadoze (pid 18451) has died
01-22 03:01:00.570 879 3721 W ActivityManager: Scheduling restart of crashed service net.pmarks.chromadoze/.NoiseService in 13305612ms
Cela concerne uniquement les applications avec targetSdkVersion 23
, mais une fois que vous avez publié une telle application, il est impossible de revenir à 22
: les utilisateurs qui tentent d'installer la version suivante voient (Error -504)
dans le Play Store.
Je connais deux solutions:
Android:allowBackup="false"
dans votre manifeste pour désactiver toutes les sauvegardes.Android:backupAgent
, qui (éventuellement) désactive les sauvegardes complètes et utilise l'ancienne API de sauvegarde.Cependant, si vous avez une application targetSdkVersion 23
installée sans backupAgent
, l'ajout de backupAgent
ne désactive pas les sauvegardes complètes dans l'immédiat. vous devez redémarrer l'appareil pour le retirer de la file d'attente.
Pour voir quelles applications recevront une sauvegarde complète, vous pouvez exécuter ce qui suit:
$ adb Shell dumpsys backup
Et ensuite, cherchez la section Full backup queue:
.