1# 短彩信<a name="ZH-CN_TOPIC_0000001105544742"></a> 2 3 4- [简介<a name="section117mcpsimp"></a>](#简介) 5- [目录<a name="section125mcpsimp"></a>](#目录) 6- [约束<a name="section129mcpsimp"></a>](#约束) 7- [接口说明<a name="section134mcpsimp"></a>](#接口说明) 8- [使用说明<a name="section170mcpsimp"></a>](#使用说明) 9 - [发送短信<a name="section172mcpsimp"></a>](#发送短信) 10 - [创建ShortMessage对象<a name="section181mcpsimp"></a>](#创建shortmessage对象) 11- [相关仓<a name="section189mcpsimp"></a>](#相关仓) 12 13## 简介<a name="section117mcpsimp"></a> 14 15短彩信模块为移动数据用户提供短信收发和彩信编解码功能,主要功能有GSM/CDMA短信收发、短信PDU(Protocol data unit,协议数据单元)编解码、Wap Push接收处理 、小区广播接收、彩信通知、 彩信编解码和SIM卡短信记录增删改查等。 16 17**图 1** 短彩信模块架构图<a name="fig420553511549"></a> 18 19 20短彩信模块由接口管理类、短信发送管理类、短信接收管理类,和彩信编解码工具类组成。其中: 21 22- 接口管理类:SmsInterfaceManager 负责对外提供短信发送、SIM卡短信记录操作和配置相关接口,负责创建SmsSendManager 、SmsReceiveManager和smsMiscManager 对象。 23- 短信发送管理类: SmsSendManager创建GSM\(GsmSmsSender\) 、CDMA\(CdmaSmsSender\) 和网络策略管理(SmsNetworkPolicyManager)对象,并根据网络制式调度对应的GSM或CDMA对象发送短信。 24- 短信接收管理类: SmsReceiveManager 负责短信接收,监听来自RIL层的新短信信息;创建GSM\(GsmSmsReceiveHandler\) 和CDMA\(CdmaSmsReceiveHandler\) 对象;创建SmsWapPushHandler 和SmsCellBroadcastHandler 对象。 25- 彩信编解码类:负责彩信PDU的编解码处理。 26- Misc管理类:负责Sim卡短信操作、小区广播配置、短信服务中心地址配置和默认卡槽配置等。 27- IMS短信管理类:ImsSmsClient 负责IMS短信发送,及设置/获取IMS短信配置信息。 28 29## 目录<a name="section125mcpsimp"></a> 30 31``` 32/base/telephony/sms_mms 33├─ common # 内部公共代码 34├─ figures # Readme资源文件 35├─ frameworks # 短彩信内部框架接口层 36│ ├─ js # js相关代码 37│ └─ native # native相关代码 38├─ interfaces # 接口目录 39│ ├─ innerkits # 部件间的内部接口 40│ │ └─ ims # IMS短信接口定义 41│ └─ kits # 对应用提供的接口(例如JS接口) 42├─ sa_profile # 短信服务的启动文件目录 43├─ services # 短彩信服务实现代码 44│ ├─ ims_service_interaction # IMS短信服务交互层 45│ ├─ include # 头文件目录 46│ ├─ cdma # CDMA制式源文件 47│ └─ gsm # GSM制式源文件 48├─ test # 单元测试目录 49│ ├─ fuzztest # 模糊测试相关代码 50│ ├─ gtest # 自动化测试相关代码 51│ └─ unittest # 单元测试相关代码 52└─ utils # 通用工具相关 53``` 54 55## 约束<a name="section129mcpsimp"></a> 56 57- 开发语言:JavaScript。 58- 软件约束,需要与以下服务配合使用:Telephony核心服务(core\_service);依赖[glib](https://gitlab.gnome.org/GNOME/glib)库。 59- 硬件约束,需要搭载的设备支持以下硬件:可以进行独立蜂窝通信的Modem以及SIM卡。 60 61## 接口说明<a name="section134mcpsimp"></a> 62 63**表 1** 短彩信对外提供的接口 64 65| 接口名称 | 接口描述 | 所需权限 | 66| ------------------------------------------------------------ | ------------------------------------------------------------ | ----------------------------------- | 67| function sendMessage(options: SendMessageOptions): void; | 发送短信,通过callback异步获取短信发送结果。 | SystemPermission.SEND_MESSAGES | 68| function createMessage(pdu: Array\<number>, specification: string, callback: AsyncCallback、\<ShortMessage>): void; | 根据协议数据单元(PDU)和指定的短信协议创建短信实例,使用callback方式异步返回创建的短信实例。 | 无 | 69| function createMessage(pdu: Array\<number>, specification: string): Promise\<ShortMessage> | 根据协议数据单元(PDU)和指定的短信协议创建短信实例,使用Promise方式异步返回创建的短信实例。 | 无 | 70| function getDefaultSmsSlotId(callback: AsyncCallback\<number>): void | 获取发送短信的默认SIM卡槽,使用callback方式异步返回默认SIM卡槽。 | 无 | 71| function getDefaultSmsSlotId():Promise\<number> | 获取发送短信的默认SIM卡,使用Promise方式异步返回默认SIM卡槽。 | 无 | 72| function getDefaultSmsSimId(callback: AsyncCallback\<number>): void | 获取发送短信的默认SIM卡ID,使用callback方式异步返回默认SIM卡槽。 | 无 | 73| function getDefaultSmsSimId():Promise\<number> | 获取发送短信的默认SIM卡ID,使用Promise方式异步返回默认SIM卡槽。 | 无 | 74| function setSmscAddr(slotId: number, smscAddr: string, callback: AsyncCallback\<void>): void | 设置短信服务中心地址,使用callback方式异步返回undefined。 | ohos.permission.SET_TELEPHONY_STATE | 75| function setSmscAddr(slotId: number, smscAddr: string): Promise\<void> | 设置短信服务中心地址,使用Promise方式异步返回undefined。 | ohos.permission.SET_TELEPHONY_STATE | 76| function getSmscAddr(slotId: number, callback: AsyncCallback\<string>): void | 获取短信服务中心地址,使用callback方式异步返回短信服务中心地址。 | ohos.permission.GET_TELEPHONY_STATE | 77| function getSmscAddr(slotId: number): Promise\<string> | 获取短信服务中心地址,使用Promise方式异步返回短信服务中心地址。 | ohos.permission.GET_TELEPHONY_STATE | 78 79**表 2** 发送短信接口参数SendMessageOptions说明 80 81| 参数 | 类型 | 描述 | 是否必填 | 82| ---------------- | --------------------------------------------- | ---------------- | ---------------- | 83| slotId | number | 卡槽id | 是 | 84| destinationHost | string | 接收端的电话号码 | 是 | 85| serviceCenter | string | 短信中心服务地址 | 否 | 86| content | content \| Array\<number> | 短信内容 | 是 | 87| destinationPort | number | 接收端端口号 | 发送数据短信必填 | 88| sendCallback | AsyncCallback\<ISendShortMessageCallback> | 发送结果回调 | 是 | 89| deliveryCallback | AsyncCallback\<IDeliveryShortMessageCallback> | 送达报告回调 | 是 | 90 91**表 3** ISendShortMessageCallback类型说明 92 93| 参数 | 类型 | 描述 | 94| ---------- | ------------- | ------------------ | 95| result | SendSmsResult | 发送结果 | 96| url | string | URL地址 | 97| isLastPart | boolean | 是否是最后一条短信 | 98 99**表 4** SendSmsResult枚举值 100 101| 名称 | 值 | 描述 | 102| ------------------------------------ | ---- | ------------------------ | 103| SEND_SMS_SUCCESS | 0 | 发送成功 | 104| SEND_SMS_FAILURE_UNKNOWN | 1 | 发送失败,原因未知 | 105| SEND_SMS_FAILURE_RADIO_OFF | 2 | 发送失败,因为Modem关闭 | 106| SEND_SMS_FAILURE_SERVICE_UNAVAILABLE | 3 | 发送失败,因为网络不可用 | 107 108**表 5** IDeliveryShortMessageCallback类型说明 109 110| 参数 | 类型 | 描述 | 111| ---- | -------------- | ------------------------------------------- | 112| pdu | Array\<number> | PDU(Protocol data unit,协议数据单元)数组 | 113 114**表 6** createMessage接口参数说明 115 116| 参数 | 类型 | 描述 | 117| ------------- | -------------- | ------------------------------------------- | 118| pdu | Array\<number> | PDU(Protocol data unit,协议数据单元)数组 | 119| specification | string | 协议类型(3gpp或3gpp2) | 120 121**表 7** getDefaultSmsSlotId接口参数说明 122 123| 参数 | 类型 | 描述 | 124| -------- | ---------------------- | ------------------------- | 125| callback | AsyncCallback\<number> | 回调函数。0:卡槽1:卡槽2 | 126 127**表 8** setSmscAddr接口参数说明 128 129| 参数名 | 类型 | 必填 | 说明 | 130| -------- | -------------------- | ---- | -------------------------- | 131| slotId | number | 是 | SIM卡槽ID:0:卡槽1:卡槽2 | 132| smscAddr | string | 是 | 短信服务中心(SMSC)地址。 | 133| callback | AsyncCallback\<void> | 是 | 回调函数。 | 134 135**表 9** getSmscAddr接口参数说明 136 137| 参数名 | 类型 | 必填 | 说明 | 138| -------- | ---------------------- | ---- | -------------------------- | 139| slotId | number | 是 | SIM卡槽ID:0:卡槽1:卡槽2 | 140| callback | AsyncCallback\<string> | 是 | 回调函数。 | 141 142**表 10** 创建短信异步回调ShortMessage说明 143 144| 变量 | 类型 | 说明 | 145| ------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | 146| emailAddress | string | 电子邮件地址。 | 147| emailMessageBody | string | 电子邮件正文。 | 148| hasReplyPath | boolean | 收到的短信是否包含“TP-回复路径”,默认为false。“TP-回复路径”:移动电话可循发送SMS消息的短消息中心进行回复。 | 149| isEmailMessage | boolean | 收到的短信是否为电子邮件。 | 150| isReplaceMessage | boolean | 收到的短信是否为“替换短信”,默认为false。“替换短信”有关详细信息,参见 “3GPP TS 23.040 9.2.3.9”。 | 151| isSmsStatusReportMessage | boolean | 当前消息是否为“短信状态报告”,默认为false。“短信状态报告”是一种特定格式的短信,被用来从Service Center到Mobile Station传送状态报告。 | 152| messageClass | [ShortMessageClass](https://gitee.com/openharmony/telephony_sms_mms#section141712166453) | 短信类型。 | 153| pdu | Array\<number> | SMS消息中的协议数据单元 (PDU)。 | 154| protocolId | number | 发送短信时使用的协议标识。 | 155| scAddress | string | 短信服务中心(SMSC)地址。 | 156| scTimestamp | number | SMSC时间戳。 | 157| status | number | SMS-STATUS-REPORT消息中的短信状态指示短信服务中心(SMSC)发送的短信状态。 | 158| userRawData | Array\<number> | 除协议头部的用户数据,即未解码的短信内容。 | 159| visibleMessageBody | string | 短信正文。 | 160| visibleRawAddress | string | 发送者地址。 | 161 162**表 11** getDefaultSmsSimId接口参数说明 163 164| 参数 | 类型 | 描述 | 165| -------- | ---------------------- | ------------------------- | 166| callback | AsyncCallback\<number> | 回调函数。 | 167 168完整的JS API说明以及实例代码请参考:[收发短信](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-sms.md) 169 170## 使用说明<a name="section170mcpsimp"></a> 171 172### 发送短信<a name="section172mcpsimp"></a> 173 174以发送普通文本短信为例,主要步骤和代码如下: 175 1761. 构造SendMessageOptions对象,传入必要的参数;若关注发送结果或送达报告,需要传入sendCallback或deliveryCallback对象。 1772. 可以通过callback或者Promise的方式调用sendMessage接口。 1783. 该接口为异步接口,相关执行结果会从callback中返回。 179 180 ``` 181 import sms from "@ohos.telephony.sms"; 182 183 let msg: SendMessageOptions = { 184 slotId: 0, 185 destinationHost: '123xxxxxxxx', 186 content: '这是一封短信', 187 sendCallback: (err, data) => { 188 if (err) { 189 // 接口调用失败,err非空 190 console.error(`failed to send message because ${err.message}`); 191 return; 192 } 193 // 接口调用成功,err为空 194 console.log(`success to send message: ${data.result}`); 195 } 196 } 197 198 // 调用接口 199 sms.sendMessage(msg); 200 ``` 201 202 203### 创建ShortMessage对象<a name="section181mcpsimp"></a> 204 205以解析3gpp类型的PDU,调用createMessage为例,主要步骤和代码如下: 206 2071. 构造短信的PDU,指定协议类型为3gpp或者3gpp2。 2082. 可以通过callback或者Promise的方式调用createMessage接口。 2093. 该接口为异步接口,成功后获取ShortMessage 对象属性来得到解析后的短信息数据。 210 211 ``` 212 import sms from "@ohos.telephony.sms"; 213 214 let pdu = [80, 80, 80]; // 这里只是表示是短信PDU,并非真实短信 215 let specification = "3gpp"; 216 217 // 调用接口【callback方式】 218 sms.createMessage(pdu, specification, (err, value) => { 219 if (err) { 220 // 接口调用失败,err非空 221 console.error(`failed to createMessage because ${err.message}`); 222 return; 223 } 224 // 接口调用成功,err为空 225 console.log(`success to createMessage: ${value}`); 226 }); 227 228 // 调用接口【Promise方式】 229 let promise = sms.createMessage(pdu, specification); 230 promise.then((value) => { 231 // 接口调用成功,此处可以实现成功场景分支代码。 232 console.log(`success to createMessage: ${value}`); 233 }).catch((err) => { 234 // 接口调用失败,此处可以实现失败场景分支代码。 235 console.error(`failed to createMessage because ${err.message}`); 236 }); 237 ``` 238 239### 发送彩信<a name="section172mcpsimp"></a> 240 241以中国联通SIM卡发送彩信为例,主要步骤和代码如下: 242 2431. 发送彩信,需要先编码再发送。 2442. 编码:将多媒体文件编码成彩信pdu。app将多媒体文件放入沙箱,调用编码接口encodeMms,app传入必要参数,返回的彩信pdu需要app写入沙箱 2453. 发送:将彩信pdu发送到对端手机。调用发送接口sendMms,app需传入必要参数,彩信中心需和运营商卡匹配。 2464. 可以通过callback或者Promise的方式调用sendMessage接口。 2475. 该接口为异步接口,相关执行结果会从callback中返回。 248 249 ``` 250 import mms from "@ohos.telephony.sms"; 251 252 // 获取MmsType,输入本机号码,目的手机号码 253 async function getMmstype(tid){ 254 return { 255 from : {address: '+86xxxxxxxxxxx/TYPE=PLMN', charset: mms.UTF_8}, 256 to: [{address: '+86xxxxxxxxxxx/TYPE=PLMN', charset: mms.UTF_8}], 257 contentType: "application/vnd.wap.multipart.related", 258 transactionId: tid, 259 version: mms.MMS_VERSION_1_2, 260 subject: "Test mms" 261 }; 262 } 263 let MMSTYPE = await getMmstype("1"); 264 265 // 只包括图片附件,图片名字picture.gif 266 const ATTACHMENT_PICTURE = [ 267 {path: sandPath + 'picture.gif', 268 fileName: 'picture.gif', 269 contentId:'<picture.gif>', 270 contentLocation:'picture.gif', 271 contentDisposition: mms.ATTACHMENT, 272 contentTransferEncoding: 'binary', 273 contentType:'image/gif', 274 isSmil: false, 275 inBuff: [], 276 charset: mms.UTF_8 277 } 278 ]; 279 280 // 编码彩信pdu 281 const wrapperStepForEncodeMms = async function (mmsType, attachment) { 282 try { 283 // 调用编码接口 284 const encodeData = await mms.encodeMms({messageType: mms.TYPE_MMS_SEND_REQ, mmsType, attachment}); 285 console.log(`encodeMms Success, data length:${encodeData.length}`); 286 await writefd(casename, encodeData); 287 } catch (error) { 288 throw error; 289 } 290 }; 291 292 // 进行彩信pdu编码,编码前将图片放入沙箱 293 try { 294 await wrapperStepForEncodeMms(MMSTYPE, ATTACHMENT_PICTURE); 295 console.log(`wrapperStepForEncodeMms success.`); 296 } catch (error) { 297 console.log(`wrapperStepForEncodeMms fail, error: ${toString(error)}`); 298 return; 299 } 300 301 const sandBoxPath = '/data/storage/el2/base/files/'; 302 let filePath = sandBoxPath + 'SendReq.mms'; 303 // 彩信pdu写入沙箱 304 async function writefd(array){ 305 let data = new Uint8Array(array).buffer; 306 try { 307 let fd = await fileio.open(filePath , 0o102, 0o666); 308 console.log(`fd: ${toString(fd)}`); 309 const number = await fileio.write(fd, data); 310 console.log(`write data to file success number: ${toString(number)}`); 311 await fileio.close(fd); 312 } catch (error) { 313 console.log(`write data to file failed with error: ${toString(error)}`); 314 } 315 } 316 317 // 彩信用户代理、用户代理描述配置。根据运营商要求配置,默认ua,uaprof 318 let mmsCfg = { 319 userAgent:'ua', 320 userAgentProfile: 'uaprof' 321 }; 322 323 // 发送彩信参数 324 let mmsParams = { 325 slotId : DEFAULT_SLOTID, 326 mmsc: 'http://mmsc.myuni.com.cn', 327 data: filePath, 328 mmsConfig: mmsCfg 329 }; 330 // 调用发送接口 331 mms.sendMms(globalThis.context, mmsParams, async(err) =>{ 332 if (err) { 333 console.log(`sendMms fail, err : ${toString(err)}`); 334 return; 335 } 336 console.log(`sendMms Success`); 337 } 338 ``` 339 340## 相关仓<a name="section189mcpsimp"></a> 341 342[电话服务子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/电话服务子系统.md) 343 344**telephony_sms_mms** 345 346[telephony_core_service](https://gitee.com/openharmony/telephony_core_service/blob/master/README_zh.md) 347