`
seya
  • 浏览: 361549 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Android浏览器Browser二次开发(二)支持WML

阅读更多
第二章 修改浏览器使之支持WML格式页面。
对于移动终端,有时候服务器返回的是WML格式的页面。 比如说中国移动的一些需要使用cmwap接入点的业务页面(DCD, 移动梦网…), 这就要求终端浏览器必须能够支持对WML格式页面的解析和显示。 Android原始代码里的webkit层虽然提供了WML相关的解析类,但是并没有很好地支持,所以在页面上无法正确显示。 我们需要做以下一些修改:
1. 打开对WML格式解析的通道
修改源码的\external\webkit\WebCore\dom\DOMImplementation.cpp
获取到服务器返回的数据中的content-type字段值后,会调用这个类里面的isXMLMIMEType()方法来判断是否按照XML格式来解析。我们看这个方法:
bool DOMImplementation::isXMLMIMEType(const String& mimeType)
{
if (mimeType == "text/xml" || mimeType == "application/xml" || mimeType == "text/xsl")
return true;
static const char* const validChars = "[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]"; // per RFCs: 3023, 2045
DEFINE_STATIC_LOCAL(RegularExpression, xmlTypeRegExp, (String("^") + validChars + "+/" + validChars + "+\\+xml$", TextCaseSensitive));
return xmlTypeRegExp.match(mimeType) > -1;
}
这里只包含了text/xml, application/xml, text/xls. 我们需要把WML相应的MiMeType类型加进去
If(mimeType == “text/vnd.wap.wml”) return true;

修改framework/base/core/java/android/webkit/LoadListener.java, 源码如下:
// Does the header parsing work on the WebCore thread.
private void handleHeaders(Headers headers) {

} else if (mMimeType.equals("text/vnd.wap.wml")) {
// As we don't support wml, render it as plain text
mMimeType = "text/plain";

}
我们可以看到, 原来是不支持wml格式的, 都当做text/plain来处理了,这样显然是不能正确显示的。 所以这一行mMimeType = "text/plain";需要注释掉,打开给外围。
2. 对WML中的超链接元素(WMLAElement和WMLAnchorElement)中href属性值里面的变量替换。
笔者发现,在一个WML的登陆页面上,填入用户名和密码后,点击登陆,附加到url后面的用户名和密码是$(username) 和$(password) ,有web开发经验的XDJM都知道,这是没有将变量替换为页面上相应值。我们看WMLAElement.cpp中处理点击事件的方法:
void WMLAElement::defaultEventHandler(Event* event)
{
if (isLink() && (event->type() == eventNames().clickEvent || (event->type() == eventNames().keydownEvent && focused()))) {
MouseEvent* e = 0;
if (event->type() == eventNames().clickEvent && event->isMouseEvent())
e = static_cast<MouseEvent*>(event);

KeyboardEvent* k = 0;
if (event->type() == eventNames().keydownEvent && event->isKeyboardEvent())
k = static_cast<KeyboardEvent*>(event);

if (e && e->button() == RightButton) {
WMLElement::defaultEventHandler(event);
return;
}

if (k) {
if (k->keyIdentifier() != "Enter") {
WMLElement::defaultEventHandler(event);
return;
}

event->setDefaultHandled();
dispatchSimulatedClick(event);
return;
}

if (!event->defaultPrevented() && document()->frame()) {
String url = document()->completeURL(deprecatedParseURL(getAttribute(HTMLNames::hrefAttr)));
/
document()->frame()->loader()->urlSelected(url, target(), event, false, false, true, SendReferrer);
}

event->setDefaultHandled();
}

WMLElement::defaultEventHandler(event);
通过打印Log发现,getAttribute(HTMLNames::hrefAttr)获取的只是href后面的字符串,包含变量$(). 我们需要对其中的变量进行转化。还好WMLVariables里面已经提供了相应的方法substituteVariableReferences,不需要我们再去写一个了。修改如下
#include "WMLVariables.h"
。。。
if (!event->defaultPrevented() && document()->frame()) {
// Substitute variables within target url attribute value. String href = getAttribute(HTMLNames::hrefAttr);
href = substituteVariableReferences(href, document(), WMLVariableEscapingEscape);
String url = document()->completeURL(deprecatedParseURL(href));
document()->frame()->loader()->urlSelected(url, target(), event, false, false, true, SendReferrer);
}

别忘了,WMLAnchorElement.cpp中相应的地方也要同样改掉。
3. 在页面上长按链接时弹出选项点击失效
这是由于点击时是从webkit层去获取这个链接的地址和标题的, 而源码中只考虑了HTML格式的页面, WML页面被忽略了。 返回的href为null.
首先要在WMLAElement.cpp中提供接口, 返回链接。
KURL WMLAElement::href() const
{
// Substitute variables within target url attribute value.
String href = substituteVariableReferences(getAttribute(HTMLNames::hrefAttr),
document(), WMLVariableEscapingEscape);
return document()->completeURL(href);
}
由于WMLAnchorElement继承了WMLAElement, 就不需要再添加这个方法了。
然后修改WebViewCore.cpp, 原来获取href的方法是这样的:
WebCore::String WebViewCore::retrieveHref(WebCore::Frame* frame, WebCore::Node* node)
{
WebCore::HTMLAnchorElement* anchor = retrieveAnchorElement(frame, node);
return anchor ? anchor->href() : WebCore::String();
}
在这里增加WML的支持, 修改如下:
/**add WML anchor support. 20110224, begin**/
#if ENABLE(WML)
WebCore::WMLAnchorElement* WebViewCore::retrieveWMLAElement(WebCore::Frame* frame, WebCore::Node* node)
{
if (!CacheBuilder::validNode(m_mainFrame, frame, node))
return 0;
if (!node->hasTagName(WebCore::WMLNames::aTag))
return 0;
return static_cast<WebCore::WMLAnchorElement*>(node);
}
#endif
/**add WML anchor support 20110224, end**/

WebCore::String WebViewCore::retrieveHref(WebCore::Frame* frame, WebCore::Node* node)
{
/**retrieve WMLAnchor element. 20110224, begin**/
#if ENABLE(WML)
if (node->isWMLElement()) {
WebCore::WMLAnchorElement* anchor = retrieveWMLAElement(frame, node);
return anchor ? anchor->href() : WebCore::String();
}
#endif
/**retrieve WMLAnchor element. 20110224, end**/
WebCore::HTMLAnchorElement* anchor = retrieveAnchorElement(frame, node);
return anchor ? anchor->href() : WebCore::String();
}
还有获取链接标题的方法,修改如下:
WebCore::String WebViewCore::retrieveAnchorText(WebCore::Frame* frame, WebCore::Node* node)
{
/**retrieve WMLAnchor element. 20110224, begin**/
#if ENABLE(WML)
if (node->isWMLElement()) {
WebCore::WMLAnchorElement* anchor = retrieveWMLAElement(frame, node);
return anchor ? anchor->title() : WebCore::String();
}
#endif
/**retrieve WMLAnchor element. 20110224, end**/
WebCore::HTMLAnchorElement* anchor = retrieveAnchorElement(frame, node);
return anchor ? anchor->text() : WebCore::String();
}
4. 移动梦网无法正确显示,解析出错。
移动梦网返回的数据格式为application/vnd.wap.xhtml+xml, 包含了xhtml和xml两种格式。而CMCC的数据本身又不是严格按照W3C标准来的, 导致在解析的时候出现了语法错误提示。 对于这种情况,我们显然无法去要求CMCC改变数据, 只能把这种格式当做普通的html来显示, html没有那么严格的语法检查, 可以正常显示。修改framework/base/core/java/android/webkit/LoadListener.java:
// Does the header parsing work on the WebCore thread.
private void handleHeaders(Headers headers) {
。。。
String contentType = headers.getContentType();
if (contentType != null) {
parseContentTypeHeader(contentType);

// If we have one of "generic" MIME types, try to deduce
// the right MIME type from the file extension (if any):
if (mMimeType.equals("text/plain") ||
mMimeType.equals("application/octet-stream")) {

// for attachment, use the filename in the Content-Disposition
// to guess the mimetype
String contentDisposition = headers.getContentDisposition();
String url = null;
if (contentDisposition != null) {
url = URLUtil.parseContentDisposition(contentDisposition);
}
if (url == null) {
url = mUrl;
}
String newMimeType = guessMimeTypeFromExtension(url);
if (newMimeType != null) {
mMimeType = newMimeType;
}
} else if (mMimeType.equals("text/vnd.wap.wml")) {
// As we don't support wml, render it as plain text
// mMimeType = "text/plain";
} else {
// It seems that xhtml+xml and vnd.wap.xhtml+xml mime
// subtypes are used interchangeably. So treat them the same.


//if (mMimeType.equals("application/vnd.wap.xhtml+xml")) {
// mMimeType = "application/xhtml+xml";
//}
/* Webkit used libxml2 as the xml parser, but the CMCC's WAP sites
written in WML or XHTML do not meet W3C's specification well,
and libxml2 will throw a lot of grammatical errors when it parses
the document which has the mime type is "application/xhtml+xml" or
"application/vnd.wap.xhtml+xml". When i opened the macro named
"XHTMLMP" in config.h in webcore and tested, i found some bugs,
i believed that Google did not do detail test works for this macro.
So i could handle "XHTML" mime type as "HTML" only in order to
open CMCC's WAP sites in browser.
*/

if (mMimeType.equals("application/vnd.wap.xhtml+xml") ||
mMimeType.equals("application/xhtml+xml"))
{
mMimeType = "text/html";
}

分享到:
评论
6 楼 a2825220 2012-02-13  
seya 写道
a2825220 写道
好文章,谢谢seya!


一点皮毛, 分享一下而已。 目前正在做音视频通话。


呵呵,只是和你做过同样的事情,没有你总结的好;我一直在做WebKit方面,音视频我这边做过浏览器对HTML5的video和audio标签的支持
5 楼 seya 2012-02-13  
a2825220 写道
好文章,谢谢seya!


一点皮毛, 分享一下而已。 目前正在做音视频通话。
4 楼 a2825220 2012-02-09  
好文章,谢谢seya!
3 楼 a2825220 2012-02-09  
2楼的是说WML的input标签不支持中文输入法吧,这个我改过,修改的地方比较多,建议你可以参见HTML的input标签是怎么支持输入中文的,然后将wml的input跟它走同一条路。
2 楼 yocaishen 2012-02-05  
Dear seya:
     现在打开支持WML格式,但现在遇到了一个比较棘手的问题。就是在input编辑框中,无法输入中文,英文是可以输入的,请问你有遇到这个问题吗?
      如果不方便透露具体的文件,也可简单提点一下小弟,谢谢?
1 楼 yqlxj2 2011-03-15  
seya,你好,
      ENABLE_XML宏打开之后报了很多错误,是否有其他修改方式,或者如何解决这些错误?

相关推荐

    手机网页浏览器 Wap浏览器 wml浏览器

    早期的诺基亚、摩托罗拉等手机中常见的Opera Mini、UCWeb等浏览器都支持WML页面。这些浏览器通常具有节省流量、快速加载的特点,因为WAP技术通过压缩数据并优化传输方式来提高效率。 随着3G、4G网络的普及以及HTML5...

    支持WML的浏览器,可以进行手机上网~!支持HTTP协议!

    "MRP的WML的编辑"可能指的是该浏览器还具备MRP(Mobile Runtime Platform)相关的WML编辑功能,MRP是一种为移动设备开发应用的平台,这暗示了该浏览器可能包含了一些针对手机游戏或应用的特定支持。 综合来看,这个...

    wml浏览器(支持wap1.2).rar

    标题中的“wml浏览器(支持wap1.2)”指的是一个专为浏览WML(Wireless Markup Language)页面设计的浏览器,它支持WAP 1.2协议。WML是一种基于XML的语言,主要用于创建适用于移动设备的小型网页,特别是在早期的...

    wap浏览器开发资料大全(含wml解析器)

    本压缩包包含的是一系列关于wap浏览器开发的重要资源,特别是对WML(无线标记语言)解析器的深入探讨。WAP(无线应用协议)是为移动设备设计的一种通信协议,使得手机和其他便携式设备能够访问互联网内容。WML解释器...

    最新的WAP浏览器,支持WML和XHTML MP

    最新的WAP浏览器,支持WML和XHTML MP页面浏览,可以看腾讯网哦。

    wml_02 继续配置wml开发环境02 安装 Nokia Mobile Browser Simulator 4.0并且浏览一些例子.rar

    Nokia Mobile Browser Simulator 4.0是一款强大的工具,允许开发者在没有实际移动设备的情况下,模拟多种Nokia手机上的Web浏览器行为,这对于优化WML网页设计和测试至关重要。 WML是一种专为无线通信设备设计的标记...

    WML语言参考教程 WML

    WML(Wireless Markup Language)是一种专为无线设备,特别是早期的移动电话设计的标记语言,用于创建可适应小型屏幕和有限功能的移动浏览器的网页内容。WML是XML的子集,因此它遵循XML的语法规则。本教程将深入探讨...

    毕业论文答辩——浏览器开发

    【标题】: "毕业论文答辩——浏览器开发" 【描述】: "本文主要探讨的是嵌入式浏览器的开发,包括HTML的词法分析、JavaScript支持的实现以及浏览器开发的难点和策略。" 【标签】: "毕业论文答辩——浏览器开发" 在...

    WAP开发教程(含WML)

    **WAP开发教程(含WML)** WAP(Wireless Application Protocol)无线应用协议是一种在移动设备上访问互联网的标准,使得用户可以通过手机等移动设备浏览网页、接收邮件、使用在线服务等。WAP技术主要应用于2G网络,...

    Learning WML & WML Script

    《Learning WML & WML Script》是一本由Martin Frost编写的书籍,专注于介绍无线标记语言(WML)和WML脚本,适用于那些希望在移动通信领域开发内容的开发者。WML是Wireless Markup Language的缩写,是为无线应用平台...

    wml基本知识教程(wap开发)

    **WML基础知识教程——WAP开发** WML(Wireless Markup Language)是为无线设备,如早期的手机和平板电脑,设计的一种标记语言,用于创建适应小型屏幕和有限功能的移动浏览器的网页。WML是WAP(Wireless ...

    WML1.3开发指南

    《WML1.3开发指南》是一份由Openwave Systems Inc.出版的专业文档,旨在为开发者提供关于WML(Wireless Markup Language)1.3版本的深入理解和实践指导。WML是一种专为无线设备设计的标记语言,用于创建适配于小屏幕...

    WML(无线标记语言)

    **WML(无线标记语言)**是专门为无线设备如移动电话、呼机和PDA设计的一种标记语言,它是XML的一个子集,由WAP论坛提出。WML的主要目的是为无线设备用户提供...学习和掌握WML对于开发适应移动设备的Web服务至关重要。

    Nokia Mobile Browser Simulator 4.0(手机模拟器,用来访问wap网站,wml网页).rar

    2. **.wml文件支持**:软件内置了对.wml文件的支持,可以直接打开和浏览这类文件,这对于开发者来说是非常有用的,因为他们可以在不依赖真实设备的情况下测试和调整.wml页面的设计和功能。 3. **性能模拟**:模拟器...

    WAP 开发 (WML)

    5. **WAP浏览器**:早期的移动设备上的浏览器称为WAP浏览器,它们专门设计用来解析和展示WML文档。随着技术的发展,许多现代移动设备支持更先进的HTML和CSS,但WML在某些特定场景下仍然有其应用价值,比如在物联网...

    关于wml的常见问题解答

    因此,WAP工作小组开发了WML,作为一种专门为无线设备量身定制的语言,以克服这些限制,提供更好的用户体验。 六、HTML与无线设备的兼容性 理论上,无线设备可以支持HTML,但实际效果往往不佳。移动设备上的微型...

    wml语言

    - 图形化的开发环境,内置浏览器和WML/WMLScript编译器。 - 需要在Windows NT 4.0环境下运行。 - 需要Java运行环境的支持,因此需先安装Java 2 SDK或JRE。 - **优势**: - 成熟度高,文档丰富,适合初学者快速...

    WAP 开发工具 WML

    这种工具通常包含基础的WML编辑器,支持语法高亮、自动完成等功能,以提高编码效率。同时,它还可能提供实时预览功能,允许开发者在模拟器或真实设备上查看WML页面在移动设备上的效果。 标签中的“WAP”、“开发...

    WAP网站开发WML语言基础

    测试WML程序通常使用微浏览器,如WinWap,因为它可以模拟WAP手机的功能。将WML文件上传到WAP服务器(通常是IIS下的WWW服务器的虚拟目录“wap”)后,可以通过微浏览器访问服务器上的WML文件来查看和调试程序效果。 ...

Global site tag (gtag.js) - Google Analytics