WAP PUSH
Date | Ver | Description | Author | Reviewer |
2011-9-5 | 0.0.1 | Draft |
|
|
|
|
|
|
|
1. Wap Push简介:
Wap Push分为两种:SI(Server Initiate)和SL(Server Load),都是服务器端向客户端推送消息的一种方式。
SI流程:
服务器通过网关采用OTA协议把信息发送到手机,手机存储解析并存储信息,然后提示给用户。
SL流程:
在接收到SL消息后,同样也会存储并提示用户(视情况具体对待),区别在于客户端会主动调用浏览器打开SL中附带的连接。
修改前状况:
短信可以收到wap push数据,收到后短信发出广播,在原有的类WapPushOverSms对wap push数据进行了部分处理,去掉了transactionId(1byte)、pduType(1byte)和header(
2 byte),然后将pdu data发出,现在没有相对应的receiver接收,进行解析、存储信息和显示给用户的功能处理。
以下是短信接收的一个pdu的数据包:
pdu:
700601ae02056a0045c6080c0368647373316674622e666574696f6e2e636f6d2e636e
2f4844535f5330302f642e617370783f663d3339303035313235362532663130360001
03e79aaee79aaee59091e682a8e58f91e98081e4ba86e69687e4bbb6312e706e67efbc8c
e682a8e58fafe4bba5e782b9e587bbe4b88be99da2e79a84e993bee68ea5e4b88be8bdbd
e588b0e6898be69cbae38082000101
以下短信处理后漏给新添加的类WapPushReceiver的数据包:
Pdu:
02056a0045c6080c0368647373316674622e666574696f6e2e636f6d2e636e2f4844535
f5330302f642e617370783f663d333930303531323536253266313036000103e79aaee7
9aaee59091e682a8e58f91e98081e4ba86e69687e4bbb6312e706e67efbc8ce682a8e58fa
fe4bba5e782b9e587bbe4b88be99da2e79a84e993bee68ea5e4b88be8bdbde588b0e6898
be69cbae38082000101
进行修改目的:
现在没有接收wap push的receiver,所以添加了新类WapPushReceiver。如果不用的话需要修改其它的receiver接收,需要添加intent_filter
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
<data android:mimeType="application/vnd.wap.sic" />
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
<data android:mimeType="application/vnd.wap. slc" />
</intent-filter>
来接收wap push的广播。这里直接添加的新类WapPushReceiver,没有修改其他的receiver.
添加了类WapPushReceiver接收wap push数据,添加了类WapPushPduParser对wap push数据进行进一步的解析,存储,然后添加到短信中显示给用户。
下边是对改动内容的讲解:
2 .发出广播前需要进行的处理:
在包com.android.internal.telephony内原有的类WapPushOverSms是处理wap push的类,这个类中有public的方法dispatchWapPdu是用来分发广播的,其中调用了类SMSDispatcher的方法dispatch(Intent intent, String permission),指定了接收的intent(Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION))且要有"android.permission. RECEIVE_WAP_PUSH"这个权限,所以监听wap push的WapPushReceiver,需要有:
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
<data android:mimeType="application/vnd.wap.sic" />
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
<data android:mimeType="application/vnd.wap.slc" />
</intent-filter>
来监听wap push的intent,并且需要有监听wap push信息的权限:<uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />。
WapPushReceiver还需要有发出一个收到wap push信息的广播权限:
android:permission="android.permission.BROADCAST_WAP_PUSH">。
以下是代码中的修改:
监听wap push的WapPushReceiver添加权限是采取静态方式添加的:
1)采用静态方式在AndroidManifest.xml添加WapPushReceiver;
修改packages/apps/Mms/AndroidManifest.xml这个文件如下:
添加android.permission. RECEIVE_WAP_PUSH"这个权限:
<uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
2)添加一个接收wap push的recevier:
<receiver android:name=".transaction.WapPushReceiver"
android:permission="android.permission.BROADCAST_WAP_PUSH">
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
<data android:mimeType="application/vnd.wap.sic" />
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
<data android:mimeType="application/vnd.wap.slc" />
</intent-filter>
</receiver>
BROADCAST_WAP_PUSH:允许发出一个收到wap push信息的广播权限;
RECEIVE_WAP_PUSH:允许监听wap push信息;
3. wap push接收处理:
当有广播信息时,新添加类WapPushReceiver重载的方法onReceive会接收其wap push数据,通过WapPushReceiver的inten-filter判断是否是符合条件的wap push信息,符合条件的会创建一个异步Task进行处理。
异步task执行后,系统会调到重载doInBackground方法【我们重载这个方法的目的就是处理我们需要的wap push处理】,这个方法通过intent.getByteArrayExtra("data")获取pdu有效数据,然后创建了pushmessage的数据【这个数据是十六进制数据,是一个已经被短信处理过得数据】,让新添加的类WapPushPduParser对pdu进行解析,保存,然后在方法doInBackground中,通过sms.getDisplayMessageBody()获得解析后数据【这里获得是在解析完后的push数据,这个方法是短信中有的,不是新添加的】,由SqliteWrapper.insert添加到短信数据库中,通过MessagingNotification.blockingUpdateNewMessageIndicator(mContext, true, false)的第二个参数告诉当前是否是新的消息,然后由从短信中查看,显示给用户。当前是这么处理的。
以下是如何创建wap push的pdu数据包处理处理流程:
SmsMessage.createFromPduForPush |
Gsm.SmsMessage.createFromPushPdu |
SmsMessage.parsePushPdu |
WapPushPduParser.parse |
messageBody=content+url |
|
首先解析pdu数据包(parsePushPdu),数据包的具体解析在类WapPushPduParser的方法parse里进行解析的。解析分为检查wap push数据包头(通过checkHead实现),字符串处理(字符串以0x03开始,以0x00结束,字符串分为URL和Content两部分,分别由Token确定,如果字符串中以“0x0b~0x0F”开头,则说明是URL,否则为Content),Token处理(分为个别Token处理“0x45/SI,0xc6/Indication,0x01/end”,StartToken处理“0x05~0x12”和ValueToken处理“0x85~0x88”),处理完后URL和Content分别通过类WapPushPduParser的public方法getUrl和getContent获得。具体实现查看类WapPushPduParser,到这里实现了wap push数据包的解析。
目前不支持SL类的wap push实现。
Parse分别解析后只保留了pdu的链接url和文本信息content通过类WapPushPduParser的方法getUrl和getContent赋给messageBody,由values.put(Inbox.BODY, sms.getDisplayMessageBody())添加到短信库中,实现了wap push数据的存储。
在短信库中添加完wap push数据信息后,通过方法MessagingNotification.blockingUpdateNewMessageIndicator(mContext, true, false)在重载方法doInBackground处理中设置了状态栏来新消息的通知。第二个参数为是否新消息的判断,如果是新消息就是true,否则false。
在短信界面处理的原有类ComposeMessageActivity的方法initMessageList注册了OnItemClickListener,当在视图中作有click事件时,会作onMessageListItemClick处理,在onMessageListItemClick处理中MessageUtils.extractUris(spans)中获取了短信中的不同格式的字符串,其中包含URL格式的字符串,URL字符串就获取出来了,通过startActivity(intent)启动browser。
以下是解析时Token值对应表:
action | signal-none | 5 |
action | signal-low | 6 |
action | signal-medium | 7 |
action | signal-high | 8 |
action | delete | 9 |
created |
| A |
href |
| B |
href | http:// | C |
href | http://www. | D |
href | https:// | E |
href | https://www. | F |
si-expires |
| 10 |
si-id |
| 11 |
class |
| 12 |
| .com/ | 85 |
| .edu/ | 86 |
| .net/ | 87 |
| .org/ | 88 |
Wap push数据包的一个例子:
主要参考资料wap-167-serviceind-20010731-a.pdf。