Android浏览器Browser二次开发(二) 修改浏览器使之支持WML格式页面
2011-04-27 17:55
225 查看
Android浏览器Browser二次开发(二)
第二章 修改浏览器使之支持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";
}
该篇文章转自:http://seya.javaeye.com/blog/931289
相关文章推荐
- 修改浏览器使之支持WML格式页面
- 修改Android Webkit使浏览器支持WML格式的页面
- Android浏览器Browser二次开发(二)支持WML
- Android浏览器Browser二次开发(四)浏览器中的APN切换
- wap1.0用wml card变换产生动态页面,此法很多浏览器不支持
- net控件中数据导到Excel的格式 首先,我们了解一下excel从web页面上导出的原理。当我们把这些数据发送到客户端时,我们想让客户端程序(浏览器)以excel的格式读取它,所以把mime类型设为:application/vnd.ms-excel,当excel读取文件时会以每个cell的格式呈现数据,如果cell没有规定的格式,则excel会以默认的格式去呈现该cell的数据。这样就给我们提供了自定义数据格式的空间,当然我们必须使用excel支持的格式。下面就列出常用的一些格式: 1) 文本
- Android浏览器Browser二次开发(四)浏览器中的APN切换
- Android浏览器Browser二次开发(四)浏览器中的APN切换
- android ICS原生态Browser上增加对WML的支持
- 如何修改网页小图标,浏览器页面上的图标。
- 几组超神奇的网页应用代码要你在IE浏览器任意打开一个网站,然后在浏览器上输入如下代码神奇的代码,可随意修改复制页面内容!
- js监听表单value的修改同步问题,跨浏览器支持
- HTML5 修改浏览器url而不刷新页面
- 最强大的对联广告,所有浏览器支持,ie6无抖动,缩放页面ie6没有横向滚动条
- 浏览器支持播放的视频播放格式要求(H5的video标签)
- 浏览器探究——WebKit部分——支持WML
- android4.4 Browser 浏览器模式选项 默认值修改
- 浏览器以图片格式请求一个aspx页面和以iframe形式请求页面,在服务器端可以判断出来么?
- 解决openwrt页面升级中“不支持所上传的文件格式”问题
- 制作手机浏览器显示格式的HTML页面