如何测试Android 6.0完整备份行为?

36

简述:如何成功使用命令行工具(或其他任何工具)测试Android 6.0备份和还原功能,因为我无法恢复任何数据?


既然我在尝试让书上的示例应用程序正常运行时遇到了问题,为了解决这个问题,我从头开始创建了一个新项目。

我使用 Android Studio 1.4.1 新建项目向导创建了一个全新的项目,并接受了所有相关默认设置,除了选择了“空白活动”模板并在应用程序 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)。根据文档的说法,"您可以通过卸载和重新安装您的应用程序来测试自动恢复。应用程序数据在应用程序安装完成后会自动从云端恢复。"然而,在重新安装几分钟后,SharedPreferences文件仍不存在。

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

我是否遗漏了此过程中的步骤或其他未记录的步骤?

编辑:我一直在实际硬件(Nexus 6)上进行测试。根据MH的评论,我在一个Android 6.0模拟器(没有Play服务)上测试了这个过程,并且它有效。这表明文档并不完全错误,尽管这仍然值得怀疑为什么在硬件上不能正常工作。


1
@CommonsWare:只是想确认一下:BackupManagerService:完整备份目前不可行--键/值备份尚未运行?问题线程也没有帮助吗?谢谢。 - ρяσѕρєя K
1
你看过这篇文章吗:http://arstechnica.com/gadgets/2015/10/android-6-0s-auto-backup-for-apps-perfect-data-backup-for-the-1-5/ 文章中提到了JobScheduler API和Google Drive。 - Morrison Chang
@ρяσѕρєяK:我之前也遇到过这个问题和“用户没有看到最新的法律文本”问题。我解决了那些问题,然后来到了这里。 - CommonsWare
1
有趣的问题。我刚刚按照上述过程(在默认的emulator64-x86实例和Genymotion GN5X 6.0预览版上)进行了相同的备份和还原共享偏好设置,并成功地完成了操作。出于某种原因,我的还原日志中没有提到Google Drive。这让我尝试在设备上设置或不设置任何帐户来重新执行整个过程,但看起来并没有什么区别。很乐意进一步探究,但不确定下一步该去哪里... - MH.
1
@CommonsWare:好的,今天我在一台运行Android 6.0的物理(非root)Nexus 5上重试了一下。在备份选择中遇到了一些问题(我一直遇到可怕的法律文本问题,并且切换备份设置并重新启动设备没有任何作用),最终我将Google帐户从设备中删除并重新添加。从那时起,我重复了昨天的相同步骤,一切都像微风一样顺利。甚至卸载、重新安装并确认备份的首选项确实在安装后恢复了。我可以在答案中写出整个过程,但我怀疑你不会读到任何新内容... - MH.
显示剩余15条评论
2个回答

26
经过讨论和测试不同的情况(请参考下面问题的评论),我决定将这些结果结合起来,写成一篇答案。实际上,这并没有解决所提出的问题,但它会回答一个问题:“如何成功地使用命令行工具(或其他任何东西)来测试Android 6.0的备份和恢复行为?”它将以逐步指南的形式进行,概述我所做的工作以及我如何克服沿途遇到的各种问题。
接下来是步骤。如果您还没有完成“为应用配置自动备份”的培训,请先完成此培训。它记录了自动备份功能,并已经非常好地记录了各种步骤。

让我们从头开始:我们需要一个应用程序进行测试!就像CommonsWare一样,我只是使用Android Studio创建了一个带有活动的新项目。确保将API 23设置为目标SDK。打开自动生成的MainActivity并在onCreate()中添加一些代码以将值保留在共享首选项中(或者只需从问题中复制代码片段):

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

构建,部署和运行应用程序。这将触发foo被持久化,并导致在磁盘上创建一个xml文件。通过以下方式确认:
adb shell run-as <package_name> ls -al shared_prefs

我的测试应用程序的包名是com.example.mh.backuptest(这也是我将在此处使用的示例命令),因此我的命令是:

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

你应该看到一行输出,列出了shared_prefs文件夹中的所有文件,应该只有一个:
com.example.mh.backuptest_preferences.xml

这意味着首选项文件已成功创建,并将“foo”写入其中。如果您愿意,可以检查文件的内容以确认此操作。
现在,回到测试自动备份。首先,请确保您选择了自动应用程序备份选项。在您的Android 6.0设备上,请转到:
Settings > Backup & reset > Back up my data > On

然后,打开备份传输和备份XML解析器的详细日志记录,以便我们可以看到发生了什么:

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

然后,初始化备份管理器:
adb shell bmgr run

