• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 应用触发数据备份/恢复(仅对系统应用开放)
2
3备份恢复是为设备上应用数据、公共数据和系统服务提供的完整的数据备份和恢复解决方案。系统应用开发者可以根据需求,按下述指导开发应用,以触发备份/恢复数据。
4
5- [获取能力文件](#获取能力文件):获取当前系统用户内所有应用与备份恢复相关基础信息的能力文件。能力文件在应用备份/恢复数据时不可缺少。
6
7- [应用备份数据](#应用备份数据):根据能力文件提供的应用信息,选择需要备份的应用数据并进行备份。
8
9- [应用恢复数据](#应用恢复数据):根据能力文件提供的应用信息,选择需要恢复的应用数据并进行恢复。
10
11## 开发说明
12
13备份恢复API的使用指导请参见[API参考](../reference/apis-core-file-kit/js-apis-file-backup-sys.md)。
14
15在使用备份恢复接口之前,需要:
16
171. [申请应用权限](../security/AccessToken/determine-application-mode.md#system_basic等级的应用申请权限):`ohos.permission.BACKUP`
18
192. 导入依赖模块:`@ohos.file.backup`
20
21   ```js
22   import backup from '@ohos.file.backup';
23   ```
24
25## 获取能力文件
26
27获取当前系统用户内所有应用与备份恢复相关基础信息的能力文件。能力文件在应用备份恢复数据时是不可缺少的,开发者可以根据需要获取能力文件。
28
29该文件包含设备类型、设备版本、应用的基础性信息,如应用名称、应用数据大小、应用版本信息、是否支持备份恢复、是否在恢复时安装应用。
30
31调用`backup.getLocalCapabilities()`获取能力文件。
32
33```ts
34import backup from '@ohos.file.backup';
35import common from '@ohos.app.ability.common';
36import fs from '@ohos.file.fs';
37import { BusinessError } from '@ohos.base';
38
39// 获取应用文件路径
40let context = getContext(this) as common.UIAbilityContext;
41let filesDir = context.filesDir;
42
43async function getLocalCapabilities(): Promise<void> {
44 try {
45   let fileData = await backup.getLocalCapabilities();
46   console.info('getLocalCapabilities success');
47   let fpath = filesDir + '/localCapabilities.json';
48   fs.copyFileSync(fileData.fd, fpath);
49   fs.closeSync(fileData.fd);
50 } catch (error) {
51   let err: BusinessError = error as BusinessError;
52   console.error('getLocalCapabilities failed with err: ' + JSON.stringify(err));
53 }
54}
55```
56
57**返回的能力文件内容示例:**
58
59| 属性名称       | 数据类型 | 必填 | 含义                   |
60| -------------- | -------- | ---- | ---------------------- |
61| bundleInfos    | 数组     | 是   | 应用信息列表           |
62| &nbsp;&nbsp;&nbsp;&nbsp; allToBackup    | 布尔值   | 是   | 是否允许备份恢复       |
63| &nbsp;&nbsp;&nbsp;&nbsp; extensionName  | 字符串   | 是   | 应用的扩展名           |
64| &nbsp;&nbsp;&nbsp;&nbsp; name           | 字符串   | 是   | 应用的包名             |
65| &nbsp;&nbsp;&nbsp;&nbsp; needToInstall  | 布尔值   | 是   | 应用恢复时是否需要安装 |
66| &nbsp;&nbsp;&nbsp;&nbsp; spaceOccupied  | 数值     | 是   | 应用数据占用的空间大小 |
67| &nbsp;&nbsp;&nbsp;&nbsp; versionCode    | 数值     | 是   | 应用的版本号           |
68| &nbsp;&nbsp;&nbsp;&nbsp; versionName    | 字符串   | 是   | 应用的版本名称         |
69| deviceType     | 字符串   | 是   | 设备类型               |
70| systemFullName | 字符串   | 是   | 设备版本               |
71
72```json
73{
74"bundleInfos" :[{
75 "allToBackup" : true,
76 "extensionName" : "BackupExtensionAbility",
77 "name" : "com.example.hiworld",
78 "needToInstall" : false,
79 "spaceOccupied" : 0,
80 "versionCode" : 1000000,
81 "versionName" : "1.0.0"
82 }],
83"deviceType" : "default",
84"systemFullName" : "OpenHarmony-4.0.0.0"
85}
86```
87
88## 应用备份数据
89
90开发者可以根据能力文件提供的应用信息,选择需要备份的应用数据。
91
92备份过程中,备份恢复服务会将应用的数据打包成文件,打包后的文件会以打开的文件句柄形式,通过创建实例时所注册的回调[onFileReady](../reference/apis-core-file-kit/js-apis-file-backup-sys.md#onfileready)接口返回。
93
94开发者可以根据需要将文件内容保存到本地。
95
96**示例**
97
98 ```ts
99  import backup from '@ohos.file.backup';
100  import common from '@ohos.app.ability.common';
101  import fs from '@ohos.file.fs';
102  import { BusinessError } from '@ohos.base';
103
104  // 获取沙箱路径
105  let context = getContext(this) as common.UIAbilityContext;
106  let filesDir = context.filesDir;
107  // 创建SessionBackup类的实例用于备份数据
108  let g_session: backup.SessionBackup;
109  function createSessionBackup(): backup.SessionBackup {
110    let generalCallbacks: backup.GeneralCallbacks = {
111      // onFileReady为服务回调给应用侧数据完成的通知,建议开发者在该接口内不要进行过多的耗时实现,可以通过异步线程实现file.fd数据的处理
112      onFileReady: (err: BusinessError, file: backup.File) => {
113        if (err) {
114          console.info('onFileReady err: ' + JSON.stringify(err));
115        }
116        try {
117          let bundlePath = filesDir + '/' + file.bundleName;
118          if (!fs.accessSync(bundlePath)) {
119            fs.mkdirSync(bundlePath);
120          }
121          // 此处执行copyFileSync会多一次内存拷贝,开发者可以直接使用onFileReady的file.fd来进行数据出来,处理完成后close即可,这样会减少内存消耗
122          fs.copyFileSync(file.fd, bundlePath + `/${file.uri}`);
123          fs.closeSync(file.fd);
124          console.info('onFileReady success');
125        } catch (e) {
126          console.error('onFileReady failed with err: ' + e);
127        }
128      },
129      onBundleBegin: (err: BusinessError, bundleName: string) => {
130        if (err) {
131          console.info('onBundleBegin err: ' + JSON.stringify(err));
132        } else {
133          console.info('onBundleBegin bundleName: ' + bundleName);
134        }
135      },
136      onBundleEnd: (err: BusinessError, bundleName: string) => {
137        if (err) {
138          console.info('onBundleEnd err: ' + JSON.stringify(err));
139        } else {
140          console.info('onBundleEnd bundleName: ' + bundleName);
141        }
142      },
143      onAllBundlesEnd: (err: BusinessError) => {
144        if (err) {
145          console.info('onAllBundlesEnd err: ' + JSON.stringify(err));
146        } else {
147          console.info('onAllBundlesEnd');
148        }
149      },
150      onBackupServiceDied: () => {
151        console.info('onBackupServiceDied');
152      },
153    }
154    let sessionBackup = new backup.SessionBackup(generalCallbacks);
155    return sessionBackup;
156  }
157
158  async function sessionBackup (): Promise<void> {
159    g_session = createSessionBackup();
160    // 此处可根据backup.getLocalCapabilities()提供的能力文件,选择需要备份的应用
161    // 也可直接根据应用包名称进行备份
162    const backupApps: string[] = [
163      "com.example.hiworld",
164    ]
165    await g_session.appendBundles(backupApps);
166    console.info('appendBundles success');
167  }
168 ```
169
170## 应用恢复数据
171
172开发者可以根据能力文件提供的应用信息,选择需要恢复的应用数据。
173
174恢复过程中,备份恢复服务会根据开发者调用[getFileHandle](../reference/apis-core-file-kit/js-apis-file-backup-sys.md#getfilehandle)的请求内容,将应用待恢复数据的文件句柄,通过创建实例时注册的回调[onFileReady](../reference/apis-core-file-kit/js-apis-file-backup-sys.md#onfileready)接口返回。可以根据返回的[uri](../reference/apis-core-file-kit/js-apis-file-backup-sys.md#filemeta)将应用对应的待恢复数据写入到文件句柄中。写入完成后开发者调用[publishFile](../reference/apis-core-file-kit/js-apis-file-backup-sys.md#publishfile)通知服务写入完成。
175
176待应用所有恢复数据准备就绪后,服务开始恢复应用数据。
177
178**示例**
179
180 ```ts
181  import backup from '@ohos.file.backup';
182  import fs from '@ohos.file.fs';
183  import { BusinessError } from '@ohos.base';
184  // 创建SessionRestore类的实例用于恢复数据
185  let g_session: backup.SessionRestore;
186  async function publishFile(file: backup.File): Promise<void> {
187    let fileMeta: backup.FileMeta = {
188      bundleName: file.bundleName,
189      uri: file.uri
190    }
191    await g_session.publishFile(fileMeta);
192  }
193  function createSessionRestore(): backup.SessionRestore {
194    let generalCallbacks: backup.GeneralCallbacks = {
195      onFileReady: (err: BusinessError, file: backup.File) => {
196        if (err) {
197          console.info('onFileReady err: ' + JSON.stringify(err));
198        }
199        // 此处开发者请根据实际场景待恢复文件存放位置进行调整 bundlePath
200        let bundlePath: string = '';
201        if (!fs.accessSync(bundlePath)) {
202          console.info('onFileReady bundlePath err : ' + bundlePath);
203        }
204        fs.copyFileSync(bundlePath, file.fd);
205        fs.closeSync(file.fd);
206        // 恢复数据传输完成后,会通知服务端文件准备就绪
207        publishFile(file);
208        console.info('onFileReady success');
209      },
210      onBundleBegin: (err: BusinessError, bundleName: string) => {
211        if (err) {
212          console.error('onBundleBegin failed with err: ' + JSON.stringify(err));
213        }
214        console.info('onBundleBegin success');
215      },
216      onBundleEnd: (err: BusinessError, bundleName: string) => {
217        if (err) {
218          console.error('onBundleEnd failed with err: ' + JSON.stringify(err));
219        }
220        console.info('onBundleEnd success');
221      },
222      onAllBundlesEnd: (err: BusinessError) => {
223        if (err) {
224          console.error('onAllBundlesEnd failed with err: ' + JSON.stringify(err));
225        }
226        console.info('onAllBundlesEnd success');
227      },
228      onBackupServiceDied: () => {
229        console.info('service died');
230      }
231    }
232    let sessionRestore = new backup.SessionRestore(generalCallbacks);
233    return sessionRestore;
234  }
235
236  async function restore01 (): Promise<void> {
237    g_session = createSessionRestore();
238    const restoreApps: string[] = [
239      "com.example.hiworld",
240    ]
241    // 能力文件的获取方式可以根据开发者实际场景进行调整。此处仅为请求示例
242    // 开发者也可以根据能力文件内容的结构示例,自行构造能力文件内容
243    let fileData = await backup.getLocalCapabilities();
244    await g_session.appendBundles(fileData.fd, restoreApps);
245    console.info('appendBundles success');
246    // 添加需要恢复的应用成功后,请根据需要恢复的应用名称,调用getFileHandle接口获取待恢复应用数文件的文件句柄
247    // 应用待恢复数据文件数请依据实际备份文件个数为准,此处仅为请求示例
248    let handle: backup.FileMeta = {
249      bundleName: restoreApps[0],
250      uri: "manage.json"
251    }
252    await g_session.getFileHandle(handle);
253    handle.uri = "1.tar";
254    await g_session.getFileHandle(handle);
255    console.info('getFileHandle success');
256  }
257 ```
258