• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Updating Local and Online Images in the Widget
2
3
4Typically, a widget includes local images or online images downloaded from the network. To obtain local and online images, use the FormExtensionAbility. The following exemplifies how to show local and online images on a widget.
5
6
71. For the widget to download online images, declare the **ohos.permission.INTERNET** permission for the widget. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md).
8
92. Update local files in the **onAddForm** lifecycle callback of the EntryFormAbility.
10
11   ```ts
12   import formBindingData from '@ohos.app.form.formBindingData';
13   import formProvider from '@ohos.app.form.formProvider';
14   import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
15   import request from '@ohos.request';
16   import fs from '@ohos.file.fs';
17
18   export default class EntryFormAbility extends FormExtensionAbility {
19     ...
20     // When the widget is added, a local image is opened and transferred to the widget page for display.
21     onAddForm(want) {
22       // Assume that the local image head.PNG is in the tmp directory of the current widget.
23       let tempDir = this.context.getApplicationContext().tempDir;
24       // Open the local image and obtain the FD after the image is opened.
25       let file;
26       try {
27         file = fs.openSync(tempDir + '/' + 'head.PNG');
28       } catch (e) {
29         console.error(`openSync failed: ${JSON.stringify(e)}`);
30       }
31       let formData = {
32         'text': 'Image: Bear',
33         'imgName': 'imgBear',
34         'formImages': {
35           'imgBear': file.fd
36         },
37         'loaded': true
38       }
39       // Encapsulate the FD in formData and return it to the widget page.
40       return formBindingData.createFormBindingData(formData);
41     }
42
43     ...
44   }
45   ```
46
473. Update online images in the **onFormEvent** lifecycle callback of the EntryFormAbility.
48
49   ```ts
50   import formBindingData from '@ohos.app.form.formBindingData';
51   import formProvider from '@ohos.app.form.formProvider';
52   import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
53   import request from '@ohos.request';
54   import fs from '@ohos.file.fs';
55
56   export default class EntryFormAbility extends FormExtensionAbility {
57     // When the message event is triggered on the widget page, an online image is downloaded and transferred to the widget page for display.
58     onFormEvent(formId, message) {
59       let formInfo = formBindingData.createFormBindingData({
60         'text': 'Updating...'
61       })
62       formProvider.updateForm(formId, formInfo)
63       // Note: After being started with the triggering of the lifecycle callback, the FormExtensionAbility can run in the background for only 5 seconds.
64       // When possible, limit the size of the image to download. If an image cannot be downloaded within 5 seconds, it will not be updated to the widget page.
65       let netFile = 'https://xxxx/xxxx.png'; // Specify the URL of the image to download.
66       let tempDir = this.context.getApplicationContext().tempDir;
67       let fileName = 'file' + Date.now();
68       let tmpFile = tempDir + '/' + fileName;
69       request.downloadFile(this.context, {
70         url: netFile, filePath: tmpFile, enableMetered: true, enableRoaming: true
71       }).then((task) => {
72         task.on('complete', function callback() {
73           console.info('ArkTSCard download complete:' + tmpFile);
74           let file;
75           try {
76             file = fs.openSync(tmpFile);
77           } catch (e) {
78             console.error(`openSync failed: ${JSON.stringify(e)}`);
79           }
80           let fileInfo = {};
81           fileInfo[fileName] = file.fd;
82           let formData = {
83             'text': 'Image:' + fileName,
84             'imgName': fileName,
85             'formImages': fileInfo,
86             'loaded': true
87           };
88           let formInfo = formBindingData.createFormBindingData(formData)
89           formProvider.updateForm(formId, formInfo).then((data) => {
90             console.info('FormAbility updateForm success.' + JSON.stringify(data));
91           }).catch((error) => {
92             console.error('FormAbility updateForm failed: ' + JSON.stringify(error));
93           })
94         })
95         task.on('fail', function callBack(err) {
96           console.info('ArkTSCard download task failed. Cause:' + err);
97           let formInfo = formBindingData.createFormBindingData({
98             'text':'Update failed.'
99           })
100           formProvider.updateForm(formId, formInfo)
101         });
102       }).catch((err) => {
103         console.error('Failed to request the download. Cause: ' + JSON.stringify(err));
104       });
105     }
106
107     ...
108   };
109   ```
110
1114. On the widget page, use the **\<Image>** component to display the widget content transferred from the EntryFormAbility.
112
113   ```ts
114   let storage = new LocalStorage();
115   @Entry(storage)
116   @Component
117   struct WidgetCard {
118     @LocalStorageProp('text') text: string = 'Loading...';
119     @LocalStorageProp('loaded') loaded: boolean = false;
120     @LocalStorageProp('imgName') imgName: string = 'name';
121
122     build() {
123       Column() {
124         Text(this.text)
125           .fontSize('12vp')
126           .textAlign(TextAlign.Center)
127           .width('100%')
128           .height('15%')
129
130         Row() {
131           if (this.loaded) {
132             Image('memory://' + this.imgName)
133               .width('50%')
134               .height('50%')
135               .margin('5%')
136           } else {
137             Image('common/start.PNG')
138               .width('50%')
139               .height('50%')
140               .margin('5%')
141           }
142         }.alignItems(VerticalAlign.Center)
143         .justifyContent(FlexAlign.Center)
144
145         Button ('Update')
146           .height('15%')
147           .onClick(() => {
148             postCardAction(this, {
149               'action': 'message',
150               'params': {
151                 'info': 'refreshImage'
152               }
153             });
154           })
155       }
156       .width('100%').height('100%')
157       .alignItems(HorizontalAlign.Center)
158       .padding('5%')
159     }
160   }
161   ```
162
163> **NOTE**
164> - The **\<Image>** component displays images in the remote memory based on the **memory://** identifier in the input parameter (**memory://fileName**). The value of **fileName** must be consistent with the key in the object (**'formImages': {key: fd}**) passed by the EntryFormAbility.
165>
166> - The **\<Image>** component determines whether to update the image by comparing the values of **imgName** consecutively passed by the EntryFormAbility. It updates the image only when the values are different.
167