BlackBerry的聯網(HTTP/SOCKET)方式分爲五種:
第一種: BES(Blackberry enterprise Server)
該方式是通過假設企業級Blackberry服務器,來負責客戶端與服務器交互,通過使用BES的MDS service來進行網絡連接,負責數據的請求與加密等服務。
所以blackberry規範中約定如果使用BES服務,那麼url必須要被重寫,例如
http://www.myserver.com 原生的地址要重寫爲 http://www.myserver.com;deviceside=false
第二種:BIS(Blackberry internet Service)
該服務是Blackberry自己的互聯網服務,並開放給第三方合作伙伴。比如說中國移動與加拿大的RIM聯合合作推出了電子郵件的推送服務,都是由BIS來承載的。
同樣,如果您的企業要使用該服務的前提是必須要與RIM公司進行合作,在這裏我們稱爲“入盟”。
使用BIS服務的網絡url也需要被重寫:
http://www.myservice.com;deviceside=false;connectionUID="本地uid";ConnectionType=mds-public
本地uid需要從servicebook讀取,之後會講解servicebook的原理和解析方式。
第三種:WAP2
如果要連接WAP2.0網關,你需要在連接時指定service record ,以及UID,後面會有代碼解讀。
網絡連接的url被重寫爲 www.myservice.com;deviceside=true;ConnectionUID="UID"
第四種:WIFI
直接在url後面加入參數 interface=wifi
第五種:DIRECT TCP
需要在url後面跟參數 device=true
好了,說完了這五種連接方式,再說下servicebook,網上不少人叫它傻逼(SB),呵呵,原名“服務預訂”,我沒有很深刻的理解這個概念,總之我覺得就是聯網選擇的服務參數表,你選擇什麼樣的網絡服務,就需要在servicebook中選擇合適的參數,比如說UID。
讀取servicebook代碼:
/**
* 讀servicebook
*/
public void readServiceBook() {
ServiceBook sb = ServiceBook.getSB();
ServiceRecord[] records = sb.getRecords();
for (int i = 0; i < records.length; i++) {
ServiceRecord myRecord = records[i];
String cid, uid;
if (myRecord.isValid() && !myRecord.isDisabled()) {
cid = myRecord.getCid().toLowerCase();
uid = myRecord.getUid().toLowerCase();
// BIS
if (cid.indexOf("ippp") != -1 && uid.indexOf("gpmds") != -1) {
bisUid = myRecord.getUid();
}
// WIFI
if (cid.indexOf("wptcp") != -1 && uid.indexOf("wifi") != -1) {
wifiUid = myRecord.getUid();
}
// Wap2.0
if (cid.indexOf("wptcp") != -1 && uid.indexOf("wifi") == -1
&& uid.indexOf("mms") == -1) {
wap2Uid = myRecord.getUid();
}
}
}
}
接下來,講一下,我在實際項目中的一個需求案例,這裏的要求,終端聯網策略有兩種,一種是自動選擇網絡連接,一種是手動選擇,自動選擇就不多說了,就是遇到可用網絡就優先嚐試連接,直到連接成功位置,手動選擇分爲四種,BIS WIFI WAP2 DRIECT/TCP,用戶可以手動選擇4中網絡方式進行連接。
那麼發一下我的代碼,供大家參考:
/**
* FileName: AccessPoint.java
* All rights Reserved, Designed By 21winmess
* Copyright: Copyright(C) 2011-2012
* Company 21winmess DaLian LTD.
* @author: Gordon Bi
* @version V2.0
* Createdate: 2012-8-3 下午4:33:09
*
* Modification History:
* Date Author Version Discription
* -----------------------------------------------------------------------------------
* 2012-8-3 Qute for BlackBerry
* Why & What is modified: <修改原因描述>
*/
package org.blz.net;
import org.blz.rms.RmsFacade;
import org.blz.rms.RmsSeed;
import net.rim.device.api.servicebook.ServiceBook;
import net.rim.device.api.servicebook.ServiceRecord;
import net.rim.device.api.system.CoverageInfo;
import net.rim.device.api.system.WLANInfo;
/**
* @ClassName: AccessPoint
* @Description:接入點能力
* @author: GordonBi
* @date: 2012-8-3 下午4:33:09
*
*/
public class APN {
public static int WIFI = 1;
public static int BIS = 2;
public static int WAP = 3;
public static int DIRECT_TCP = 4;
public static int AUTO_SELECT = 5;
public static int currentAPN = -1;// 當前接入點方式
public static boolean isManualSelectAPN = false;// 是否手動選擇APN 默認
public String bisUid = null;
public String wifiUid = null;
public String wap2Uid = null;
public String currentSocketUrl = "";
/**
* 根據當前APN,重寫socket url地址
* @param url
* @return
*/
public String rewriteSocketUrl(String url) {
switch (currentAPN) {
case 1:
currentSocketUrl = getWIFIURL(url);
break;
case 2:
currentSocketUrl = getBISURL(url, bisUid);
break;
case 3:
currentSocketUrl = getWAP2URL(url, wap2Uid);
break;
case 4:
currentSocketUrl = getDirectTCP(url);
break;
}
return currentSocketUrl;
}
/**
* 手動選擇APN聯網方式
*
* @param conncetionMethod
* @return
*/
public void manualSelectAPN(int conncetionMethod) {
switch (conncetionMethod) {
case 1:
currentAPN = WIFI;
break;
case 2:
currentAPN = BIS;
break;
case 3:
currentAPN = WAP;
break;
case 4:
currentAPN = DIRECT_TCP;
break;
}
RmsFacade.setBoolean(RmsSeed.IS_MANUAL_SELECT_APN, true);
RmsFacade.setInt(RmsSeed.APN_SETTING, currentAPN);// 設置當前接入點
isManualSelectAPN = true;
}
/**
* 自動檢測APN,選擇最優聯網方式
*
* @return
*/
public void autoSelectAPN() {
if (CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_DIRECT)) {
currentAPN = DIRECT_TCP;
}
if (CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_BIS_B)) {
currentAPN = BIS;
}
if (CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_DIRECT)) {
if (wap2Uid != null && !"".equals(wap2Uid)) {
currentAPN = WAP;
}
}
if (WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED) {
currentAPN = WIFI;
}
RmsFacade.setInt(RmsSeed.APN_SETTING, currentAPN);// 設置當前接入點
RmsFacade.setBoolean(RmsSeed.IS_MANUAL_SELECT_APN, false);
isManualSelectAPN = false;
}
/**
* 讀servicebook
*/
public void readServiceBook() {
ServiceBook sb = ServiceBook.getSB();
ServiceRecord[] records = sb.getRecords();
for (int i = 0; i < records.length; i++) {
ServiceRecord myRecord = records[i];
String cid, uid;
if (myRecord.isValid() && !myRecord.isDisabled()) {
cid = myRecord.getCid().toLowerCase();
uid = myRecord.getUid().toLowerCase();
// BIS
if (cid.indexOf("ippp") != -1 && uid.indexOf("gpmds") != -1) {
bisUid = myRecord.getUid();
}
// WIFI
if (cid.indexOf("wptcp") != -1 && uid.indexOf("wifi") != -1) {
wifiUid = myRecord.getUid();
}
// Wap2.0
if (cid.indexOf("wptcp") != -1 && uid.indexOf("wifi") == -1
&& uid.indexOf("mms") == -1) {
wap2Uid = myRecord.getUid();
}
}
}
}
// ================build url by different connection
// method=================//
public static String getWIFIURL(String url) {
if (url != null && !"".equals(url)) {
return url + ";interface=wifi";
} else {
return "";
}
}
public static String getBISURL(String url, final String bisUid) {
if (url != null && !"".equals(url) && bisUid != null
&& !"".equals(bisUid)) {
return url + ";deviceside=false;connectionUID=" + bisUid
+ ";ConnectionType=mds-public";
} else {
return "";
}
}
public static String getWAP2URL(String url, final String wap2Uid) {
if (url != null && !"".equals(url) && wap2Uid != null
&& !"".equals(wap2Uid)) {
return url + ";deviceside=true" + ";ConnectionUID=" + wap2Uid;
} else {
return "";
}
}
public static String getDirectTCP(String url) {
if (url != null && !"".equals(url)) {
return url + ";deviceside=true";
} else {
return "";
}
}
// ===============================================================//
// ======================單例模式===========================//
private static APN mSingleInstance = null;
private static Object mSyncObject = new Object();
public static APN getSingleInstance() {
synchronized (mSyncObject) {
if (mSingleInstance == null)
mSingleInstance = new APN();
}
return mSingleInstance;
}
private APN() {
readServiceBook();
// autoSelectAPN();
}
public static String getAPNAlice(int apnIndex){
String apnAlice = "";
switch (apnIndex) {
case 1:
apnAlice = "WIFI";
break;
case 2:
apnAlice = "BIS-B";
break;
case 3:
apnAlice = "WAP";
break;
case 4:
apnAlice = "DRTCP";
break;
}
return apnAlice;
}
}