BlackBerry 网络连接编程

作者: 王恒进

 

 

1. BlackBerry 上连 HTTP Socket 的五种方式

 

 

 

BlackBerry JDE API 了五种式来 HTTP 或者 socket ,包

 

1.1.        BlackBerry Enterprise Server(BES)方式

这种方通过使 BES  BlackBerry MDS Services 行网连接BlackBerry

MDS Services 责处所有的览器求或者连请求并负数据加密,这是 手机的认连方式,如下:

 

1  (HttpConnection) Connector.open("http://www.testserver.com");

 

以上代会自 BlackBerry MDS Services 为它的认连路径。实际开发 如果要保应程序使 uses BlackBerry MDS Services 它的连接路径,要在 URL 加上deviceside=false我们推的方,如

 

2  (HttpConnection)Connector.open(http://www.testserver.com;deviceside=false);

 

1.2.       BlackBerry Internet ServieBIS)方式

这种方是为三方提供的连接口,对数据不进行加,用可以通过使用

HTTPS SSL 行安的连接注:对加入了 BlackBerry Alliance Program

第三开放作伙伴开放,详参考:

http://na.blackberry.com/eng/partners/alliance.jsp

 

 

1.3.       Direct TCP 方式

这种方允许没有使 BlackBerry MDS 黑莓手机上 TCP 了能启用 direct TCP ,用需要在机的-级选项-TCP/IP APN,以 应的用名和码。

 

1行在 iDEN 上的黑手机包括 651075107520 7100i),如不指

deviceside (如例 1),默的连 direct TCP iDEN 络上的其 他黑莓机,果不 deviceside ,默的连接是 BlackBerry MDS

 

2果连 BlackBerry MDS 不存,黑手机也自动 direct TCP 式。

 

因此,果要将 direct TCP 黑莓机的默认连接方,我建议在 URL 中加入

deviceside=true参数,如下:

 

3-1  (SocketConnection)Connector.open("socket://testserver:600;deviceside=true");

 

此外,果应程序不希使用用自己置的 APN,也可 URL 定自己

APN,以下是指通过国移动 CMNET 进行 TCP 的例

 

3-2  (SocketConnection)Connector.open("socket://testserver:600;deviceside=true;APN=cmnet");

 

  

 

1.4.       Wi-Fi

如果需 Wi-Fi 创建网络连,不要在应用程序中虑特的底层逻

URL 入参interface=wifi能实现 Wi-Fi 接,如

 

