1# 拉起邮件类应用(startAbilityByType) 2 3本章节介绍如何拉起邮件类应用扩展面板。 4 5## 邮件类应用扩展面板参数说明 6 7startAbilityByType接口中type字段为mail,对应的wantParam参数: 8 9| 参数名 | 类型 | 必填 | 说明 | 10| ------------------------------------- | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | 11| email | string[ ] | 否 | 收件人邮箱地址(支持多个且以逗号分隔) | 12| cc | string[ ] | 否 | 抄收人邮箱地址(支持多个且以逗号分隔) | 13| bcc | string[ ] | 否 | 密送人邮箱地址(支持多个且以逗号分隔) | 14| subject | string | 否 | 邮件主题 | 15| body | string | 否 | 邮件内容 | 16| ability.params.stream | string[ ] | 否 | 邮件附件(附件的uri地址列表) | 17| ability.want.params.uriPermissionFlag | [wantConstant.Flags](../reference/apis-ability-kit/js-apis-app-ability-wantConstant.md#flags) | 否 | 给邮件附件赋予至少读权限。邮件附件参数存在时,该参数也必须要传 | 18| sceneType | number | 否 | 意图场景,表明本次请求对应的操作意图。1:发邮件。默认为1。 | 19 20> **说明:** 21> 22> * 邮件类应用扩展面板中的类型为string的参数,都要经过encodeURI编码。 23> 24> * 邮件类应用扩展面板中的类型为string[]的参数,数组中的元素都要经过encodeURI编码。 25 26## 拉起方开发步骤 271. 导入相关模块。 28 ```ts 29 import { common, wantConstant } from '@kit.AbilityKit'; 30 ``` 312. 构造接口参数并调用startAbilityByType接口。 32 33 ```ts 34 let context = getContext(this) as common.UIAbilityContext; 35 let wantParam: Record<string, Object> = { 36 'sceneType': 1, 37 'email': [encodeURI('xxx@example.com'),encodeURI('xxx@example.com')], // 收件人邮箱地址,多值以逗号分隔,对数组内容使用encodeURI()方法进行url编码 38 'cc': [encodeURI('xxx@example.com'),encodeURI('xxx@example.com')], // 抄收人邮箱地址,多值以逗号分隔,对数组内容使用encodeURI()方法进行url编码 39 'bcc': [encodeURI('xxx@example.com'),encodeURI('xxx@example.com')], // 密送人邮箱地址,多值以逗号分隔,对数组内容使用encodeURI()方法进行url编码 40 'subject': encodeURI('邮件主题'), // 邮件主题,对内容使用encodeURI()方法进行url编码 41 'body': encodeURI('邮件正文'), // 邮件正文,对内容使用encodeURI()方法进行url编码 42 'ability.params.stream': [encodeURI('附件uri1'),encodeURI('附件uri2')], // 附件uri,多值以逗号分隔,对数组内容使用encodeURI()方法进行url编码 43 'ability.want.params.uriPermissionFlag': wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION 44 }; 45 let abilityStartCallback: common.AbilityStartCallback = { 46 onError: (code: number, name: string, message: string) => { 47 console.log(`onError code ${code} name: ${name} message: ${message}`); 48 }, 49 onResult: (result)=>{ 50 console.log(`onResult result: ${JSON.stringify(result)}`); 51 } 52 } 53 54 context.startAbilityByType("mail", wantParam, abilityStartCallback, 55 (err) => { 56 if (err) { 57 console.error(`startAbilityByType fail, err: ${JSON.stringify(err)}`); 58 } else { 59 console.log(`success`); 60 } 61 }); 62 ``` 63 效果示例图: 64 65  66 67## 目标方开发步骤 68 691. 在module.json5中新增[linkFeature](../quick-start/module-configuration-file.md#skills标签)属性并设置声明当前应用支持的特性功能,从而系统可以从设备已安装应用中找到当前支持该特性的应用,取值范围如下: 70 71 | 取值 | 含义 | 72 | --------------| ------------------------- | 73 | ComposeMail | 声明应用支持撰写邮件功能 | 74 75 ```json 76 { 77 "abilities": [ 78 { 79 "skills": [ 80 { 81 "uris": [ 82 { 83 "scheme": "mailto", // 这里仅示意,应用需确保这里声明的的uri能被外部正常拉起 84 "host": "", 85 "path": "", 86 "linkFeature": "ComposeMail" // 声明应用支持撰写邮件功能 87 } 88 ] 89 } 90 ] 91 } 92 ] 93 } 94 ``` 95 962. 解析面板传过来的参数并做对应处理。 97 98 ```ts 99 UIAbility.onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void 100 ``` 101 102 在参数**want.parameters**中会携带Caller方传入的参数(与调用方传入的有些差异),如下表所示: 103 104 | 参数名 | 类型 | 必填 | 说明 | 105 | ------- | --------- | ---- | -------------------------------------- | 106 | email | string[ ] | 否 | 收件人邮箱地址(支持多个且以逗号分隔) | 107 | cc | string[ ] | 否 | 抄收人邮箱地址(支持多个且以逗号分隔) | 108 | bcc | string[ ] | 否 | 密送人邮箱地址(支持多个且以逗号分隔) | 109 | subject | string | 否 | 邮件主题 | 110 | body | string | 否 | 邮件内容 | 111 | stream | string[ ] | 否 | 邮件附件列表(附件的uri地址列表) | 112 113 > **说明:** 114 > 115 > * 目标方接收的类型为string的参数,都要经过decodeURI解码。 116 > 117 > * 目标方接收的类型为string[]的参数,数组中的元素都要经过decodeURI解码。 118 119**完整示例:** 120 121```ts 122import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 123import { hilog } from '@kit.PerformanceAnalysisKit'; 124import { window } from '@kit.ArkUI'; 125 126const TAG = 'MailTarget1.EntryAbility' 127 128export default class EntryAbility extends UIAbility { 129 windowStage: window.WindowStage | null = null; 130 131 email: string[] | undefined; 132 cc: string[] | undefined; 133 bcc: string[] | undefined; 134 subject: string | undefined; 135 body: string | undefined; 136 stream: string[] | undefined; 137 138 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 139 hilog.info(0x0000, TAG, `onCreate, want=${JSON.stringify(want)}`); 140 super.onCreate(want, launchParam); 141 this.parseWant(want); 142 } 143 144 onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { 145 hilog.info(0x0000, TAG, `onNewWant, want=${JSON.stringify(want)}`); 146 super.onNewWant(want, launchParam); 147 this.parseWant(want); 148 if (!this.windowStage) { 149 hilog.error(0x0000, TAG, 'windowStage is null'); 150 this.context.terminateSelf(); 151 return; 152 } 153 this.loadPage(this.windowStage); 154 } 155 156 private parseWant(want: Want): void { 157 this.email = this.decodeStringArr(want.parameters?.email as string[]); 158 this.cc = this.decodeStringArr(want.parameters?.cc as string[]); 159 this.bcc = this.decodeStringArr(want.parameters?.bcc as string[]); 160 this.subject = decodeURI(want.parameters?.subject as string);// 使用decodeURI()方法对邮件主题进行url解码,其他字段处理方法相同 161 this.body = decodeURI(want.parameters?.body as string);// 使用decodeURI()方法对邮件内容进行url解码,其他字段处理方法相同 162 this.stream = this.decodeStringArr(want.parameters?.stream as string[]); 163 } 164 165 // 使用decodeURI()方法对string数组内容进行解码 166 private decodeStringArr(source: string[] | undefined): string[] { 167 let target: string[] = []; 168 source?.forEach(e => { 169 target.push(decodeURI(e)); 170 }) 171 return target; 172 } 173 174 private loadPage(windowStage: window.WindowStage): void { 175 const storage: LocalStorage = new LocalStorage({ 176 "email": this.email, 177 "cc": this.cc, 178 "bcc": this.bcc, 179 "subject": this.subject, 180 "body": this.body, 181 "stream": this.stream 182 } as Record<string, Object>); 183 184 windowStage.loadContent('pages/ComposeMailPage', storage); 185 186 } 187 188 onDestroy(): void { 189 hilog.info(0x0000, TAG, `onDestroy`); 190 } 191 192 onWindowStageCreate(windowStage: window.WindowStage): void { 193 hilog.info(0x0000, TAG, `onWindowStageCreate`); 194 this.windowStage = windowStage; 195 this.loadPage(this.windowStage); 196 } 197 198 onWindowStageDestroy(): void { 199 hilog.info(0x0000, TAG, `onWindowStageDestroy`); 200 } 201 202 onForeground(): void { 203 hilog.info(0x0000, TAG, `onForeground`); 204 } 205 206 onBackground(): void { 207 hilog.info(0x0000, TAG, `onBackground`); 208 } 209} 210```