Android中WAP PUSH的实现分析
来源:互联网 发布:win10登录界面域名 编辑:程序博客网 时间:2024/06/05 04:25
转自:http://dev.10086.cn/cmdn/wiki/index.php?doc-view-5371.html
1 WAP PUSH 流程简介 WAP Push分为两种:SI(Service Initiate) 和SL(Service Load)。都是服务器端向客户端推送消息的一种方式。 SI是服务器通过网关采用OTA协议把信息发送到手机,手机存储解析并存储信息,然后提示给用户。 在接收到SL消息后,同样也会存储并提示用户(视情况具体对待),区别在于客户端会主动调用浏览器打开SL中附带的连接。 2 WAP PUSH消息体剖析 下面我们以SL为例,来看看WAP PUSH的消息。 一个SL的WAP PUSH消息主体大致如下: < !-- Service Loading (SL) Document Type Definition. SL is an XML language. Typical usage: < ?xml version="1.0"?> < !DOCTYPE sl PUBLIC "-//WAPFORUM//DTD SL 1.0//EN" "http://www.wapforum.org/DTD/sl.dtd"> < sl> href %URI; #REQUIRED action (execute-low|execute-high|cache) "execute-low" < /sl> 大家都看到了,其实内容很少,包括一个连接和一个action控制执行的优先级。 由于考虑到节约网络数据的传输,往往都是将这些文本转化为WBXML格式再进行传输。WBXML是一种压缩的二进制表示方式,有严格的定义。对于标签和属性,定义如下表: Tag Name Token sl 5 Attribute Name Attribute Value Prefix Token action execute-low 5 action execute-high 6 action cache 7 href 8 href http:// 9 href http://www. A href https:// B href https://www. C Attribute Value Token .com/ 85 .edu/ 86 .net/ 87 .org/ 88 文本中的对应Tag和Attribute value会被Token代替,以减少文本大小。我们看下面一段内容: < ?xml version="1.0"?> < !DOCTYPE sl PUBLIC "-//WAPFORUM//DTD SL 1.0//EN" "http://www.wapforum.org/DTD/sl.dtd"> < sl href="http://www.xyz.com/ppaid/123/abc.wml">< /sl> 总共有159个字节。 我们使用WBXML格式来表示,如下表对应关系: Token Stream Description 02 Version number - WBXML version 1.2 06 SL 1.0 Public Identifier 6A Charset=UTF-8 (MIBEnum 106) 00 String table length 05 sl, with attributes 0A Token for "href="http://www." 03 Inline string follows ‘x’, ‘y’, ‘z’, 00 String 85 Token for ".com/" 03 Inline string follows ‘p’, ‘p’, ‘a’, ‘i’, ‘d’, ‘/’, ‘1’, ‘2’, ‘3’, ‘/’, ‘a’, ‘b’, ‘c’, ‘.’, ‘w’, ‘m’, ‘l’, 00 String 01 END (of sl attribute list) 这样一来,就是: 02 06 6A 00 05 0A 03 'x' 'y' 'z' 00 85 03 'p' 'p' 'a' 'i' 'd' '/' '1' '2' '3' '/' 'a' 'b' 'c' '.' 'w' 'm' 'l' 00 01 总共才需要32个字节, 大大减少了数据量。 以上的只是消息主体内容,在传输过来的时候,还需要加上一些附加的信息,如 mimeType: 表示是SI还是SL, application/vnd.wap.sic或者 application/vnd.wap.slc (text/vnd.wap.sl). transactionId: 用于分段发送大数据量的消息, 这些消息具有相同的trasactionId. pduType: 未识别 header: 附加信息,用于标示特定的业务。 3 Android中解析WAP PUSH 按照以上所述,网络传输过来的是WBXML数据,通常我们需要按照Token表对应的进行解析,才可以得到XML格式的正文,从而获取href和 action。 庆幸的是Android中在framework层的WapPushOverSms.Java中已经完成了对消息的部分解析,把mimeType, trasactionId, pduType, header 和 data分离出来,放在intent的传递参数中了。看以下代码: private void dispatchWapPdu_PushCO(byte[] pdu, int transactionId, int pduType, int headerStartIndex, int headerLength) { byte[] header = new byte[headerLength]; System.arraycopy(pdu, headerStartIndex, header, 0, header.length); Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION); intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO); intent.putExtra("transactionId", transactionId); intent.putExtra("pduType", pduType); intent.putExtra("header", header); intent.putExtra("data", pdu); mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_WAP_PUSH"); } 我们在应用层只需要添加对WAP_PUSH_RECEIVED_ACTION的监听,便可获取到这个WAP PUSH。 下面以接收中国移动DCD业务的WAP PUSH为例,看看是如何实现的。 需要写一个DcdWapPushReceiver.java: public class DcdWapPushReceiver extends BroadcastReceiver { private static final String LOGTAG = "DcdPushReceiver"; public static final String CONTENT_MIME_TYPE_B_PUSH_SL = "application/vnd.wap.slc"; public static final String APPLICATION_DCD_ID = "application/x-oma-DCD:DCD.ua"; public void onReceive(Context context, Intent intent) { //only deal with SL WAP PUSH if (intent.getAction().equals(WAP_PUSH_RECEIVED_ACTION) && CONTENT_MIME_TYPE_B_PUSH_SL.equals(intent.getType())) { // Start a new AsyncTask to process the data. if (APPLICATION_DCD_ID.equals(getAppIdFromIntent(intent))) { new ReceivePushTask(context).execute(intent); } } } /* * get application id from intent header. * < ==header sample==> * B0 B4 87 AF application/x-oma-DCD:DCD.ua 00 Encoding-Version 00 */ public static String getAppIdFromIntent(Intent intent) { byte[] header = intent.getByteArrayExtra("header"); if (header == null) { return null; } String str = new String(header); int start = str.indexOf("application/"); if (start > 0) { //application id end with 00. int end = str.indexOf(0x00); if (end > 0) { str = str.substring(start, end); return str; } } return null; } private class ReceivePushTask extends AsyncTask< Intent, Void, Void> { private Context mContext; public ReceivePushTask(Context context) { mContext = context; } protected Void doInBackground(Intent... intents) { Intent intent = intents[0]; // step1. obtain wbxml data from intent. byte[] pushData = intent.getByteArrayExtra("data"); String wbxmlData = ""; for (byte by: pushData) { wbxmlData = wbxmlData + by + " "; } Debug.print("wap push data = "+wbxmlData); // step2. pass the data to WapPushParser and get the parsing result. DcdWapPushParser parser = new DcdWapPushParser(pushData); DcdWapPushMsg pushMsg = null; if (CONTENT_MIME_TYPE_B_PUSH_SL.equals(intent.getType())) { pushMsg = parser.parse(DcdWapPushMsg.WAP_PUSH_TYPE_SL); } if (null == pushMsg) { Debug.error("Invalid WAP PUSH data"); return null; } //get href String href = pushMsg.getAttributeValueString(DcdWapPushMsg.WAP_PUSH_PROJECTION_HREF); Debug.print("href = " + href); Intent i = new Intent(mContext, DcdCmService.class); //step3. sync invoked by wap push, so set sync type to SVR //i.putExtra("syncType", DcdCmService.SYNC_TYPE_SVR); //i.putExtra("href", href); Bundle bundle = new Bundle(); bundle.putBoolean(DcdCmService.NOTIFICATION_WAPPUSH, true); bundle.putString("syncType", DcdRequest.REQUEST_TYPE_SVR); bundle.putString("href", href); i.putExtras(bundle); //start sync service mContext.startService(i); return null; } } } 在AndroidManifest.xml中注册这个接收器: < receiver android:name=".contentmanager.DcdWapPushReceiver"> < intent-filter> < action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" /> < data android:mimeType="application/vnd.wap.slc" /> < /intent-filter> < /receiver>
- Android中WAP PUSH的实现分析
- Android中WAP PUSH的实现分析
- Android中WAP PUSH的实现分析
- Android中WAP PUSH的实现分析
- android wap push实现
- WAP PUSH解析(3)——Android中实现
- WAP PUSH解析(3)——Android中实现
- WAP PUSH解析(3)——Android中实现
- WAP PUSH解析(3)——Android中实现
- Android 短信 彩信 wap push的接收
- Android 短信 彩信 wap push的接收
- .net实现WAP PUSH
- Wap push点对点短消息通知模式的实现
- sms实现wap push的方法和格式
- Wap Push的各类代码
- Android代码中实现WAP方式联网
- Android代码中实现WAP方式联网
- Android代码中实现WAP方式联网
- 下拉框树
- onresize 多次触发及其解决办法
- iterator与const_iterator
- 拷贝构造函数与赋值构造函数(operator=)之区别
- Archlinux Eclipse 崩溃问题解决
- Android中WAP PUSH的实现分析
- 用户并发数计算
- 单链表的基本操作实现
- 块编程指南
- Visitor (C++实现)
- Win32应用程序中进程间通信方法分析与比较
- 正则表达式
- VuGen中的web动作函数
- WEB性能测试用例设计