作者:
Confach 发表于2006-04-28 22:20 pm
版权信息:可以任意转载, 转载时请务必以超链接形式标明文章
原始出处 和作者信息.
http://www.cnblogs.com/confach/articles/387948.html
5
第5章 BlackBerry浏览器
|
浏览器API
在浏览器显示Web内容
在一个浏览器域里显示Web内容
支持附加的MIME类型
注册一个HTTP过滤器
|
|
API名和包
|
描述
|
|
浏览器应用程序API(net.rim.blackberry.api.browser)
|
通过调用Blackberry浏览器,API允许应用程序显示web内容,包括支持的图片格式,HTML以及WML页面.也允许应用程序提供HTTP请求的一个Referrer,HTTP头,以及提交的内容.为获得更多信息,参看51页的”在浏览器显示Web内容”.
|
|
浏览器域API
(net.rim.blackberry.api.browser.field)
|
此API允许一个应用程序获取web内容在一个浏览器域里的显示,此域包含在应用程序UI里.也允许应用程序配置浏览器域的表现形式,例如去除滚动条,或者指定仅显示屏幕一部分的浏览器域.
|
|
浏览器页面API(net.rim.blackberry.api.browser.plugin)
|
此API允许应用程序支持附加的MIME类型.当BlackBerry启动时,注册一个提交提供者,所有后发的浏览器对话将支持附加的MIME类型.为获取更多信息,参看66页的”支持附加的MIME类型”.
|
|
HTTP过滤器API
(net.rim.device.api.io.http)
|
API允许应用程序向浏览器注册一个或多个URL的提供者.为获取更多信息,参看71页的”注册一个HTTP过滤器”.
|
为了在浏览器里显示web内容,使用浏览器应用程序API(net.rim.blackberry.api.browser).
为了获取一个缺省的BrowserSession对象,调用静态方法Browser.getDefaultSession().本对象允许你访问正在BlackBerry设备上运行的浏览器.
为了新增一个约会,调用EventList.importEvent().
注:获取缺省的对话会覆写任何BlackBerry设备上已经打开的对话.
为获取一个不同的对话,调用getSession().此方法根据它的唯一ID(UID)获取一个浏览器配置服务记录.为获得更多信息,参见113页的”服务定制API”.
为请求一个Web页面,调用BrowserSession.displayPage()方法.下面的实例使用了仅接受一个URL的displayPage()方法.为指定一个referrer,HTTP头,以及提交的数据,使用接受这些附加信息的方法.
下面来自Restaurants.java实例的引用创建了一个菜单,此菜单会在浏览器中显示一个Web页面.
|
private MenuItem browserItem = new MenuItem(
_resources.getString(MENUITEM_BROWSER), 110, 12) {
public void run() {
synchronized(store) {
String websiteUrl = websitefield.getText();
if (websiteUrl.length == 0) {
Dialog.alert(_resources.getString(ALERT_NO_WEBSITE));
}
else {
BrowserSession visit = Browser.getDefaultSession();
visit.displayPage(websiteUrl);
}
}
}
};
|
为了在应用程序UI里包含一个浏览器域,使用浏览器域API (net.rim.device.api.browser.field).浏览器呈现(rendering)库为域处理web内容的描绘,然后返回一个BrowserField-在此域URL内容得到描绘-到你的应用程序显示.
注:用来打开一个浏览器域的浏览器对话独立于BlackBerry设备上缺省的浏览器对话. 任何打开的浏览器对话则不受影响.
RenderingApplication接口定义了一个描绘对话所需要的回调功能来帮助处理URL资源, RenderingApplication接口的实现在一个浏览器域里显示web内容.
当应用程序获取和显示浏览器域时,为阻止应用程序挂起,在一个独立线程上完成这些操作.
|
class CreationThread extends Thread {
BrowserFieldHandlerApplication _callBackApplication;
BasicRenderingApplication _renderingApplication;
public CreationThread(BrowserFieldHandlerApplication callBackApplication) {
_callBackApplication = callBackApplication;
}
public void run() {
_renderingApplication = new BasicRenderingApplication(_callBackApplication);
BrowserField field = _renderingApplication.getBrowserField("www.blackberry.com");
_callBackApplication.displayBrowserField(field);
}
}
|
覆写getRenderingOptions().如果你没有覆写此方法, 将使用缺省的呈现选项.为获得更多信息,参看API参考的RenderingOptions.
eventOccurred()的实现处理事件,例如一个URL请求.
|
public Object eventOccurred(Event event) {
int eventId = event.getUID();
switch (eventId) {
case Event.EVENT_URL_REQUESTED : {
UrlRequestedEvent e = (UrlRequestedEvent) event;
// This is a regular request.
String absoluteUrl = e.getURL();
HttpConnection conn = null;
OutputStream out = null;
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
FormData postData = e.getPostData();
if (postData == null) {
conn.setRequestMethod(HttpConnection.GET);
}
else {
conn.setRequestMethod(HttpConnection.POST);
byte[] postBytes = postData.getBytes();
conn.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_LENGTH,
String.valueOf(postBytes.length));
if (conn.getRequestProperty(
HttpProtocolConstants.HEADER_CONTENT_TYPE) == null) {
conn.setRequestProperty(
HttpProtocolConstants.HEADER_CONTENT_TYPE,
postData.getContentType());
}
out = conn.openOutputStream();
out.write(postBytes);
}
HttpHeaders requestHeaders = e.getHeaders();
if (requestHeaders != null) {
/* From http://www.w3.org/Protocols/rfc2616/rfc2616-sec15.html#sec15.1.3
* Clients SHOULD NOT include a Referer header field in a
* (non-secure) HTTP request if the referring page was
* transferred with a secure protocol.*/
String referer =
requestHeaders.getPropertyValue("referer");
boolean sendReferrer = true;
if (referer != null && referer.startsWith("https:") &&
!absoluteUrl.startsWith("https:")) {
sendReferrer = false;
}
int size = requestHeaders.size();
for (int i = 0; i < size; i++) {
String header = requestHeaders.getPropertyKey(i);
// Remove refer header if needed.
if ( !sendReferrer && header.equals("referer")) {
requestHeaders.removeProperty(i);
continue;
}
conn.setRequestProperty( header,
requestHeaders.getPropertyValue( i ) );
}
}
}
catch (IOException e1) {
}
finally {
if (out != null) {
try {
out.close();
}
catch (IOException e2) {
}
}
}
BrowserField browserField = getBrowserField(conn, e);
_callbackApplication.displayBrowserField(browserField);
break;
}
case Event.EVENT_BROWSER_FIELD_CHANGED : {
// Browser field title might have changed. Update title.
break;
}
case Event.EVENT_REDIRECT : {
RedirectEvent e = (RedirectEvent) event;
switch (e.getType()) {
case RedirectEvent.TYPE_SINGLE_FRAME_REDIRECT :
// Show redirect message.
Application.getApplication().invokeAndWait(new Runnable() {
public void run() {
Status.show("");
}
});
break;
case RedirectEvent.TYPE_JAVASCRIPT :
case RedirectEvent.TYPE_META :
case RedirectEvent.TYPE_300_REDIRECT :
}
String absoluteUrl = e.getLocation();
HttpConnection conn = null;
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
}
catch (IOException e1) {
}
BrowserField browserField = getBrowserField(conn,
e.getOriginalEvent());
_callbackApplication.displayBrowserField(browserField);
break;
}
case Event.EVENT_CLOSE :
// Close the appication.
break;
case Event.EVENT_SET_HEADER :// no cache support
case Event.EVENT_SET_HTTP_COOKIE : // no cookie support
case Event.EVENT_HISTORY : // no history support
case Event.EVENT_LOADING_IMAGES :// no progress bar is supported
case Event.EVENT_EXECUTING_SCRIPT : // no progress bar is supported
case Event.EVENT_FULL_WINDOW : // no full window support
case Event.EVENT_STOP : // no stop loading support
default :
}
return null;
}
|
getBrowserField()的实现为呈现获取浏览器内容. getBrowserField()方法调用RenderingSession.getBrowserField()获取一个浏览器域.应用程序不能直接实例化BrowserField
|
public BrowserField getBrowserField (String absoluteUrl) {
HttpConnection conn = null;
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
// Set transcode to true.
conn.setRequestProperty( "x-rim-transcode-content", "*/*" );
}
catch (IOException e1) {
}
return getBrowserField(conn, null);
}
private BrowserField getBrowserField(HttpConnection conn, Event e) {
BrowserField field = null;
try {
field = _renderingSession.getBrowserField(conn, this, e);
}
catch (RenderingException re) {
return null;
}
// Add to the event queue a thread that invokes finishLoading().
Application.getApplication().invokeLater(new RenderingThread(field));
return field;
}
|
调用BrowserField.finishLoading().在下面的代码实例中, BrowserField.getBrowserField()将一个新的描绘线程加载到应用程序事件队列里来运行finishLoading().
注:HTML文件显示一个空白域,直到你调用BrowserField.finishLoading().在调用此方法前WML文件和图像可能加载 .在一个独立线程上运行finishLoading(),这样UI不会锁住.
|
class RenderingThread implements Runnable {
BrowserField _browserField;
RenderingThread(BrowserField field) {
_browserField = field;
}
public void run() {
try {
_browserField.finishLoading();
}
catch (RenderingException e) {
// Handle exception.
}
}
}
|
displayBrowserField()的实现删除屏幕内容,然后增加浏览器域到屏幕.
|
public void displayBrowserField(BrowserField browserField) {
synchronized (Application.getEventLock()) {
_vfm.deleteAll();
_vfm.add(browserField);
}
}
|
下面的实例包含了3个文件: BasicRenderingApplication.java, BrowserFieldHandlerApplication.java, 以及 BrowserFieldSampleApp.java.
例:浏览器域实例
/**
* BasicRenderingApplication.java
* Copyright (C) 2002-2005 Research In Motion Limited.
*/
package com.rim.samples.docs.browser;
import java.io.IOException;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.browser.field.*;
import net.rim.device.api.io.http.HttpHeaders;
import net.rim.device.api.io.http.HttpProtocolConstants;
import net.rim.device.api.system.Application;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.component.Status;
import com.rim.samples.docs.browser.BrowserFieldHandlerApplication.*;
final public class BasicRenderingApplication implements RenderingApplication
{
RenderingSession _renderingSession;
BrowserFieldHandlerApplication _callbackApplication;
public BasicRenderingApplication(BrowserFieldHandlerApplication callBackApplication) {
_renderingSession = RenderingSession.getNewInstance();
_callbackApplication = callBackApplication;
}
/**
* * Simple method to get a browser field by specifying the URL.
* * This call blocks until the browser field is returned by RenderingSession.getBrowserField().
* * The browser field can continue to be rendered after the field is returned.
* *
* * @param absoluteUrl - absolute url of the page to render
* * @return rendered browser field
* */
public BrowserContent getBrowserField (String absoluteUrl) {
HttpConnection conn = null;
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
// Set transcode to true.
conn.setRequestProperty( "x-rim-transcode-content", "*/*" );
}
catch (IOException e1) {
}
return getBrowserField(conn, null);
}
private BrowserContent getBrowserField(HttpConnection conn, Event e) {
BrowserContent field = null;
try {
field = _renderingSession.getBrowserContent(conn, this, e);
}
catch (RenderingException re) {
return null;
}
Application.getApplication().invokeLater(new RenderingThread(field));
return field;
}
/**
* * Invoked when an event occurs.
* */
public Object eventOccurred(Event event) {
int eventId = event.getUID();
switch (eventId) {
case Event.EVENT_URL_REQUESTED : {
UrlRequestedEvent e = (UrlRequestedEvent) event;
// this is a regular request
String absoluteUrl = e.getURL();
HttpConnection conn = null;
OutputStream out = null;
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
byte[] postData = e.getPostData();
if (postData == null) {
conn.setRequestMethod(HttpConnection.GET);
}
else {
conn.setRequestMethod(HttpConnection.POST);
conn.setRequestProperty( HttpProtocolConstants.HEADER_CONTENT_LENGTH,
String.valueOf(postData.length));
out = conn.openOutputStream();
out.write(postData);
}
HttpHeaders requestHeaders = e.getHeaders();
if (requestHeaders != null) {
/* From http://www.w3.org/Protocols/rfc2616/rfc2616-sec15.html#sec15.1.3
* ...
* Clients SHOULD NOT include a Referer header field in a
* (non-secure) HTTP request if the referring page was
* transferred with a secure protocol.
* */
String referer = requestHeaders.getPropertyValue("referer");
boolean sendReferrer = true;
if (referer != null && referer.startsWith("https:") &&
!absoluteUrl.startsWith("https:")) {
sendReferrer = false;
}
int size = requestHeaders.size();
for (int i = 0; i < size; i++) {
String header = requestHeaders.getPropertyKey(i);
// Remove refer header if needed.
if ( !sendReferrer && header.equals("referrer")) {
requestHeaders.removeProperty(i);
continue;
}
conn.setRequestProperty( header,
requestHeaders.getPropertyValue( i ) );
}
}
}
catch (IOException e1) {
}
finally {
if (out != null) {
try {
out.close();
}
catch (IOException e2) {
}
}
}
BrowserContent browserField = getBrowserField(conn, e);
_callbackApplication.displayBrowserField(browserField);
break;
}
case Event.EVENT_BROWSER_CONTENT_CHANGED : {
// Browser field title might have changed. Update title.
break;
}
case Event.EVENT_REDIRECT : {
RedirectEvent e = (RedirectEvent) event;
switch (e.getType()) {
// Show redirect message.
Application.getApplication().invokeAndWait(new Runnable() {
public void run() {
Status.show("");
}
});
break;
case RedirectEvent.TYPE_JAVASCRIPT :
case RedirectEvent.TYPE_META :
case RedirectEvent.TYPE_300_REDIRECT :
}
String absoluteUrl = e.getLocation();
HttpConnection conn = null;
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
}
catch (IOException e1) {
}
BrowserContent browserField = getBrowserField(conn, e.getOriginalEvent());
_callbackApplication.displayBrowserField(browserField);
break;
}
case Event.EVENT_CLOSE :
// Close the appication.
break;
case Event.EVENT_TICK_CONTENT_READ : // No progress bar is supported.
case Event.EVENT_SET_HEADER : // No cache support.
case Event.EVENT_SET_HTTP_COOKIE : // No cookie support.
case Event.EVENT_HISTORY : // No history support
case Event.EVENT_LOADING_IMAGES : // No progress bar is supported.
case Event.EVENT_EXECUTING_SCRIPT : // No progress bar is supported.
case Event.EVENT_FULL_WINDOW : // No full window support.
case Event.EVENT_STOP : // No stop loading support.
default :
}
return null;
}
/**
* * Retrieves the pixels of height available for provided browser content.
* * @param browserField Content for which to retrieve available pixels of height.
* * @return Height available.
* */
public int getAvailableHeight(BrowserContent browserField) {
// Field has full screen.
return Graphics.getScreenHeight();
}
/**
* * Retrieves the pixels of width available for provided browser content.
* */
public int getAvailableWidth(BrowserContent browserField) {
// Field has full screen.
return Graphics.getScreenWidth();
}
/**
* * Retrieves the history position for provided browser content.
* */
public int getHistoryPosition(BrowserContent browserField) {
// No history support.
return 0;
}
/**
* * Retrieves cookies associated with a provided URL.
* */
public String getHTTPCookie(String url) {
// No cookie support.
return null;
}
/**
* * Retrieves the specified resource.
*/
public HttpConnection getResource( RequestedResource resource, BrowserContent referrer)
{
if (resource == null) {
return null;
}
// Check if this is cache-only request.
if (resource.isCacheOnly()) {
// No cache support.
return null;
}
String url = resource.getUrl();
if (url == null) {
return null;
}
// If referrer is null, return the connection.
if (referrer == null) {
HttpConnection conn;
try {
return (HttpConnection) Connector.open(resource.getUrl());
}
catch (IOException e) {
return null;
}
}
else {
// If referrer is provided, set up the connection on a
// separate thread.
Application.getApplication().invokeLater(
new RetrieveThread(resource, referrer));
}
return null;
}
/**
* * Invokes the provided runnable object.
* */
public void invokeRunnable(Runnable runnable) {
(new Thread(runnable)).run();
}
}
class RenderingThread implements Runnable {
BrowserContent _browserField;
RenderingThread(BrowserContent field) {
_browserField = field;
}
public void run() {
try {
_browserField.finishLoading();
}
catch (RenderingException e) {
}
}
}
class RetrieveThread implements Runnable {
BrowserContent _browserField;
RequestedResource _resource;
RetrieveThread(RequestedResource resource, BrowserContent referrer) {
_browserField = referrer;
_resource = resource;
}
public void run() {
HttpConnection conn;
try {
conn = (HttpConnection) Connector.open(_resource.getUrl());
}
catch (IOException e) {
return;
}
_resource.setHttpConnection(conn);
_browserField.resourceReady(_resource);
}
}
/**
* BasicRenderingApplication.java
* Copyright (C) 2002-2005 Research In Motion Limited.
*/
package com.rim.samples.docs.browser;
import java.io.IOException;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.browser.field.*;
import net.rim.device.api.io.http.HttpHeaders;
import net.rim.device.api.io.http.HttpProtocolConstants;
import net.rim.device.api.system.Application;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.component.Status;
import com.rim.samples.docs.browser.BrowserFieldHandlerApplication.*;
final public class BasicRenderingApplication implements RenderingApplication {
RenderingSession _renderingSession;
BrowserFieldHandlerApplication _callbackApplication;
public BasicRenderingApplication(BrowserFieldHandlerApplication callBackApplication) {
_renderingSession = RenderingSession.getNewInstance();
_callbackApplication = callBackApplication;
}
/**
* * Simple method to get a browser field by specifying the URL.
* * This call blocks until the browser field is returned by RenderingSession.getBrowserField().
* * The browser field can continue to be rendered after the field is returned.
* *
* * @param absoluteUrl - absolute url of the page to render
* * @return rendered browser field
* */
public BrowserContent getBrowserField (String absoluteUrl) {
HttpConnection conn = null;
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
// Set transcode to true.
conn.setRequestProperty("x-rim-transcode-content", "*/*" );
}
catch (IOException e1) {
}
return getBrowserField(conn, null);
}
private BrowserContent getBrowserField(HttpConnection conn, Event e) {
BrowserContent field = null;
try {
field = _renderingSession.getBrowserContent(conn, this, e);
}
catch (RenderingException re) {
return null;
}
Application.getApplication().invokeLater(new RenderingThread(field));
return field;
}
/**
* * Invoked when an event occurs.
* */
public Object eventOccurred(Event event) {
int eventId = event.getUID();
switch (eventId) {
case Event.EVENT_URL_REQUESTED : {
UrlRequestedEvent e = (UrlRequestedEvent) event;
// this is a regular request
String absoluteUrl = e.getURL();
HttpConnection conn = null;
OutputStream out = null;
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
byte[] postData = e.getPostData();
if (postData == null) {
conn.setRequestMethod(HttpConnection.GET);
}
else {
conn.setRequestMethod(HttpConnection.POST);
conn.setRequestProperty( HttpProtocolConstants.HEADER_CONTENT_LENGTH,
String.valueOf(postData.length));
out = conn.openOutputStream();
out.write(postData);
}
HttpHeaders requestHeaders = e.getHeaders();
if (requestHeaders != null) {
/* From http://www.w3.org/Protocols/rfc2616/rfc2616-sec15.html#sec15.1.3
* ...
* Clients SHOULD NOT include a Referer header field in a
* (non-secure) HTTP request if the referring page was
* transferred with a secure protocol.*/
String referer = requestHeaders.getPropertyValue("referer");
boolean sendReferrer = true;
if (referer != null && referer.startsWith("https:")
&& !absoluteUrl.startsWith("https:")) {
sendReferrer = false;
}
int size = requestHeaders.size();
for (int i = 0; i < size; i++) {
String header = requestHeaders.getPropertyKey(i);
// Remove refer header if needed.
if ( !sendReferrer && header.equals("referrer")) {
requestHeaders.removeProperty(i);
continue;
}
conn.setRequestProperty( header, requestHeaders.getPropertyValue( i ) );
}
}
}
catch (IOException e1) {
}
finally {
if (out != null) {
try {
out.close();
}
catch (IOException e2) {
}
}
}
BrowserContent browserField = getBrowserField(conn, e);
_callbackApplication.displayBrowserField(browserField);
break;
}
case Event.EVENT_BROWSER_CONTENT_CHANGED : {
// Browser field title might have changed. Update title.
break;
}
case Event.EVENT_REDIRECT : {
RedirectEvent e = (RedirectEvent) event;
switch (e.getType()) {
case RedirectEvent.TYPE_SINGLE_FRAME_REDIRECT :
// Show redirect message.
Application.getApplication().invokeAndWait(new Runnable() {
public void run() {
Status.show("");
}
});
break;
case RedirectEvent.TYPE_JAVASCRIPT :
case RedirectEvent.TYPE_META :
case RedirectEvent.TYPE_300_REDIRECT :
}
String absoluteUrl = e.getLocation();
HttpConnection conn = null;
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
}
catch (IOException e1) {
}
BrowserContent browserField = getBrowserField(conn, e.getOriginalEvent());
_callbackApplication.displayBrowserField(browserField);
break;
}
case Event.EVENT_CLOSE :
// Close the appication.
break;
case Event.EVENT_TICK_CONTENT_READ : // No progress bar is supported.
case Event.EVENT_SET_HEADER : // No cache support.
case Event.EVENT_SET_HTTP_COOKIE : // No cookie support.
case Event.EVENT_HISTORY : // No history support.
case Event.EVENT_LOADING_IMAGES : // No progress bar is supported.
case Event.EVENT_EXECUTING_SCRIPT : // No progress bar is supported
case Event.EVENT_FULL_WINDOW : // No full window support
case Event.EVENT_STOP : // No stop loading support.
default :
}
return null;
}
/**
* * Retrieves the pixels of height available for provided browser content.
* * @param browserField Content for which to retrieve available pixels of height.
* * @return Height available.
* */
public int getAvailableHeight(BrowserContent browserField) {
// Field has full screen.
return Graphics.getScreenHeight();
}
/**
* * Retrieves the pixels of width available for provided browser content.
* */
public int getAvailableWidth(BrowserContent browserField) {
// Field has full screen.
return Graphics.getScreenWidth();
}
/**
* * Retrieves the history position for provided browser content.
* */
public int getHistoryPosition(BrowserContent browserField) {
// No history support.
return 0;
}
/**
* * Retrieves cookies associated with a provided URL.
* */
public String getHTTPCookie(String url) {
// No cookie support.
return null;
}
/**
* * Retrieves the specified resource.
* */
public HttpConnection getResource( RequestedResource resource, BrowserContent referrer)
{
if (resource == null) {
return null;
}
// Check if this is cache-only request.
if (resource.isCacheOnly()) {
// No cache support.
return null;
}
String url = resource.getUrl();
if (url == null) {
return null;
}
// If referrer is null, return the connection.
if (referrer == null) {
HttpConnection conn;
try {
return (HttpConnection) Connector.open(resource.getUrl());
}
catch (IOException e) {
return null;
}
}
else {
// If referrer is provided, set up the connection on a
// separate thread.
Application.getApplication().invokeLater(
new RetrieveThread(resource, referrer));
}
return null;
}
/**
* * Invokes the provided runnable object.
* */
public void invokeRunnable(Runnable runnable) {
(new Thread(runnable)).run();
}
}
class RenderingThread implements Runnable {
BrowserContent _browserField;
RenderingThread(BrowserContent field) {
_browserField = field;
}
public void run() {
try {
browserField.finishLoading();
}
catch (RenderingException e) {
}
}
}
class RetrieveThread implements Runnable {
BrowserContent _browserField;
RequestedResource _resource;
RetrieveThread(RequestedResource resource, BrowserContent referrer) {
_browserField = referrer;
_resource = resource;
}
public void run() {
HttpConnection conn;
try {
conn = (HttpConnection) Connector.open(_resource.getUrl());
}
catch (IOException e) {
return;
}
_resource.setHttpConnection(conn);
_browserField.resourceReady(_resource);
}
}
浏览器页面API在net.rim.device.api.browser.plugin包中,它允许第三方应用程序向描绘库将它们自己注册为BlackBerry浏览器不支持的MIME类型的描绘提供者.
注: 如果你试着注册一个BlackBerry浏览器已经支持的MIME类型,BrowserFieldProviderRegistry.register()方法会抛出一个异常.为得到支持的MIME类型列表,调用RenderingSession.getSupportedMimeType().
为支持附加的MIME类型,需要扩展BrowserContentProvider抽象类.为了指定显示特性,例如没有滚动条显示或全屏显示,需要实现BrowserPageContext接口.
呈现的类库调用BrowserContentProvider.getAccept()和BrowserContentProvider.getSupportedMimeTypes()标志提供者呈现的MIME类型.
列出接受的MIME类型
getAccept()和getSupportedMimeTypes()的实现列出了提供者接受的MIME类型,它们给定了一组呈现的选项. getAccept()方法考虑到已经设置的呈现选项.这个例子假设没有设置呈现选项.为得到更多信息.参看API参考的RenderingOptions
|
public String[] getAccept(RenderingOptions context) {
// Return subset of getSupportedMimeTypes() if accept depends on rendering
// options. For example, HTML can be turned off in the rendering options.
// This would cause HTMLConverter to remove HTML MIME types.
return ACCEPT;
}
public String[] getSupportedMimeTypes() {
return ACCEPT;
}
|
指定显示特征
BrowserPageContext接口的实现指定了显示的特征.如果没有实现此接口,将使用缺省的值.
在本例中,所有属性都是整型.一个带有Boolean,String,和Object属性的应用程序将实现对应的方法.
|
public boolean getPropertyWithBooleanValue(int id, boolean defaultValue) {
// TODO Implement.
return false;
}
public int getPropertyWithIntValue(int id, int defaultValue) {
if (id == BrowserPageContext.DISPLAY_STYLE) {
// Turn off the scroll bar.
return BrowserPageContext.STYLE_NO_VERTICAL_SCROLLBAR;
}
return 0;
}
public Object getPropertyWithObjectValue(int id, Object defaultValue) {
// TODO Implement.
return null;
}
public String getPropertyWithStringValue(int id, String defaultValue) {
// TODO Implement.
return null;
}
|
获取一个域呈现内容
实现getBrowserContent(BrowserContentProviderContext)方法.
|
public BrowserContent getBrowserContent( BrowserContentProviderContext context)
throws RenderingException {
if (context == null) {
throw new RenderingException("No Context is passed into Provider");
}
BrowserContentBaseImpl browserContentBaseImpl = new
BrowserContentBaseImpl(context.getHttpConnection().getURL(), null,
context.getRenderingApplication(),
context.getRenderingSession().getRenderingOptions(), context.getFlags());
VerticalFieldManager vfm = new VerticalFieldManager(Manager.VERTICAL_SCROLL);
vfm.add(new LabelField("Mime type: ") );
vfm.add(new LabelField(ACCEPT[0]));
vfm.add(new SeparatorField());
vfm.add(new LabelField("Content of the resource file: \n"));
vfm.add(new SeparatorField());
try {
HttpConnection conn = context.getHttpConnection();
InputStream in = conn.openInputStream();
byte[] data = IOUtilities.streamToBytes(in);
vfm.add(new LabelField(new String(data)));
}
catch (IOException e) {
// TODO Implement.
e.printStackTrace();
}
browserContentBaseImpl.setContent(vfm);
browserContentBaseImpl.setTitle(ACCEPT[0]);
// Set browser page context, this will tell the browser how to display this
// field.
browserContentBaseImpl.setBrowserPageContext(this);
return browserContentBaseImpl;
}
|
在BlackBerry启动时注册
创建一个类库工程,将它的属性设置为启动时自动运行.在libMain()里,调用BrowserFieldProviderRegistry.getInstance()方法,然后再调用invoke register().
|
public static void libMain( String[] args ) {
BrowserContentProviderRegistry converterRegistry =
BrowserContentProviderRegistry.getInstance();
if (converterRegistry != null) {
converterRegistry.register(new BrowserPlugin());
}
}
|
下面的例子包含2个文件, LoaderApp.java和BrowserPlugin.java.当BlackBerry设备启动时LoaderApp.java增加一个新支持的MIME类型. BrowserPlugin.java包含了一个扩展了BrowserContentProvider的类.
例: BrowserPlugin.java和LoaderApp.java
/**
* LoaderApp.java
* Copyright (C) 2004-2005 Research In Motion Limited.
*/
package com.rim.samples.docs.browser;
import net.rim.device.api.browser.plugin.BrowserContentProviderRegistry;
final class LoaderApp {
public static void libMain( String[] args ) {
BrowserContentProviderRegistry converterRegistry =
BrowserContentProviderRegistry.getInstance();
if (converterRegistry != null) {
converterRegistry.register(new BrowserPlugin());
}
}
}
/**
* BrowserPlugin.java
* Copyright (C) 2004-2005 Research In Motion Limited.
*/
package com.rim.samples.docs.browser;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.browser.field.*;
import net.rim.device.api.browser.plugin.*;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.VerticalFieldManager;
/**
* Create a file with xxtest extension and associate that type with
* application/x-vnd.rim.xxxtest mime type on any server.
*/
public final class BrowserPlugin extends BrowserContentProvider
implements BrowserPageContext {
private static final String[] ACCEPT = {"application/x-vnd.rim.xxxtest"};
/**
* Retrieves list of mime types this provider can accept given a set of rendering options.
* * @param context Rendering options in place this provider should consider.
* * @return Array of mime types this provider will accept, given the provided rendering
* options.
**/
public String[] getAccept(RenderingOptions context) {
// Return subset of getSupportedMimeTypes() if accept depends in rendering options.
// For example HTML can be disabled in the rendering options, and HTMLConverter would remove
// html MIME types.
return ACCEPT;
}
/**
* Retrieves a browser content capable of rendering the mime content this provider
* can handle.
* @param context Provider context object provided by rendering session.
* @return Browser content to render specialized content.
*/
public BrowserContent getBrowserContent( BrowserContentProviderContext context)
throws RenderingException {
if (context == null) {
throw new RenderingException("No Context is passed into Provider");
}
BrowserContentBaseImpl browserContentBaseImpl =
new BrowserContentBaseImpl(context.getHttpConnection().getURL(),
null, context.getRenderingApplication(),
context.getRenderingSession().getRenderingOptions(),
context.getFlags());
VerticalFieldManager vfm = new VerticalFieldManager(Manager.VERTICAL_SCROLL);
vfm.add(new LabelField("Mime type: ") );
vfm.add(new LabelField(ACCEPT[0]));
vfm.add(new SeparatorField());
vfm.add(new LabelField("Content of the resource file: \n"));
vfm.add(new SeparatorField());
try {
HttpConnection conn = context.getHttpConnection();
InputStream in = conn.openInputStream();
int numBytes = in.available();
byte[] data = new byte[numBytes];
in.read(data, 0, numBytes);
vfm.add(new LabelField(new String(data)));
}
catch (IOException e) {
e.printStackTrace();
}