如何testingAndroid 6.0完全备份行为?

TL; DR:您如何成功地使用命令行工具(或其他)来testingAndroid 6.0的备份和还原行为,因为我无法让他们恢复任何东西?


由于我之前遇到了一个来自我的书中的示例应用程序,试图让这个工作,我从头开始为这个问题的目的。

我从Android Studio 1.4.1新build项目向导中创build了一个全新的项目,接受所有相关的默认设置,除了我使用了“Empty Activity”模板并在应用程序ID和显示名称上添加了2 。 然后,我添加了一些代码给活动给我一些关于内部存储的数据:

 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(); } } 

我运行的应用程序,并确认,使用adb shell run-as com.commonsware.myapplication2 ... SharedPreferences文件存在。

然后,我运行adb shell setprop log.tag.BackupXmlParserLogging VERBOSE ,每个文档。 没有明显的问题。

然后,我运行adb shell bmgr run ,每个文档都生成了很多日志消息,但没有任何与我的应用程序有关的内容(正如我们所预料的那样(也没有提示备份引擎有什么特别的问题)。

然后,我运行adb shell bmgr fullbackup com.commonsware.myapplication2 ,根据生成的文档:

 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. 

似乎没有任何指示备份中的错误或其他故障。

然后我通过手动删除SharedPreferences文件:

 adb shell run-as com.commonsware.myapplication2 rm /data/data/com.commonsware.myapplication2/shared_prefs/com.commonsware.myapplication2_preferences.xml 

并确认SharedPreferences文件不再存在。

然后,我运行adb shell bmgr restore com.commonsware.myapplication2 ,根据文档。 这产生了另一组日志消息,有一些明显的错误:

 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] 

令人担忧的是:

 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 

而且,果然,文件没有被恢复。 我不知道什么是“未经授权的完整数据恢复请求”的含义。

所以,我卸载了应用程序(通过gradle uninstallDebug ),并再次安装它,而不运行它(通过gradle installDebug )。 根据文档,“您可以通过卸载并重新安装您的应用程序来testing您的应用程序的自动恢复。应用程序安装完成后,应用程序数据将自动从云端恢复。 但是,重新安装它几分钟后, SharedPreferences文件仍然不存在。

然后,我再次运行adb shell bmgr restore com.commonsware.myapplication2 ,并得到了一组类似的日志语句,与“未经授权的完整数据恢复请求”消息相同。

这个过程有没有步骤,我缺less或没有logging?

编辑 :我一直在testing实际的硬件(Nexus 6)。 每MH的评论,我testing了这个程序在Android 6.0模拟器(无广告服务),它的工作原理。 这表明文档并不是完全错误的,尽pipe它仍然存在着为什么不能使用硬件的问题。

Related of "如何testingAndroid 6.0完全备份行为?"

在讨论和testing了各种场景(参考下面的评论)之后,我决定把这些结果合并起来写成答案。 事实上,这实际上并没有解决问题,但它将回答“你如何成功地使用命令行工具(或其他)来testingAndroid 6.0的备份和恢复行为? 这将以一步一步的指导的forms进行,概述什么对我有效,以及我如何克服我一路上所遇到的各种障碍。

开始。 如果您还没有完成“ configuration应用程序的自动备份 ”的培训,我build议您先做。 它logging了自动备份function,并且已经完成了logging各个步骤的非常体面的工作。

让我们从头开始:我们需要一个应用程序来testing! 就像CommonsWare一样,我只是简单地使用Android Studio来创build一个Empty项目的新项目。 确保将API 23设置为目标SDK。 打开自动生成的MainActivity并将一些代码添加到onCreate()以便将值保存到共享首选项中(或仅复制问题中的代码段):

 PreferenceManager .getDefaultSharedPreferences(this) .edit() .putBoolean("foo", true) .apply(); 

构build,部署和运行应用程序。 这应该触发foo被持久化,并将导致在磁盘上创build一个xml文件。 确认这一点:

 adb shell run-as <package_name> ls -al shared_prefs 

我的testing应用程序的包是com.example.mh.backuptest (这是我将在这里使用示例命令),所以我的命令是:

 adb shell run-as com.example.mh.backuptest ls -al shared_prefs 

您应该看到一行输出列出了shared_prefs文件夹中的所有文件,该文件应该只有一行:

 com.example.mh.backuptest_preferences.xml 

这意味着首选项文件已成功创build, foo被写入。 如果你喜欢,你可以检查文件的内容来确认这一点。

现在回到testing自动备份。 首先,确保您select了自动应用程序备份。 在您的Android 6.0设备上,转至:

 Settings > Backup & reset > Back up my data > On 