这应该会在logcat中生成大量输出。您至少应该看到类似于以下内容的东西:
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 

请确保您已选择自动应用备份(见上文)。如果您已经这么做了,但仍然看到这些消息 - 我也遇到了这种情况 - 请尝试多次切换设置并重新启动设备。还是没有成功?我也有过这种经历...从设备中删除 Google 帐户,重新启动,重新添加帐户并再次选择加入。其他人已经报告说出厂设置也可以解决问题,但我觉得那有点过分了。:)

如果您已经完成上述步骤,那么现在是时候确保我们的测试应用程序得到备份了!要强制备份,请运行:

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.

备份了我们的测试应用程序后,让我们看看它是否能够还原数据。首先,让我们删除我们的测试应用程序创建的偏好文件,并将其作为默认自动备份的一部分:

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 文件夹中没有文件,并且您已成功删除了 prefs。现在,触发我们的测试应用程序的还原:
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的自动备份应用程序功能备份和还原了你的应用程序!
开心吗?那么我们再做一个测试!卸载应用程序:
adb uninstall com.example.mh.backuptest

即使我们看到“Success”,也要确认它已经消失:
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.

看起来很有希望!在重新安装应用程序时,它确实恢复了我们备份的首选项文件吗?

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

如果您现在看到的输出已经很熟悉了,那么答案是肯定的!

最后说明:我已经在多种设备上成功测试了以上步骤:

  • 默认的Android 6.0模拟器(emulator64-x86),未安装Google Play服务
  • Genymotion Google Nexus 5X - API 23 - 预览版,已安装Google Play服务
  • Nexus 5X(实体设备),已安装Google Play服务

如果我没记错的话,在设备上没有安装Google Play服务的情况下,备份管理器实际上不会连接到Google Drive(这并不奇怪),但请随时纠正我。


来源:


恢复对我无效。 我怀疑是因为令牌始终为0:http://pastebin.com/raw/mP768it0 - JoachimR
我遇到了“拒绝完全数据备份,用户还没有看到最新的法律文本”的问题,只有删除并重新添加账户才起作用。非常感谢您的回答! - Malcolm
我已经在每个设备上单独备份/恢复工作了。但是我一直在尝试在新设备上(即在新的模拟器实例中使用我的Google帐户登录)测试从另一个设备恢复备份。但我一直没有成功。我想我只是打算将代码保留为现在的状态。也许只有在上传到Play Store之后才能正常工作...#沮丧 - Boy
我按照你的步骤操作,但是我遇到了以下备份错误。你有什么想法吗?[GmsBackupTransport] 拒绝对 com.myapp 应用程序进行完全备份,因为它不符合条件 (INELIGIBLE_DOLLY_CONSENT)。 - Emil
@batmaci:不幸的是,我不知道“dolly consent”是什么。Google似乎也没有提供很有帮助的信息。我最好的猜测是某些设置还没有被启用或选择。可能与设备相关,但也可以尝试调整帐户设置,特别是与Google Drive相关的设置。您也可以尝试使用不同的帐户或在不同的设备上使用相同的帐户。我的建议是通过试错来尝试缩小问题范围。祝你好运! - MH.

0

我在Android 6.0中遇到了一个bug,即它有时会杀死甚至是粘性前台服务来运行doFullBackup(),并且在数小时内不重新启动。如果您的应用程序需要在手机充电时无间断地运行(Chroma Doze是一个白噪声生成器,因此它经常在用户睡觉时运行),这将成为问题:

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

这只影响到 targetSdkVersion 23 的应用程序,但一旦您发布了这样的应用程序,则无法恢复到 22:尝试安装下一个版本的用户在 Play 商店中看到 (Error -504)

我知道有两种解决方案:

  • 在清单文件中设置 android:allowBackup="false" 以禁用所有备份。
  • 实现一个 android:backupAgent,该备份代理(最终)禁用完整备份并使用旧备份API。

但是,如果您安装了没有 backupAgenttargetSdkVersion 23 应用程序,则添加 backupAgent 实际上不会立即禁用完整备份;您需要重新启动设备以将其从队列中删除。

要查看哪些应用程序将接收完整备份,请运行以下命令:

$ adb shell dumpsys backup

然后查找完整备份队列:部分。


你是否报告了这个错误?并且在两年后它仍然有效吗? - Emil
https://android.googlesource.com/platform/frameworks/base/+/63fec3e 和 https://android.googlesource.com/platform/frameworks/base/+/339b53a 应该可以解决这个问题,但我不知道这些漏洞在实际中是否仍然存在。 - Paul Marks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接