4(StreamConnection)Connector.open(“socket:// testserver:600;interface=wifi”);

 

 

1.5.       WAP

 

1.5.1. WAP 1.x

并不是有的动运营商都支持 WAP 关进行连接,所如果要创 WAP 接,开者需和移动运营商联,获提供这种支、并获取他们 WAP 管参数。

 

以下是个基中国 CMWAP WAP 进行 HTTP 的例

 

5

(HttpConnection)Connector.open("http://wap.google.com;WAPGatewayIP=10.0.0.172;WAPGatewayAPN=cm wap");

 

注:其中 WAPGatewayIP WAPGatewayAPN 这两项数必指定,参数之间用

;隔开,下是所有 WAP 参数表,实际开发时根据营商提供的信息 哪些参需要

 

 

Parameter

Description

 

WapGatewayIP

 

IP address of the gateway.

WapGatewayAPN

APN for General Packet Radio Service (GPRS) networks only. For testing purposes, you can use rim.net.gprs

WapGatewayPort

Gateway port value. If port 9203 is specified, Wireless Transport Layer Security (WTLS) is used unless WapEnableWTLS=false is specified.

WapSourceIP

IP address of the source.


 

WapSourcePort

Source port value.

TunnelAuthUsername

User name for APN session, when Password Authentication

Protocol (PAP) or Challenge Handshake Application Protocol

(CHAP) authentication is used.

TunnelAuthPassword

Password for APN session, when PAP or CHAP

authentication is used.

WapEnableWTLS

Explicitly turns on or turns off WTLS. If this parameter is not specified, WTLS is used by default for connections to port

9203.

 

 

1.5.2. WAP 2.0

如果要 WAP2.0 关,需在连时指定 service record UID以下代说明

 WAP2.0 的连时如工作的:

 

5

 

 

ServiceBook sb = ServiceBook.getSB();

ServiceRecord[] records = sb.findRecordsByCid("WPTCP"); String uid = null;

 

for(int i=0; i < records.length; i++)

{

//Search through all service records to find the

//valid non-Wi-Fi and non-MMS

//WAP 2.0 Gateway Service Record.

if (records[i].isValid() && !records[i].isDisabled())

{

 

if (records[i].getUid() != null && records[i].getUid().length() != 0)

{

if ((records[i].getUid().toLowerCase().indexOf("wifi") == -1) &&

(records[i].getUid().toLowerCase().indexOf("mms") == -1))

{

uid = records[i].getUid();

break;

}

}

}

}

 

if (uid != null)

{

 

//open a WAP 2 connection

Connector.open(_url + ";ConnectionUID=" + uid);

}

 

else

{

 

//Consider another transport or alternative action.

}

 

在这里基本程是 Service Book 获得 Service Record,然后再从中获得 UID

后文会此进更具体的分析。

 

 

 

2. BlackBerry 上中国移动 WAP 网关连接技巧

首先解一下中国移动提供 CMNET CMWAP APN本质,这 APN 本应没 有区别但是营商从商业角度发,以下两方面来定这二

 

1,采用同的费方,不包的情CMNET 有可收费

 

2,网络入的权不CMNET 能获完全网络访问, PC 接上一样,而 CMWAP

只能限 WAP(基本上可以等 HTTP,也是只能访 web service

  

那么接来,黑莓上这两个 APN 有什区别呢,显然,连 CMNET 能干更多的事,如:

 

1 长连接

 

2 对端口的 socket 连接 

 

CMWAP 由于费便宜,因此用可能话,往往倾向于这个 APN不少应用为达到 更好的验,将自己的应用首或者至绑定 CMWAP

 

最后,罗列下中国移动的 WAP 情况,有哪些连接方

 

WAP 1.x(国内开发者,特别是从 J2ME 过来开发者往往向于)

1  接或者 socket 连接 建议用:

(SocketConnection)Connector.open("socket://testserver:600;deviceside=true;APN=

cmnet");

 

如果在--TCP/IP 中填 CMNET,用面这种式也成功

(SocketConnection)Connector.open("socket://testserver:600;deviceside=true");

 

                   2  CMWAP 访 WAP 网站

 

(HttpConnection)Connector.open(http://wap.google.com;WAPGatewayIP=10.0.0.172;W APGatewayAPN=cmwap);

 

 

 

                  这里,意不 WapGatewayPort=80 (似很多人容易这个错误),原是系

 

统会根关键字 http 动识别该用个网关端口,实上在莓上这个值也不是 80 而是 9201

  

3  CMNET 访 WAP 网站

 

(HttpConnection)Connector.open(http://wap.google.com;WAPGatewayIP=10.0.0.172;W APGatewayAPN=cmnet );

 

或用 CMNET 访任意

 

(HttpConnection)Connector.open( http://www.google.com;deviceside=true;APN=cmne

t )

 

 

 

 

WAP 2.0 方式这是我强烈推荐

可能大也发了,用 WAP1.x 常之灵活,代码也往会变很复杂很乱。 而其实莓上更好更简洁的办,就通过 WAP 2.0 访问,上一里面写一个例

子,来明如通过 WAP2.0 网络在这里解释一下:

 

打开选项-高级-服务预订中能看一项 WAP2 Transport[WPTCP]去可以 看到以信息

 

名称:  WAP2 Transport

 

UID  WAP2 trans

 

CID:     WPTCP

 

 

 

 

这些信从哪来的呢,这是黑上面一个概念叫做 service book一项 service

book 就是套对机服务行描的配置文件,在里的 RIM 中国移合作的 时候准好的置项,由黑莓手上市预加载、或者手启动由运营商将配置送到 手机上。

 

就这一而言,UID 是描述服务关键CID 描述服走的什么网络通道UID

WAP2 trans 示这是 WAP2.0 service book而且基上这关键词是不会变。这 样就好解了 WAP2.0 那一的代了。

 

其实有简单,这个 URL 就直达到效果:

 

http://www.google.com;DeviceSide=true;ConnectionUID=WAP2 trans

 

 

 

3. BlackBerry 上中国电信 WAP 网关连接分析

 

中国电已经布了 BlackBerry 9530不同的是,这一款烧号,因此可发的候还 是会遇一些同的。

 

1 C 网和 G 的差别。中国电 CDMA WAP 时没有 GPRS APN 的概。可可能 有人要,那电信的“CTNETCTWAP怎么一事呢其实这涉及到 CDMA 底层, CDMA 是建 PPP 的,也是手拨号上网,那么能经 modem 年代童鞋 还记得号的候需要一个号码还需用户名和密码。好,里的 ctnet ctwap 其实 这里的户名中国电信的服务(一叫做 PDSN 的东东)对用的用户做配

ctwap 予的限显被限制在 WAP,而 CTNET 则能得完 TCP/IP 的权限通过一手 段,达了中移动 cmnet cmwap 类似。为什这么呢,我觉得应该商业式吧, 让移动来的户能更快适应。国外通常没有这么复

 

 

 

 

2 9530 何上呢。如你打--TCP/IP,那你会 APN 可改,也 就是说没法 CTNET 或者 CTWAP 类的东东。那么以猜RIM 该和中电信一种 协议9530 自动的通过某种号上。通过调试,我现肯不会是 CTNET可能类似 CTWAP 的帐

 

 

 

最后,了,在电信上支持的络连方式总结如下:

 

 

 

 

1果你希通过 WAP 上网, WAP2.0

 

2果你希访 TCP能采用 BES 方式(虽然内黑用户大多都是纯货,有开通 BES,但在930没有这问题买到烧号的950的应该都通过中国信开了企业 服务)

  

4. BlackBerry 5.0 新提供 Network API:自动选择网关的终

极解决方案

从前问看,想在 BlackBerry 上实自动 WAP 接网络似乎复杂。其实在

BlackBerry 5.0 ,这一切都已成往事随着 BlackBerry 5.0 布,其中包含了有用的

API Network API 是用来高网编程效率Network API 包括下类和口:

 

包名:net.rim.device.api.io.transport

 

接口:

 

 

ConnectionAttemptListener This interface prescribes methods for a class that listens for connection attempts performed by a ConnectionFactory object.

 

 

类:

 

 


 

ConnectionDescriptor


This class stores information about a Connection opened by using a

ConnectionFactory.


 

 

ConnectionFactory      This class enables you to create HTTP, HTTPS, socket, TLS, and SSL

connections over supported transports.

 

 

TransportDescriptor    This class encapsulates information related to a specific transport instance.

 

 

TransportInfo               This class provides methods that provide information about the transport types available on a BlackBerry device.

 

 

 

 

其中的 ConnectionFactory 可以开发员自动选择多种接方,也可以设置重次数自动支

 HTTPS  SSL/TLS下是一例子:

 

根据自动搜索,第一条发现的通道(由系统来决定)来建立 HTTP :

 

// Create ConnectionFactory

 

ConnectionFactory factory = new ConnectionFactory();

 

 

 

// use the factory to get a connection

 

ConnectionDescriptor conDescriptor =

factory.getConnection("http://www.blackberry.com");//不设任何参数


  

if ( conDescriptor != null ) {

 

 

// connection succeeded int transportUsed =

conDescriptor.getTransportDescriptor().getTransportType();

 

 

 

// using the connection

 

HttpConnection    httpCon = (HttpConnection) conDescriptor.getConnection();

 

...

 

}

 

设定一个连接方式列表,按照预设定的优先顺序来建立 HTTP 连接:

 

// make a list of transport types ordered according to preference (they will be tried in succession)

 

int[] preferredTransportTypes = {TransportInfo.TRANSPORT_MDS, TransportInfo.TRANSPORT_WAP2};//连接表,第优先BES 方式第二优WAP2 方式

 

 

 

 

// Create ConnectionFactory

 

ConnectionFactory factory = new ConnectionFactory();

 

 

 

// Configure the factory

 

factory.setPreferredTransportTypes( preferredTransportTypes );

 

 

 

// use the factory to get a connection

 

ConnectionDescriptor conDescriptor =

factory.getConnection("http://www.blackberry.com");

 

 

 

if ( conDescriptor != null ) {

 

 

 

//  connection suceeded

 

 

int transportUsed =

conDescriptor.getTransportDescriptor().getTransportType();

 

 

 

// using the connection

 

HttpConnection    httpCon = (HttpConnection) conDescriptor.getConnection();

 

...

 

}

 

设定一项特定的通道类型来建立 HTTP 连接:

 

// Create ConnectionFactory

 

ConnectionFactory factory = new ConnectionFactory();

 

 

 

// use the factory to get a connection

 

ConnectionDescriptor conDescriptor = factory.getConnection("http://www.blackberry.com", TransportInfo.TRANSPORT_WAP2, null);

 

 

 

if ( conDescriptor != null ) {

 

 

 

// connection over WAP2 succeeded

 

// using the connection

 

HttpConnection    httpCon = (HttpConnection) conDescriptor.getConnection();

 

...

 

}

 

设定一条具体的通道来建立 HTTP 连接:

 

// Create ConnectionFactory

 

ConnectionFactory factory = new ConnectionFactory();

 

 

// use the factory to get a connection

 

ConnectionDescriptor conDescriptor = factory.getConnection("http://www.blackberry.com", TransportInfo.TRANSPORT_MDS, "S109234");

  

if ( conDescriptor != null ) {

 

 

 

// connection to specific BES succeeded

 

// using the connection

 

HttpConnection    httpCon = (HttpConnection) conDescriptor.getConnection();

 

...

 

}

 

 

 

 

 

 

5. 网络设置解决案举 以上介了各网络连接的代码现,内黑莓开发初学在设计的时候,头疼一个 问题就网络置。

 

BlackBerry 与其他手机不同的,多好几种联网方式如何这些整合在你的置里,让 用户自来选希望的联网通道国外多成熟的应用这面早已经很完美的解了。

 

这里拿外某票软件做络连上这个应用是基于 Socket HTTP 我们首来看的设置首页,提四种BIS,BES,TCP,WiFi

补充介一下这个软件底层是 TCP/IP 的,否则的,如是基于 WAP 件,通应该

再加上 WAP  APN 置。
另外,据实情况,有的软件能需加上“自动选择络”并将其设为默认项。

 

 

 

BlackBerry 网络连接编程_第1张图片 

 

        6.  HTTP 连接代

 

以下这例子很完善,因为没包括 WAP WAP2 接,在前做了很分的 讨论,过这代码还是满足绝部分况下的需求,而同时 GET POST

 

public static final int CONNECTION_DEFAULT = 0;

 

public static final int CONNECTION_BIS = 1; public static final int CONNECTION_BES = 2; public static final int CONNECTION_TCPIP = 3; public static final int CONNECTION_WIFI = 4;

 

 

 

public boolean get(String url) {

 

service(url, null);

 

}

 

 

 

 

public boolean post(String url, URLEncodedPostData postdata) {

 

service(url, postdata);

 

}

 

 

 

 

private boolean service(String url, URLEncodedPostData postdata) { HttpConnection con = null;

InputStream in = null;

 

 

 

 

try {

 

if (CoverageInfo.isOutOfCoverage())

 

return false;

 

 

 

 

byte[] data = null;

 

if (postdata != null) {

 

data = postdata.getBytes();

 

}

 

 

 

 

// If WLAN is active, try wlan

 

if ((RadioInfo.getActiveWAFs() & RadioInfo.WAF_WLAN) != 0) {

 

try {

 

if (CoverageInfo.isCoverageSufficient( CoverageInfo.COVERAGE_CARRIER, RadioInfo.WAF_WLAN, false))

{

 

con = HttpUtils.makeHttpConnection(

 

url, new HttpHeaders(), data, CONNECTION_WIFI);

con.getResponseCode();

 

}

 

} catch (Exception ex) { Log.error("UP.R.WF: " + ex); con = null;

}

 

}

 

 

 

 

// Otherwise try the preferred connection type. if (con == null) {

 

try {

 

con = HttpUtils.makeHttpConnection(

 

url, new HttpHeaders(), data, IOPreferences.getPreferredConnectionType());

con.getResponseCode();

 

} catch (Exception ex) { Log.error("UP.R1: " + ex); con = null;

}

 

}

 

 

 

 

if (con == null) {

 

// If preferred type doesnot work, find something else. int ctype = getCoverageBasedConnectionType();

if (ctype >= 0) {

 

try {

 

con = HttpUtils.makeHttpConnection(url, new HttpHeaders(), data, ctype);

con.getResponseCode();

 

} catch (Exception ex) { Log.error("UP.R2: " + ex); con = null;

}

 

}

 

}

 

 

 

 

 

int respcode = con.getResponseCode();

 

 

 

 

// You can handle HTTP_MOVED_* here if you want to

 

// We don't because we  connect to our own servers

 

if (respcode == HttpConnection.HTTP_OK) {

 

in = con.openInputStream();

 

 

 

 

// Handle incoming data handleData(con, in);

 

 

 

return true;

 

}

 

} catch (Exception e) { Log.error("UP.R() : " + e);

} finally {

 

close(con, in);

 

}

 

 

 

 

return false;

 

}

 

 

 

 

protected abstract void handleData(HttpConnection con, InputStream in);

 

 

 

 

private static void close(HttpConnection con, InputStream in) {

 

 

 

if (in != null) {

 

try {

 

in.close();

 

} catch (IOException e2) {

 

}

 

}

 

if (con != null) { try { con.close();

} catch (IOException e) {

 

}

 

}

 

}

 

 

 

 

 

public static int getCoverageBasedConnectionType() {

 

if (CoverageInfo.isCoverageSufficient(CoverageInfoProxy.COVERAGE_CARRIER, RadioInfo.WAF_WLAN))

{

 

return IOConstants.CONNECTION_WIFI;

 

}

 

 

 

 

if (CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_BIS_B)) {

 

return IOConstants.CONNECTION_BIS;

 

}

 

 

 

 

 

 

 

if (CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_MDS)) {

 

return IOConstants.CONNECTION_BES;

 

}

 

 

 

 

return IOConstants.CONNECTION_DEFAULT;

 

}

Finally the method to make the http connection class HttpUtils {

 

public static final int CONNECTION_DEFAULT = 0;

 

public static final int CONNECTION_BIS = 1; public static final int CONNECTION_BES = 2; public static final int CONNECTION_TCPIP = 3; public static final int CONNECTION_WIFI = 4;

 

 

 

/**

 

* This method opens a HTTP connection to the given url. The method used is

 

* GET or POST depending on whether postData is null or not. Only the

 

* provided connType is used. For example, if the connType is

 

* CONNECTION_BES, the connection is tried using the BES only.

 

* The only time provided connection type is not used is when the URL

 

* contains ";deviceside=".

 

*

 

 

* @param url

 

*             The url to connect to.

 

* @param requestHeaders

 

*             The headers in the request. May be null or empty.

 

* @param postData

 

*             Data to be posted to the server. If null, the GET method used

 

*             for the http connection.

 

* @param connType

 

*             The type of transport (BES / BIS / WIFI / Default) to be used

 

*             for opening connection.

 

* @return Opened HttpConnection object or null if some error occurs.

 

*/

 

public static HttpConnection makeHttpConnection(String url, HttpHeaders requestHeaders, byte[] postData, int connType) {

HttpConnection conn = null; OutputStream out = null;

 

 

 

if (StringUtilities.startsWithIgnoreCase(url, "www.")) {

 

url = "http://" + url;

 

}

 

 

 

 

try {

 

if (url.indexOf(";deviceside=") == -1) {

 

switch (connType) {

 

case CONNECTION_BES:


                                                                        url = url + ";deviceside=false";

 

break;

 

case CONNECTION_BIS:

 

url = url + ";XXXXXXXXXXXXXXXX";

 

break;

 

case CONNECTION_TCPIP:

 

url = url + ";deviceside=true";

 

break;

 

case CONNECTION_WIFI:

 

url = url + ";interface=wifi";

 

}

 

}

 

 

 

 

conn = (HttpConnection) Connector.open(url);

 

 

 

 

if (requestHeaders != null) {

 

String referer = requestHeaders.getPropertyValue("referer");

 

 

 

 

boolean sendReferrer = true;

 

 

 

 

if (referer != null && StringUtilities.startsWithIgnoreCase(referer, "https:") &&

!StringUtilities.startsWithIgnoreCase(url, "https:")) {

 

sendReferrer = false;

 

}

 

                                            int size = requestHeaders.size();

 

for (int i = 0; i < size;) {

 

String header = requestHeaders.getPropertyKey(i);

 

// remove header if needed

 

if (!sendReferrer && header.equals("referer")) {

 

requestHeaders.removeProperty(i);

 

--size;

 

continue;

 

}

 

 

 

 

String value = requestHeaders.getPropertyValue(i++);

 

if (value != null) {

 

conn.setRequestProperty(header, value);

 

}

 

}

 

}

 

 

 

 

if (postData == null) { conn.setRequestMethod(HttpConnection.GET); conn.setRequestProperty("User-Agent",

"Profile/MIDP-2.0 Configuration/CLDC-1.0");

 

} else { conn.setRequestMethod(HttpConnection.POST); conn.setRequestProperty(

 

                                                                      H ttpProtocolConstants.HEADER_CONTENT_LENGTH,

 

String.valueOf(postData.length));

 

conn.setRequestProperty("Content-Type",

 

"application/x-www-form-urlencoded");

 

conn.setRequestProperty("User-Agent",

 

"Profile/MIDP-2.0 Configuration/CLDC-1.0");

 

 

 

 

out = conn.openOutputStream();

 

out.write(postData);

 

out.flush();

 

}

 

} catch (IOException e1) { Log.error("UTIL.HTC " + e1);

close(conn, null); // Close the connection

 

conn = null;

 

} finally {

 

close(null, out); // Close the output, but keep connection open

 

}

 

 

 

 

return conn;

 

}

 

 

 

 

private static void close(HttpConnection con, OutputStream out) {

 

if (out != null) {

 

try {

 

 

 

out.close();

 

} catch (IOException e2) {

 

}

 

}

 

if (con != null) { try { con.close();

} catch (IOException e) {

 

}

 

}

 

}

 

}

 

 

 

 
 

 

 

BlackBerry SDK下载

 

  • BlackBerry Java Plug-in for Eclipse v1.1
  • Java Plug-in for Eclipse Update Site
  • BlackBerry Web Plug-in v2.0
  • BlackBerry Widget SDK v1.0
  • BlackBerry Theme Studio v5.0
  • Plazmic Content Developer’s Kit v4.7
  • BlackBerry smartphone simulators
  • 你可能感兴趣的:(网络,service,null,url,BlackBerry,WAP)