之后,打开备份传输和备份xmlparsing器的详细日志logging,以便我们可以看到发生了什么:

 adb shell setprop log.tag.GmsBackupTransport VERBOSE adb shell setprop log.tag.BackupXmlParserLogging VERBOSE 

然后,初始化备份pipe理器:

 adb shell bmgr run 

这应该会在logcat中产生相当多的输出。 你至less应该看到类似这样的东西:

 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. 

如果您的输出包含更多,请不要担心。 我故意删除了与备份无关的行。 我只在输出时粘贴了单个应用程序的备份; 您在第一次运行此命令时可能会看到更多条目。

相反,如果你看到以下几点:

 GmsBackupTransport: Scotty transfer exception. null PFTBT : Error -1002 backing up com.example.mh.backuptest 

要么:

 GmsBackupTransport: Rejecting full data backup. user has not seen up to date legal text 

确保您select了自动应用程序备份(请参阅上文)。 如果你有,而且你仍然看到这些消息 – 这也发生在我身上 – 尝试几次设置,重新启动设备。 还是没有运气? 我一直在那里…从设备上删除Google帐户,重新启动,重新添加并再次select。 其他人报告说 ,工厂重置工作也是如此,但这似乎有点过分。 🙂

如果你有这么多,那么是时候确保我们的testing应用程序得到备份! 要强制备份,请运行:

 adb shell bmgr fullbackup com.example.mh.backuptest 

这会杀了你的应用程序,如果它仍在运行 – 不要担心,这是正常的。 您应该看到来自备份传输的相当一部分输出:

 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. 

通过备份我们的testing应用程序,让我们看看它是否实际上恢复数据。 首先,我们删除我们的testing应用程序创build的偏好文件,这是默认自动备份的一部分:

 adb shell run-as com.example.mh.backuptest rm shared_prefs/com.example.mh.backuptest_preferences.xml 

确认文件不再存在:

 adb shell run-as com.example.mh.backuptest ls -al shared_prefs 

如果该命令在没有任何输出的情况下执行,则意味着shared_prefs文件夹中没有文件,并且您已成功删除了首选项。

现在,触发我们的testing应用程序的恢复:

 adb shell bmgr restore com.example.mh.backuptest 

同样,备份传输将产生相当多的输出:

 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. 

如果一切如上所述,让我们来检查我们的首选文件是否回到了应该在的位置:

 adb shell run-as com.example.mh.backuptest ls -al shared_prefs 

输出应该是你第一次运行命令时看到的(在这个相当长的故事的早期阶段)。 如果是这样,那就恭喜你了! 您已成功使用Google的自动备份应用程序备份和恢复您的应用程序!

快乐? 那我们再来做一个testing! 卸载应用程序:

 adb uninstall com.example.mh.backuptest 

即使我们看到“成功”,但确认它已经消失:

 adb shell run-as com.example.mh.backuptest 

预期产出:

 run-as: Package 'com.example.mh.backuptest' is unknown 

现在,再次安装应用程序(但不要启动它):

 adb install backuptest.apk 

看看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. 

That looks promising! Did it really restore our backed up preference file when reinstalling the app?

 adb shell run-as com.example.mh.backuptest ls -al shared_prefs 

If you see the output that should be familiar by now, then the answer is yes!


Final notes: I've successfully tested above steps on various devices:

  • Default Android 6.0 Emulator (emulator64-x86) w/o Google Play Services
  • Genymotion Google Nexus 5X – API 23 – PREVIEW w/ Google Play Services
  • Nexus 5X (physical device) w/ Google Play Services.

If I recall correctly, without Google Play Services installed on the device, the backup manager doesn't actually go off to Google Drive (which wouldn't be surprising), but feel free to correct me on that.


资料来源:

  • CommonWare's great question at the very top of this page.
  • Google's training on Configuring Auto Backup for Apps .
  • Various issues on Google's bug tracker, including this one and this one .

I encountered a bug in Android 6.0, where it will sometimes kill even a sticky foreground service to run doFullBackup() , and not restart it for hours. This is problematic if your app needs to run without interruption while the phone is charging (Chroma Doze is a white noise generator, so it often runs while the user is asleep):

 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 

This only affects apps with targetSdkVersion 23 , but once you've published such an app, reverting to 22 is impossible: users who attempt to install the next version see (Error -504) in the Play store.

There are two solutions that I'm aware of:

  • Set android:allowBackup="false" in your manifest to disable all backups.
  • Implement an android:backupAgent , which (eventually) disables full backups and uses the old backup API instead.

However, if you have a targetSdkVersion 23 app installed without a backupAgent , adding the backupAgent doesn't actually disable full backups right away; you need to reboot the device to remove it from the queue.

To see which apps will receive a full backup, you can run the following:

 $ adb shell dumpsys backup 

And then look for the Full backup queue: section.