短信发送流程图形剖析(含编码)Android平台
更新时间:2024-04-28 10:22:01 阅读量: 综合文库 文档下载
- 网络短信发送流程推荐度:
- 相关推荐
Android平台 短信发送流程图形剖析(含编码)
转自:http://lzd20021683.iteye.com/blog/1306918
其他SMS/MMS分析:http://lzd20021683.iteye.com/category/187047
本文对Android平台短信发送流程进行了走读和剖析,特别是编码部分,今天将流程整理出来,以便平时参考,也希望对大家有用!!!
先上图,下面2个图是用PPT画的,这里截图附上来:
流程图1:
Framewoks
流程图2:
发送流程编码解析:
从上图中的GsmSMSDispatcher的sendText开始分析
Java代码 1. //GsmSMSDispatcher.java 2. /** {@inheritDoc} */ 3. @Override 4. // ①入口
5. protected void sendText(String destAddr, String scAddr, String text, 6. PendingIntent sentIntent, PendingIntent deliveryIntent) { 7. SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu ( //转②分析 8. scAddr, destAddr, text, (deliveryIntent != null));
9. 10. HashMap map = SmsTrackerMapFactory(destAddr, scAddr, text, pdu); 11. SmsTracker tracker = SmsTrackerFactory(map, sentIntent, deliveryIntent, 12. RadioTechnologyFamily.RADIO_TECH_3GPP); 13. sendRawPdu(tracker); //转I分析
14. }
15. 16. ②分析:
17. //SmsMessage.java
18. public static SubmitPdu getSubmitPdu(String scAddress, 19. String destinationAddress, String message, 20. boolean statusReportRequested) {
21. return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested, null); //转③分
析 22. }
23. 24. ③分析
25. //SmsMessage.java
26. public static SubmitPdu getSubmitPdu(String scAddress, 27. String destinationAddress, String message, 28. boolean statusReportRequested, byte[] header) {
29. return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested, header,ENCODIN
G_UNKNOWN/*默认编码方式*/); //转④分析 30. }
31. 32. ④分析 编码核心函数
33. //SmsMessage.java
34. public static SubmitPdu getSubmitPdu(String scAddress, 35. String destinationAddress, String message,
36. boolean statusReportRequested, byte[] header, int encoding) { 37. // 3
38. // Perform null parameter checks.
39. if (message == null || destinationAddress == null) { 40. return null; 41. }
42. 43. SubmitPdu ret = new SubmitPdu(); 44. // MTI = SMS-SUBMIT, UDHI = header != null 45. byte mtiByte = (byte)(0x01 | (header != null ? 0x40 : 0x00));
46. //MTI :bit 0 和 bit1 UDHI:bit6
47. // 0x01 = 0000 0001 0x40 = 0010 0000 48. ByteArrayOutputStream bo = getSubmitPduHead( 49. scAddress, destinationAddress, mtiByte, 50. statusReportRequested, ret); //转⑤分析 51. // User Data (and length) //TP-DCS 和TP-UDL 52. byte[] userData;
53. if (encoding == ENCODING_UNKNOWN) {
54. // First, try encoding it with the GSM alphabet
55. encoding = ENCODING_7BIT; //默认先采用ENCODING_7BIT编码模式 56. } 57. try {
58. if (encoding == ENCODING_7BIT) {
59. userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, header);
60. //采用ENCODING_7BIT进行编码,若出现编码异常,函数会抛出异常:EncodeException,转至⑥处。编码成功转
至⑦。stringToGsm7BitPackedWithHeader分析转⑧处 61. } else { //assume UCS-2 62. try {
63. userData = encodeUCS2(message, header); 64. } catch(UnsupportedEncodingException uex) { 65. Log.e(LOG_TAG,
66. \, 67. uex); 68. return null; 69. } 70. }
71. } catch (EncodeException ex) { //⑥ 7bit编码模式失败后,就采用UCS-2进行编码 72. // Encoding to the 7-bit alphabet failed. Let's see if we can 73. // send it as a UCS-2 encoded message 74. try {
75. userData = encodeUCS2(message, header); 76. encoding = ENCODING_16BIT;
77. } catch(UnsupportedEncodingException uex) { 78. Log.e(LOG_TAG,
79. \, 80. uex); 81. return null; 82. } 83. }
84. 85. if (encoding == ENCODING_7BIT) { //⑦ 7bit编码成功 86. if ((0xff & userData[0]) > MAX_USER_DATA_SEPTETS) { 87. // Message too long 88. return null; 89. } 90. // TP-Data-Coding-Scheme 91. // Default encoding, uncompressed 92. // To test writing messages to the SIM card, change this value 0x00 93. // to 0x12, which means \ 94. // class is 2\ 95. // words, messages sent by the phone with this change will end up on 96. // the receiver's SIM card. You can then send messages to yourself 97. // (on a phone with this change) and they'll end up on the SIM card.
98. //0x12 = 0001 0010 未压缩,class2,存储到SIM卡 99. //0x00 = 0000 0000 未压缩,class0,GSM7bit编码 100. bo.write(0x00); 101. } else { // assume UCS-2
102. if ((0xff & userData[0]) > MAX_USER_DATA_BYTES) { 103. // Message too long 104. return null; 105. }
106. // TP-Data-Coding-Scheme
107. // Class 3, UCS-2 encoding, uncompressed
108. bo.write(0x0b); //0x0b = 0000 1011 未压缩,class3,UCS-2编码 109. }
110.
111. // (no TP-Validity-Period)
112. bo.write(userData, 0, userData.length); 113. ret.encodedMessage = bo.toByteArray(); 114. return ret; 115. } 116. 117. ⑤分析
118. //SmsMessage.java
119. private static ByteArrayOutputStream getSubmitPduHead(
120. String scAddress, String destinationAddress, byte mtiByte, 121. boolean statusReportRequested, SubmitPdu ret) 122. //scAddress为短信中心号码,destinationAddress为目标地址号码
123. //mtiByte为MTI和UDHI 编码数据,见上面分析,statusReportRequested为状态报告 //ret 下面会写入数据
到ret 124. {
125. ByteArrayOutputStream bo = new ByteArrayOutputStream( 126. MAX_USER_DATA_BYTES + 40);
127.
128. // SMSC address with length octet, or 0 129. if (scAddress == null) {
130. ret.encodedScAddress = null; 131. } else {
132. ret.encodedScAddress = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength(
133. scAddress); 134. }
135. // TP-Message-Type-Indicator (and friends) 136. if (statusReportRequested) {
137. // Set TP-Status-Report-Request bit. //TP-SRR bit 5 ,0x20 = 0010 0000 138. mtiByte |= 0x20;
139. if (Config.LOGD) Log.d(LOG_TAG, \); 140. }
141. bo.write(mtiByte);
142.
143. // space for TP-Message-Reference //TP-MR 144. bo.write(0); 145.
146. byte[] daBytes; 147.
148. daBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(destinationAddress); 149.
150. // destination address length in BCD digits, ignoring TON byte and pad
151. // TODO Should be better. 152. bo.write((daBytes.length - 1) * 2
153. - ((daBytes[daBytes.length - 1] & 0xf0) == 0xf0 ? 1 : 0));
154.
155. // destination address
156. bo.write(daBytes, 0, daBytes.length); 157.
158. // TP-Protocol-Identifier //TP--PID 159. bo.write(0); 160. return bo; 161. } 162. 163. ⑧分析
164. //GsmAlphabet.java
165. public static byte[] stringToGsm7BitPackedWithHeader(String data, byte[] header) 166. throws EncodeException { //这里传进来的head为null
167.
168. if (header == null || header.length == 0) {
169. return stringToGsm7BitPacked(data); //转⑨分析 170. } 171.
172. int headerBits = (header.length + 1) * 8; 173. int headerSeptets = (headerBits + 6) / 7; 174.
175. byte[] ret = stringToGsm7BitPacked(data, headerSeptets, true); 176.
177. // Paste in the header
178. ret[1] = (byte)header.length;
179. System.arraycopy(header, 0, ret, 2, header.length); 180. return ret; 181. } 182. 183. ⑨分析
184. //GsmAlphabet.java
185. public static byte[] stringToGsm7BitPacked(String data) 186. throws EncodeException {
187. return stringToGsm7BitPacked(data, 0, true); //转⑩分析 188. }
189. 190. ⑩分析
191. //GsmAlphabet.java
192. public static byte[] stringToGsm7BitPacked(String data, int startingSeptetOffset, 193. boolean throwException) throws EncodeException { 194. int dataLen = data.length();
195. int septetCount = countGsmSeptets(data, throwException) + startingSeptetOffset; 196. // 当传入的字符串data中含有charToGsm, charToGsmExtended中没有的字符时(例如汉字),该函数会抛出异
常,这样在调用处⑥会捕获该异常。然后会采用UCS-2方式进行编码。
197.
198. if (septetCount > 255) {
199. throw new EncodeException(\); 200. }
201. int byteCount = ((septetCount * 7) + 7) / 8;
202. byte[] ret = new byte[byteCount + 1]; // Include space for one byte length prefix. 203. for (int i = 0, septets = startingSeptetOffset, bitOffset = startingSeptetOffset * 7; 204. i < dataLen && septets < septetCount; 205. i++, bitOffset += 7) { 206. char c = data.charAt(i);
207. int v = GsmAlphabet.charToGsm(c, throwException); 208. if (v == GSM_EXTENDED_ESCAPE) {
209. v = GsmAlphabet.charToGsmExtended(c); // Lookup the extended char. 210. packSmsChar(ret, bitOffset, GSM_EXTENDED_ESCAPE); 211. bitOffset += 7; 212. septets++; 213. }
214. packSmsChar(ret, bitOffset, v); 215. septets++; 216. }
217. ret[0] = (byte) (septetCount); // Validated by check above. 218. return ret;
219. }
220.
221. I分析:
222. //SMSDispatcher.java
223. protected void sendRawPdu(SmsTracker tracker) { 224. HashMap map = tracker.mData;
225. byte pdu[] = (byte[]) map.get(\);
226.
227. PendingIntent sentIntent = tracker.mSentIntent; 228. if (mSmsSendDisabled) {
229. if (sentIntent != null) { 230. try {
231. sentIntent.send(RESULT_ERROR_NO_SERVICE); 232. } catch (CanceledException ex) {} 233. }
234. Log.d(TAG, \); 235. return; 236. } 237.
238. if (pdu == null) {
239. if (sentIntent != null) { 240. try {
241. sentIntent.send(RESULT_ERROR_NULL_PDU); 242. } catch (CanceledException ex) {} 243. }
244. return; 245. }
246.
247. int ss = mPhone.getServiceState().getState(); 248.
249. // if IMS not registered on data and voice is not available... 250. if (!isIms() && ss != ServiceState.STATE_IN_SERVICE) { 251. handleNotInService(ss, tracker); 252. } else {
253. String appName = getAppNameByIntent(sentIntent); 254. if (mCounter.check(appName, SINGLE_PART_SMS)) { 255. sendSms(tracker); // 转II分析 256. } else {
257. sendMessage(obtainMessage(EVENT_POST_ALERT, tracker)); 258. } 259. } 260. } 261.
262. II分析:
263. //GsmSMSDispatcher.java 264. /** {@inheritDoc} */ 265. @Override
266. protected void sendSms(SmsTracker tracker) { 267. HashMap
268.
269. byte smsc[] = (byte[]) map.get(\); 270. byte pdu[] = (byte[]) map.get(\); 271.
272. Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker); 273.
274. if (tracker.mRetryCount > 0 || !isIms()) { 275. // this is retry, use old method
276. mCm.sendSMS(IccUtils.bytesToHexString(smsc),
277. IccUtils.bytesToHexString(pdu), reply); 278. } else {
279. mCm.sendImsGsmSms(IccUtils.bytesToHexString(smsc), 280. IccUtils.bytesToHexString(pdu), reply); 281. } 282. }
正在阅读:
深圳地铁轨道维修规程 - 图文01-30
100首训练口才的绕口令07-30
杰克琼斯调研报告正式版08-28
中国现代文学史 点12-17
感恩工作,一路前行 - 与新老员工共勉04-22
上市公司独立董事制度的思考08-13
07动植物检疫专业综合技能测试与训练07-18
徐州市人力资源和社会保障局关于印发《徐州市工伤康复管理试行办04-07
少年宫活动记录—德育类—经典诵读09-16
- 计算机试题
- 【2012天津卷高考满分作文】鱼心人不知
- 教育心理学历年真题及答案--浙江教师资格考试
- 20180327-第六届“中金所杯”全国大学生金融知识大赛参考题库
- 洪林兴达煤矿2018年度水情水害预测预报
- 基本要道讲义
- 机电设备安装试运行异常现象分析与对策
- 《有机化学》复习资料-李月明
- 非常可乐非常MC2--非常可乐广告策划提案 - 图文
- 2011中考数学真题解析4 - 科学记数法(含答案)
- 企业人力资源管理师三级07- 09年真题及答案
- 基于单片机的光控自动窗帘控制系统设计说明书1 - 图文
- 20160802神华九江输煤皮带机安装方案001
- (共53套)新人教版一生物必修2(全册)教案汇总 word打印版
- 2014行政管理学总复习
- 中国银监会关于加强地方政府融资平台贷款风险监管的指导意见
- 民宿酒店核心竞争与研究
- 游园活动谜语大全2012
- 河南省天一大联考2016届高三英语5月阶段性测试试题(六)(A卷)
- 小型超市管理系统毕业论文详细设计4
- 短信发送
- 剖析
- 图形
- 编码
- 流程
- Android
- 平台
- 外国近代学前教育
- 排球选项课理论作业(2014第2学期用)田qing
- 河工大版编译原理实验报告
- 《Windows Server 2008网络组建》试卷D
- 环境、职业健康安全合规性评价报告
- 天秤座的男性和狮子座的女性
- 人教版小学语文《狮子和鹿》教案设计2)
- 让都巴惊魂记
- 马克思主义基本原理概论第一章选择题(附答案)
- 生物安全手册检验科
- 权力的定义、起源、性质、利弊
- 2010年高中物理复合场问题分类精析
- 创业创新执行力期末考试尔雅
- 建环实验指导书汇总2011.7.7
- 2013年吉林省政法干警考试行测:并列文段结构性分析(下)
- 初中英语牛津深圳版《九年级全册》Chapter 7 The Phantom of the
- 特殊教育学校教育教学改革推进策略
- 第五届数学大奖赛小论文题目
- ANSYS学习方法汇总
- 行政执法人员考试题库及答案