This class aims to simplify HTTP requests on the BlackBerry platform. It could be extended for other uses (socket, specifically), but that exercise is left up to the reader. Use of this class will require signing your application using RIM supplied signing keys. The BlackBerry platform provides a multitude of different transports for network access. These include WiFi, BES, BIS, WAP2 and Direct TCP. Not all transports are available on all devices, carriers or service plans. Ordinarily an application must determine on its own which transports are available for a given device, and attempt to connect via them in order.
Sample use of my HttpConnectionFactory class:
HttpConnectionFactory factory = new HttpConnectionFactory("websiteurl/test.txt", HttpConnectionFactory.TRANSPORT_WIFI | HttpConnectionFactory.TRANSPORT_BES); while (true) { try { HttpConnection connection = factory.getNextConnection(); try { connection.setRequestMethod("POST"); connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded"); OutputStream os = connection.openOutputStream(); os.write("foo=bar&var2=val2".getBytes()); os.close(); InputStream is = connection.openInputStream(); //do something with the input stream if ("whatever we did worked ") { break; } } catch (IOException) { //Log the error or store it for displaying to the end user if no transports succeed } } catch (IOException e) { //There are no more transports to attempt //Note you should never attempt network activity on the event thread Dialog.alert("Unable to perform request"); break; } }
HttpConnectionFactory.java
import java.io.IOException; import java.util.Vector; import javax.microedition.io.Connector; import javax.microedition.io.HttpConnection; 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.RadioInfo; /** * @author * @version 1.0 */ public class HttpConnectionFactory { /** * Specifies that only wifi should be used */ public static final int TRANSPORT_WIFI = 1; /** * Specifies that only BES (also known as MDS or corporate servers) */ public static final int TRANSPORT_BES = 2; /** * Specifies that only BIS should be used (Basically RIM hosted BES) */ public static final int TRANSPORT_BIS = 4; /** * Specifies that TCP should be used (carrier transport) */ public static final int TRANSPORT_DIRECT_TCP = 8; /** * Specifies that WAP2 should be used (carrier transport) */ public static final int TRANSPORT_WAP2 = 16; /** * Equivalent to: TRANSPORT_WIFI | TRANSPORT_BES | TRANSPORT_BIS | TRANSPORT_DIRECT_TCP | TRANSPORT_WAP2 */ public static final int TRANSPORTS_ANY = TRANSPORT_WIFI | TRANSPORT_BES | TRANSPORT_BIS | TRANSPORT_DIRECT_TCP | TRANSPORT_WAP2; /** * Equivalent to: TRANSPORT_WIFI | TRANSPORT_BES | TRANSPORT_BIS */ public static final int TRANSPORTS_AVOID_CARRIER = TRANSPORT_WIFI | TRANSPORT_BES | TRANSPORT_BIS; /** * Equivalent to: TRANSPORT_DIRECT_TCP | TRANSPORT_WAP2 */ public static final int TRANSPORTS_CARRIER_ONLY = TRANSPORT_DIRECT_TCP | TRANSPORT_WAP2; /** * The default order in which selected transports will be attempted * */ public static final int DEFAULT_TRANSPORT_ORDER[] = { TRANSPORT_WIFI, TRANSPORT_BES, TRANSPORT_BIS, TRANSPORT_DIRECT_TCP, TRANSPORT_WAP2 }; private static final int TRANSPORT_COUNT = DEFAULT_TRANSPORT_ORDER.length; private static ServiceRecord srMDS[], srBIS[], srWAP2[], srWiFi[]; private static boolean serviceRecordsLoaded = false; private int curIndex = 0; private int curSubIndex = 0; private String url; private String extraParameters; private int transports[]; private int lastTransport = 0; public HttpConnectionFactory(String url) { this(url, null, 0); } public HttpConnectionFactory(String url, int allowedTransports) { this(url, null, allowedTransports); } public HttpConnectionFactory(String url, int transportPriority[]) { this(url, null, transportPriority); } public HttpConnectionFactory(String url, String extraParameters, int allowedTransports) { this(url, extraParameters, transportMaskToArray(allowedTransports)); } public HttpConnectionFactory(String url, String extraParameters, int transportPriority[]) { if (!serviceRecordsLoaded) { loadServiceBooks(false); } if (url == null) { throw new IllegalArgumentException("Null URL passed in"); } if (!url.toLowerCase().startsWith("http")) { throw new IllegalArgumentException("URL not http or https"); } this.url = url; this.extraParameters = extraParameters; transports = transportPriority; } public HttpConnection getNextConnection() throws IOException { HttpConnection con = null; int curTransport = 0; while (con == null && curIndex < transports.length) { curTransport = transports[curIndex]; switch (curTransport) { case TRANSPORT_WIFI: curIndex++; curSubIndex = 0; try { con = getWifiConnection(); } catch (Exception e) {} break; case TRANSPORT_BES: curIndex++; curSubIndex = 0; try { con = getBesConnection(); } catch (Exception e) {} break; case TRANSPORT_BIS: while (con == null) { try { con = getBisConnection(curSubIndex++); } catch (IOException e) { curIndex++; curSubIndex = 0; break; } catch (Exception e) {} } break; case TRANSPORT_DIRECT_TCP: curIndex++; try { con = getTcpConnection(); } catch (Exception e) {} break; case TRANSPORT_WAP2: while (con == null) { try { con = getWap2Connection(curSubIndex++); } catch (IOException e) { curIndex++; curSubIndex = 0; break; } catch (Exception e) {} } break; } } if (con == null) { throw new IOException(); } lastTransport = curTransport; return con; } public int getLastTransport() { return lastTransport; } private HttpConnection getBisConnection(int index) throws IOException { if (index >= srBIS.length) { throw new IOException("Out of BIS transports"); } ServiceRecord sr = srBIS[index]; return getConnection(";deviceside=false;connectionUID=", sr.getUid()); } private HttpConnection getBesConnection() throws IOException { if (CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_MDS)) { return getConnection(";deviceside=false", null); } return null; } private HttpConnection getWifiConnection() throws IOException { if (RadioInfo.areWAFsSupported(RadioInfo.WAF_WLAN) && (RadioInfo.getActiveWAFs() & RadioInfo.WAF_WLAN) != 0 && CoverageInfo.isCoverageSufficient(1, RadioInfo.WAF_WLAN, false)) { return getConnection(";deviceside=true;interface=wifi", null); } return null; } private HttpConnection getWap2Connection(int index) throws IOException { if (index >= srWAP2.length) { throw new IOException("Out of WAP2 transports"); } if (CoverageInfo.isCoverageSufficient(1)) { ServiceRecord sr = srWAP2[index]; return getConnection(";deviceside=true;ConnectionUID=", sr.getUid()); } return null; } private HttpConnection getTcpConnection() throws IOException { if (CoverageInfo.isCoverageSufficient(1)) { return getConnection(";deviceside=true", null); } return null; } private HttpConnection getConnection(String transportExtras1, String transportExtras2) throws IOException { StringBuffer fullUrl = new StringBuffer(); fullUrl.append(url); if (transportExtras1 != null) { fullUrl.append(transportExtras1); } if (transportExtras2 != null) { fullUrl.append(transportExtras2); } if (extraParameters != null) { fullUrl.append(extraParameters); } return (HttpConnection) Connector.open(fullUrl.toString()); } public static void reloadServiceBooks() { loadServiceBooks(true); } private static synchronized void loadServiceBooks(boolean reload) { if (serviceRecordsLoaded && !reload) { return; } ServiceBook sb = ServiceBook.getSB(); ServiceRecord[] records = sb.getRecords(); Vector mdsVec = new Vector(); Vector bisVec = new Vector(); Vector wap2Vec = new Vector(); Vector wifiVec = new Vector(); if (!serviceRecordsLoaded) { 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) { bisVec.addElement(myRecord); } // WAP1.0: Not implemented. // BES if (cid.indexOf("ippp") != -1 && uid.indexOf("gpmds") == -1) { mdsVec.addElement(myRecord); } // WiFi if (cid.indexOf("wptcp") != -1 && uid.indexOf("wifi") != -1) { wifiVec.addElement(myRecord); } // Wap2 if (cid.indexOf("wptcp") != -1 && uid.indexOf("wap2") != -1) { wap2Vec.addElement(myRecord); } } } srMDS = new ServiceRecord[mdsVec.size()]; mdsVec.copyInto(srMDS); mdsVec.removeAllElements(); mdsVec = null; srBIS = new ServiceRecord[bisVec.size()]; bisVec.copyInto(srBIS); bisVec.removeAllElements(); bisVec = null; srWAP2 = new ServiceRecord[wap2Vec.size()]; wap2Vec.copyInto(srWAP2); wap2Vec.removeAllElements(); wap2Vec = null; srWiFi = new ServiceRecord[wifiVec.size()]; wifiVec.copyInto(srWiFi); wifiVec.removeAllElements(); wifiVec = null; serviceRecordsLoaded = true; } } private static int[] transportMaskToArray(int mask) { if (mask == 0) { mask = TRANSPORTS_ANY; } int numTransports = 0; for (int i = 0; i < TRANSPORT_COUNT; i++) { if ((DEFAULT_TRANSPORT_ORDER[i] & mask) != 0) { numTransports++; } } int transports[] = new int[numTransports]; int index = 0; for (int i = 0; i < TRANSPORT_COUNT; i++) { if ((DEFAULT_TRANSPORT_ORDER[i] & mask) != 0) { transports[index++] = DEFAULT_TRANSPORT_ORDER[i]; } } return transports; } }