You are on page 1of 84

BlackBerry Java SDK

Networking and connectivity Version: 7.0 Beta


Development Guide

Published: 2011-05-31 SWD-1683136-0530104202-001

Contents
1 Networking and connectivity overview............................................................................................................ 2 Network connections........................................................................................................................................ Architecture: Network transports..................................................................................................................... Code sample: Determining network transports with sufficient coverage using the Network API............ Code sample: Determining the status of a network transport using the Network API............................. The Network API............................................................................................................................................... Choosing network transports using the Network API............................................................................... Opening a network connection using the Network API............................................................................ Generic Connection Framework....................................................................................................................... Open a network connection using the GCF............................................................................................... Send and receive data using a network connection......................................................................................... Using the BlackBerry Enterprise Server as a network gateway........................................................................ Using a wireless service provider's Internet gateway....................................................................................... Send and receive data using a network connection......................................................................................... Code sample: Retrieving a web page using the Network API........................................................................... Code sample: Retrieving a web page using the GCF......................................................................................... 3 Communication API.......................................................................................................................................... Communicating with HTTP servers................................................................................................................... Request data using a BlockingSenderDestination object.......................................................................... Request data using a NonBlockingSenderDestination object................................................................... Send data using a FireAndForgetDestination object................................................................................. Parsing a common Internet data format.......................................................................................................... Parse a JSON data structure...................................................................................................................... Code sample: Parsing a JSON data structure............................................................................................. Sending login information to an HTTP server................................................................................................... 4 Subscribing to a push initiator.......................................................................................................................... Subscribe to a push initiator............................................................................................................................. 5 Working with radios.......................................................................................................................................... Query a radio's availability and change its status............................................................................................. Code sample: Controlling radios................................................................................................................ 6 Near Field Communication............................................................................................................................... Working with smart tags................................................................................................................................... Create an NDEF tag writer................................................................................................................................ 3 4 5 7 9 11 11 11 13 14 15 18 18 19 22 26 30 31 32 36 41 42 43 46 50 51 52 54 54 55 58 58 58

Code sample: Creating an NDEF tag writer............................................................................................... Create an NDEF tag reader............................................................................................................................... Code sample: Creating an NDEF tag reader............................................................................................... Communicate with an ISO14443 smart tag...................................................................................................... Code sample: Communicating with an ISO 14443 tag............................................................................... 7 Glossary............................................................................................................................................................ 8 Provide feedback.............................................................................................................................................. 9 Document revision history................................................................................................................................ 10 Legal notice.......................................................................................................................................................

62 65 68 70 72 75 78 79 80

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Networking and connectivity overview

A BlackBerry device uses radio communication technologies such as CDMA, GPRS, or Wi-Fi technology, to communicate over wireless connections. BlackBerry devices work with different network transports over those radio technologies to connect to the Internet or a private network. Each transport offers different advantages. As a developer, you should choose the transport that is most appropriate for your requirements. When you choose a transport for your application, you should consider a number of different factors, including: Type of user Importance of security and reliability Networks that the application must use and support for roaming users Amount of data that you expect to send and receive Need to proactively push data for updates and alerts Location of the destination server (Internet or intranet) The BlackBerry Java SDK 7.0 includes the following APIs that you can use to open a network connection. BlackBerry Device Software version The Network API provides a simple interface to access many 5.0 and later connection-related options and network transports. The GCF provides a flexible way to create network 4.0 and later connections using the transport of your choice. The Communication API encapsulates all of the operations 6.0 and later that are required to connect to an HTTP server that is located on the Internet or behind an organization's firewall.

API Network API Generic Connection Framework Communication API

Description

In addition to the functionality that each API provides, you should consider whether the API exists in the version of the BlackBerry Device Software that your target devices are likely to run. For example, the Communication API requires BlackBerry Device Software 6.0. You would need to write your own code to perform similar tasks on devices that run BlackBerry Device Software 5.0 and earlier. The BlackBerry solution also enables server-side applications to proactively push data to BlackBerry devices in a highly secure and reliable manner. You can also use technologies such as Bluetooth to communicate with accessories, and NFC to communicate with smart tags.

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Network connections

The BlackBerry Application Platform offers two APIs that you can use to create network connections manually: the Network API and the GCF. Applications that target BlackBerry devices that run BlackBerry Device Software 5.0 and later can use the Network API. The Network API provides a simple interface for working with network transports, and setting a wide variety of parameters for a connection. You can use the GCF to create network connections on devices that run previous versions of the BlackBerry Device Software. However, using the GCF requires knowledge of more BlackBerry APIs to discover what transports are available and how to configure them. Regardless of which API you choose, the process of creating a network connection is similar. First, you open a network connection, then read and write data over that connection, and finally close the connection. Before you open a connection, you usually specify a transport, a protocol, and an end point. You can connect to network resources using a wide range of protocols. However, you should be aware that not all transports support all protocols. For example, WAP 1.0 and 1.1 only support HTTP over WAP and HTTPS over WAP or WTLS. The BlackBerry Application Platform supports the following protocols: HTTP HTTPS Socket TLS SSL UDP (Datagram)

The protocol and the end point are determined by your application, but the transport is determined by your users' operating environment. You may need to try more than one transport before you can make a successful connection. The following table suggests preference orders for consumer and enterprise applications that target users on CDMA and GPRS wireless networks. CDMA Consumer 1. 2. 3. 4. 5. Enterprise 1. 2. 3. 4. 5. TCP Wi-Fi TCP Cellular BlackBerry Internet Service WAP 2.0 BlackBerry Mobile Data System BlackBerry MDS TCP Wi-Fi TCP Cellular BlackBerry Internet Service WAP 2.0 GPRS 1. 2. 3. 4. 5. 1. 2. 3. 4. 5. TCP Wi-Fi BlackBerry Internet Service WAP 2.0 BlackBerry Mobile Data System TCP Cellular BlackBerry MDS TCP Wi-Fi BlackBerry Internet Service WAP 2.0 TCP Cellular

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

After you open a connection, you receive a Connection object that represents your connection. The javax.microedition.io package contains several interfaces that you can use to manipulate a Connection object. Interface
HttpConnection

HttpsConnection

SocketConnection SecureConnection

UDPDatagramConnection InputConnection, OutputConnection

Description This interface provides methods to set the HTTP request method (GET, POST, and so on) and headers, and send and receive data over the connection. This interface includes all of the methods in the HttpConnection interface, and adds getSecurityInfo() that returns the certificate that is supplied by the web server. This interface exposes methods to send data to and receive data from a network host over a socket connection. This interface provides methods to create TLS and SSL socket connections. This interface includes all of the methods in the SocketConnection interface, and adds getSecurityInfo() that returns security information about the connection. This interface provides methods to retrieve information about the connection, and create new datagram objects. These interfaces provide access to a connection's input and output data streams.

When you are ready to use your connection, cast the Connection object according to the protocol that you used to open the connection. You will need the InputConnection and OutputConnection interfaces from the javax.microedition.io package to access the Connection object's send and receive functions. Those interfaces expose the Connection object's input and output streams. For more information about sending data over the connection, see the InputStream and OutputStream classes in the API reference for the BlackBerry Java SDK.

Architecture: Network transports


A BlackBerry device can connect to a wireless network by using different transports. Not all devices have access to all transports. For example, the BlackBerry Mobile Data System transport is only available to devices registered with a BlackBerry Enterprise Server.

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Network transport TCP Wi-Fi

Description The Wi-Fi transport creates a connection to the Internet, or to private networks such as those in an organization or home. When the Wi-Fi radio is turned on, a BlackBerry device user or an application can configure the device to connect to the Internet using this transport. If there are multiple transport services available, a device running BlackBerry 6 or later automatically sends data using the fastest data connection. Earlier versions of BlackBerry Device Software send data through the least expensive transport, rather than the fastest.

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Network transport TCP Cellular

Description The TCP Cellular transport creates a connection to the Internet through a wireless service provider's Internet gateway. This method creates the most direct type of connection that uses the cellular radio. Most wireless service providers configure a user's BlackBerry device to use the provider's Internet gateway. However, when the user roams on a different network, the user needs to configure the device manually to use the Internet gateway on the host network. If your application uses this transport, you should test it for each wireless service provider that your application might use. The BlackBerry Internet Service transport creates a connection to the Internet through the BlackBerry Infrastructure. Data that you send and receive using this transport is compressed and optimized for transmission over wireless connections. Note: To use the BlackBerry Internet Service transport, you must sign up for the Push Service. For more information, visit www.blackberry.com/ developers/pushservice The BlackBerry MDS transport enables a BlackBerry device to connect to its associated BlackBerry Enterprise Server through the BlackBerry Infrastructure or using a Wi-Fi connection. The WAP transport creates a connection through a wireless service provider's WAP gateway. WAP 1.0, 1.2, and 2.0 are supported. To support this transport, a user or wireless service provider must configure the WAP connection parameters on the device. As a result, this transport might not be supported on all wireless networks or with all data plans. If your application uses this transport, you should test it for each wireless service provider that your application might use. For more information, see "Using a wireless service provider's Internet gateway". To use WAP 2.0, you will need to retrieve the connection ID from the service book. For more information about retrieving a connection ID, see the knowledge base article at http://supportforums.blackberry.com/t5/JavaDevelopment/What-Is-Network-API-alternative-for-legacy-OS/ta-p/ 614822

BlackBerry Internet Service

BlackBerry MDS

WAP

Code sample: Determining network transports with sufficient coverage using the Network API
import net.rim.device.api.io.transport.*; import net.rim.device.api.ui.*; import net.rim.device.api.ui.component.*; 7

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

import net.rim.device.api.ui.container.*; public class NetworkSample extends UiApplication { public static void main(String[] args) { NetworkSample app = new NetworkSample(); app.enterEventDispatcher(); } public NetworkSample() { pushScreen(new ListTransportsWithCoverageScreen()); } } class ListTransportsWithCoverageScreen extends MainScreen { private private private private int[] _transportsWithCoverage; TransportDescriptor[] _transports; RichTextField _rtfDisplay; ButtonField _btnShowTransports;

public ListTransportsWithCoverageScreen() { VerticalFieldManager vfm = new VerticalFieldManager(); setTitle("Network Sample"); _rtfDisplay = new RichTextField ("Click button below to display available transports."); _btnShowTransports = new ButtonField ("Show Transports", Field.FIELD_HCENTER); _btnShowTransports.setChangeListener(new FieldChangeListener() { public void fieldChanged(Field field, int context) { getTransports(); } }); vfm.add(_rtfDisplay); vfm.add(_btnShowTransports); add(vfm); } public void getTransports() { StringBuffer sb = new StringBuffer(); sb.append("The transports currently available are: \n"); _transportsWithCoverage = TransportInfo.getCoverageStatus(); _transports = TransportInfo.getTransportDescriptors (_transportsWithCoverage); for(int i = _transports.length - 1; i >=0; --i) { switch(_transports[i].getTransportType()) { case TransportInfo.TRANSPORT_BIS_B:

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

} _rtfDisplay.setText(sb.toString());

sb.append("BlackBerry Internet Service\n"); break; case TransportInfo.TRANSPORT_MDS: sb.append("BlackBerry Mobile Data Service\n"); break; case TransportInfo.TRANSPORT_TCP_CELLULAR: sb.append("TCP Cellular\n"); break; case TransportInfo.TRANSPORT_TCP_WIFI: sb.append("TCP WiFi\n"); break; case TransportInfo.TRANSPORT_WAP: sb.append("WAP 1.0 or 1.1\n"); break; case TransportInfo.TRANSPORT_WAP2: sb.append("WAP 2.0\n"); break; }

Code sample: Determining the status of a network transport using the Network API
import import import import net.rim.device.api.io.transport.TransportInfo; net.rim.device.api.ui.*; net.rim.device.api.ui.component.*; net.rim.device.api.ui.container.*;

public class NetworkSample extends UiApplication { public static void main(String[] args) { NetworkSample app = new NetworkSample(); app.enterEventDispatcher(); } public NetworkSample() { pushScreen(new ProbeSpecificTransportScreen()); } } class ProbeSpecificTransportScreen extends MainScreen implements FieldChangeListener { private TextField _tfTransportStatus; private ObjectChoiceField _ocfTransports; public ProbeSpecificTransportScreen() { String[] strTransportNames = {"none", "TCP Cellular", "WAP 1.0/1.1",

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

"WAP 2.0", "MDS", "BIS", "TCP WiFi" }; VerticalFieldManager vfm = new VerticalFieldManager(); _tfTransportStatus = new TextField(Field.FIELD_HCENTER); _tfTransportStatus.setText ("Select a transport from the list above, then click 'Probe Transport'"); _ocfTransports = new ObjectChoiceField ("Select Transport to Probe: ", strTransportNames, 0, Field.FIELD_HCENTER); _ocfTransports.setEditable(true); ButtonField btnProbe = new ButtonField("Probe Transport", Field.FIELD_HCENTER); btnProbe.setChangeListener(this); vfm.add(_ocfTransports); vfm.add(btnProbe); vfm.add(_tfTransportStatus); add(vfm);

public void fieldChanged(Field field, int context) { int intTransportType = _ocfTransports.getSelectedIndex(); if(intTransportType > 0) { if(TransportInfo.isTransportTypeAvailable(intTransportType)) { if(TransportInfo.hasSufficientCoverage(intTransportType)) { _tfTransportStatus.setText ((String)_ocfTransports.getChoice(intTransportType) + " is available."); } else { _tfTransportStatus.setText ((String)_ocfTransports.getChoice(intTransportType) + " is available but has insufficient coverage."); } } else { _tfTransportStatus.setText("Sorry, " + (String)_ocfTransports.getChoice(intTransportType) + " is not available."); } } else { _tfTransportStatus.setText ("Please select a transport first, then click 'Probe Transport'"); } }

10

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

The Network API


The Network API is implemented in the net.rim.device.api.io.transport and net.rim.device.api.io.transport.options packages. Most of the functionality is provided by the ConnectionFactory and TransportInfo classes. A ConnectionFactory object returns a ConnectionDescriptor object that contains a Connection object and information about the transport over

which the connection was opened.

Choosing network transports using the Network API


In the Network API, the TransportInfo class provides information about the network transports that are available on a BlackBerry device. You can retrieve a list of transports that currently have coverage, or use the API to determine whether a particular transport is available and has coverage. If you don't provide an ordered list of preferred transports when you open a connection, the Network API chooses a transport for you. However, you should prioritize the transports that your application uses based on the type of user that your application targets. The API steps through an array of transport types that you set by using ConnectionFactory.setPreferredTransportTypes(). After you list your preferred transports, you should set options for any transports that require specific options. For example, the WAP 1.0 and 1.1 transports require information about an APN, and the gateway authentication, and so on. For more information, see "Network transport options". You should also create a CoverageStatusListener object (in the net.rim.device.api.io.transport package), and register it using TransportInfo.addListener(). The device notifies your application about changes in coverage status so that your application can respond appropriately.

Opening a network connection using the Network API


After you decide which network transports to use, you can open a connection and use it to send and receive data. The ConnectionFactory object is responsible for opening connections. In addition to your preferred transports, you can use the ConnectionFactory to configure connection options such as: Maximum number of connection attempts. Maximum time to spend making connection attempts. Delay between connection attempts. Whether or not encryption is required between the connection end points. When you are ready to open a connection, you should invoke one of the ConnectionFactory.getConnection() methods. Be sure that you call getConnection() on a thread that is separate from the main event thread. For more information about creating a thread, see the Thread class in the API reference for the BlackBerry Java SDK.

11

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

When you open a connection successfully, the ConnectionFactory returns a ConnectionDescriptor object. The ConnectionDescriptor contains a Connection object, and information about the transport that was used to open the connection. For more information, see Open a network connection using the Network API and Send and receive data using a network connection.

Open a network connection using the Network API


CAUTION: The ConnectionFactory.getConnection() method blocks thread execution. You should create a separate thread to call getConnection(). 1. Import the required classes and interfaces.
import import import import net.rim.device.api.io.transport.*; net.rim.device.api.io.transport.options.*; net.rim.device.api.io.transport.TransportInfo; net.rim.device.api.ui.UiApplication;

2.

Create an ordered list of preferred transports.


int[] intTransports = { TransportInfo.TRANSPORT_TCP_WIFI, TransportInfo.TRANSPORT_WAP2, TransportInfo.TRANSPORT_TCP_CELLULAR }

3.

Configure the options for the TCP Cellular transport, if applicable.


TcpCellularOptions tcpOptions = new TcpCellularOptions(); if(!TcpCellularOptions.isDefaultAPNSet()) { tcpOptions.setApn("My APN"); tcpOptions.setTunnelAuthUsername("user"); tcpOptions.setTunnelAuthPassword("password"); }

4. 5.

Create a ConnectionFactory object.


ConnectionFactory factory = new ConnectionFactory();

Set any other ConnectionFactory options that are applicable to your application. In this case, TCP Cellular is one of the preferred transports, so set the TCP Cellular transport options.
factory.setTransportTypeOptions(TransportInfo.TRANSPORT_TCP_CELLULAR, tcpOptions); factory.setAttemptsLimit(5);

6.

Create a thread to retrieve the connection. If the connection was successful, then ConnectionFactory returns a ConnectionDescriptor object that you can use. In this step, pass the ConnectionDescriptor object to another method (displayContent()) that is responsible for displaying the content.
Thread t = new Thread(new Runnable() { public void run() { ConnectionDescriptor cd = _factory.getConnection

12

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

("http://www.blackberry.com"); if(cd != null) { Connection c = cd.getConnection(); displayContent(c); }

}); t.start();

7.

Implement displayContent(). In this case, push a screen that uses a Connection parameter to retrieve and display the content, after the connection retrieval thread completes.
private void displayContent(final Connection conn) { UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { UiApplication.getUiApplication().pushScreen(new HTTPOutputScreen(conn)); } }); }

After you finish: For more information about using a connection and implementing the HTTPOutputScreen class, see "Send and receive data using a network connection". For a complete code sample, see "Code sample: Retrieving a web page using the Network API".

Generic Connection Framework


If you develop applications for BlackBerry device users who are running BlackBerry Device Software 4.7 or earlier, you need to use the GCF to open a network connection. However, any code that you write that uses the GCF also runs on later versions of BlackBerry Device Software. The GCF is implemented in the javax.microedition.io.Connector class. You can call Connector.open() to create any type of supported connection. The open() method accepts a connection string that specifies the type of connection to make, the end point, and optional configuration details for the connection. The connection string that is used by the GCF comprises three parts: <scheme> : <hierarchical location information> ; <additional information> The <scheme> indicates the protocol to use to establish the connection. The <hierarchical location information> describes the end point for the connection. Finally, the <additional information> controls the transport that is used, and provides authentication details for a proxy server if they are required. For more information about transport options, see "Network transport options". For example, in the following code sample, the connection string specifies the HTTP protocol and uses a host name to indicate the connection end point. The interface=wifi parameter is included to specify that the Wi-Fi radio should be used to establish the connection.

13

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

HTTPConnection c = (HTTPConnection)Connector.open("http:// example.com;interface=wifi");

Open a network connection using the GCF


The following task shows you how to open an HTTP connection using the BlackBerry Mobile Data System transport. You can use a similar process to open a connection using other protocols and transports. CAUTION: The Connector.open() method is not thread-safe. Ensure that you invoke open() on a thread that is separate from the main event thread. Before you begin: Make sure that the transport that you want to use is available and has coverage. 1. Import the required classes and interfaces.
import net.rim.device.api.ui.UiApplication; import java.io.IOException; import javax.microedition.io.*;

2.

Create a new thread to open the connection.


Thread t = new Thread(new Runnable() { public void run() {

3. 4.

Create a local variable for your Connection object.


Connection conn = null;

Invoke open(). Specify the connection string.


try {

conn = Connector.open("http://www.blackberry.com;deviceside=false"); } catch (IOException e) { // Process your error condition }

5.

If the connection attempt was successful, open() returns a Connection object that you can use. Pass the connection object to another method (displayContent()) that is responsible for displaying the content.
if (conn != null) { displayContent(conn); }

});

6. 7.

Start your thread.


t.start();

Implement displayContent(). In this case, push a screen that uses a Connection parameter to retrieve and display the content, after the connection retrieval thread completes.

14

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

private void displayContent(final Connection conn) { UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { UiApplication.getUiApplication().pushScreen(new HTTPOutputScreen(conn)); } }); }

After you finish: For more information about using a connection, and implementing the HTTPOutputScreen class, see "Send and receive data using a network connection". For a complete code sample, see "Code sample: Retrieving a web page using the GCF".

Send and receive data using a network connection


The following task shows you how to send and receive data using an HTTP connection to a web site. The data that is returned from the web site is displayed on the screen. You can use a similar process to send and receive data using other network protocols. To make this task as general as possible, the following code sends an HTTP GET command manually to a server. Normally, you would use an HttpConnection interface, which constructs the HTTP command string according to the options that you configure. CAUTION: Network input and output operations are not thread-safe. Make sure that you create a separate thread when you use a Connection object. Before you begin: Open a network connection and pass a Connection object to the constructor of the class that is developed in this task. For more information about opening network connections, see Open a network connection using the Network API or Open a network connection using the GCF. 1. Import the required classes and interfaces.
import import import import import import import net.rim.device.api.ui.container.MainScreen; net.rim.device.api.ui.component.RichTextField; net.rim.device.api.ui.UiApplication; java.io.IOException; java.io.InputStream; java.io.OutputStream; javax.microedition.io.*;

2.

Create a class that extends the MainScreen class.


public class HTTPOutputScreen extends MainScreen {

3. 4.

Create an instance variable for a RichTextField object to display the results.


RichTextField _rtfOutput = new RichTextField();

Create a constructor that accepts a Connection object as an argument.


public HTTPOutputScreen(Connection conn) {

15

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

5.

Add the RichTextField to your screen, and start a thread to access the network connection.
_rtfOutput.setText("Retrieving data. Please wait..."); add(_rtfOutput); ContentReaderThread t = new ContentReaderThread(conn); t.start();

6.

Create a method to populate your RichTextField with the data that is returned from the web site, after ContentReaderThread completes. You invoke this method in step 20.
public void showContents(final String result) { UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { _rtfOutput.setText(result); }

});

7.

In an inner class, create a thread to communicate with the web server. Accept a ConnectionDescriptor object as an argument.
private final class ContentReaderThread extends Thread { private Connection _connection; ContentReaderThread(Connection conn) { _connection = conn; } public void run() {

8.

Initialize an OutputStream object and an InputStream object to exchange data with the web site.
OutputStream os = null; InputStream is = null;

9.

Initialize a String object to store the response from the web site.
String result = "";

10. Create an OutputConnection object to send data over your connection.


try {

OutputConnection outputConn = (OutputConnection) connection;

11. Retrieve an OutputStream from your OutputConnection.


os = outputConn.openOutputStream(); String getCommand = "GET " + "/" + " HTTP/1.0\r\n\r\n"; os.write(getCommand.getBytes()); os.flush();

16

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

12. Send an HTTP GET command to the web server over your OutputStream. Convert the GET command into a byte array.
String getCommand = "GET " + "/" + " HTTP/1.0\r\n\r\n"; os.write(getCommand.getBytes()); os.flush();

13. Create an InputConnection object to receive data from your connection.


InputConnection inputConn = (InputConnection) connection;

14. Retrieve an InputStream from your InputConnection.


is = inputConn.openInputStream();

15. Retrieve the stream data and store it in a byte array.


byte[] data = net.rim.device.api.io.IOUtilities.streamToBytes(is); result = new String(data);

16. Catch any errors that might be generated by your procedure.


catch(Exception e) { result = "ERROR fetching content: " + e.toString(); }

17. Close your OutputStream.


if(os != null) { try { os.close(); } catch(IOException e) { // process the error condition } }

18. Close your InputStream.


if(is != null) { try { is.close(); } catch(IOException e) { } }

19. Close your Connection.

17

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

connection.close(); } catch(IOException ioe) { }

20. Call showContents() that you created in step 6.


} } showContents(result);

Using the BlackBerry Enterprise Server as a network gateway


When you use the BlackBerry Enterprise Server as a network gateway, all traffic between your application and the BlackBerry Enterprise Server is encrypted using AES or triple DES encryption. When you use the BlackBerry Enterprise Server as a network gateway, all traffic between your BlackBerry WebWorks application and the BlackBerry Enterprise Server is encrypted using AES or triple DES encryption. Because the BlackBerry Enterprise Server is located behind the organization's firewall and provides inherent data encryption, applications can communicate with application servers and web servers that are located on the organization's intranet. The BlackBerry Mobile Data System component of the BlackBerry Enterprise Server includes the BlackBerry MDS Services, which provides an HTTP and TCP/IP proxy service to allow the BlackBerry Java Application to use it as a secure gateway for managing HTTP and TCP/IP connections to the intranet. The BlackBerry Mobile Data System component of the BlackBerry Enterprise Server includes the BlackBerry MDS Services, which provides an HTTP and TCP/IP proxy service to allow the BlackBerry WebWorks application to use it as a secure gateway for managing HTTP and TCP/IP connections to the intranet. If your application connects to the Internet, you might be able to use the BlackBerry Enterprise Server as a gateway. Network requests travel behind the organization's firewall to the BlackBerry Enterprise Server, which makes the network request to the Internet through the corporate firewall. Administrators can set an IT policy to make sure that the BlackBerry Enterprise Server is the gateway for all wireless network traffic, including traffic destined for the Internet. If your application connects to the Internet, you can also use either the BlackBerry Internet Service or the Internet gateway of the wireless service provider to manage connections.

Using a wireless service provider's Internet gateway


Most wireless service providers provide an Internet gateway that offers direct TCP/IP connectivity to the Internet. Some wireless service providers also provide a WAP gateway that allows HTTP connections to use the WAP protocol. A BlackBerry Java Application can use either of these gateways to connect to the Internet. A BlackBerry WebWorks application can use either of these gateways to connect to the Internet. If your application is for BlackBerry device users who are on a specific wireless network, using the wireless service provider's Internet gateway can often yield fast, and reliable connections. If your application is for users on a variety of wireless networks, testing
18

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

your application against the different Internet gateways can be challenging. In this case, you should use the BlackBerry Internet Service transport, and use the wireless service providers Internet gateway as a backup connection type if the BlackBerry Internet Service transport is not available.

Send and receive data using a network connection


The following task shows you how to send and receive data using an HTTP connection to a web site. The data that is returned from the web site is displayed on the screen. You can use a similar process to send and receive data using other network protocols. To make this task as general as possible, the following code sends an HTTP GET command manually to a server. Normally, you would use an HttpConnection interface, which constructs the HTTP command string according to the options that you configure. CAUTION: Network input and output operations are not thread-safe. Make sure that you create a separate thread when you use a Connection object. Before you begin: Open a network connection and pass a Connection object to the constructor of the class that is developed in this task. For more information about opening network connections, see Open a network connection using the Network API or Open a network connection using the GCF. 1. Import the required classes and interfaces.
import import import import import import import net.rim.device.api.ui.container.MainScreen; net.rim.device.api.ui.component.RichTextField; net.rim.device.api.ui.UiApplication; java.io.IOException; java.io.InputStream; java.io.OutputStream; javax.microedition.io.*;

2.

Create a class that extends the MainScreen class.


public class HTTPOutputScreen extends MainScreen {

3. 4.

Create an instance variable for a RichTextField object to display the results.


RichTextField _rtfOutput = new RichTextField();

Create a constructor that accepts a Connection object as an argument.


public HTTPOutputScreen(Connection conn) {

5.

Add the RichTextField to your screen, and start a thread to access the network connection.
_rtfOutput.setText("Retrieving data. Please wait..."); add(_rtfOutput); ContentReaderThread t = new ContentReaderThread(conn); t.start();

6.

Create a method to populate your RichTextField with the data that is returned from the web site, after ContentReaderThread completes. You invoke this method in step 20.

19

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

public void showContents(final String result) { UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { _rtfOutput.setText(result); }

});

7.

In an inner class, create a thread to communicate with the web server. Accept a ConnectionDescriptor object as an argument.
private final class ContentReaderThread extends Thread { private Connection _connection; ContentReaderThread(Connection conn) { _connection = conn; } public void run() {

8.

Initialize an OutputStream object and an InputStream object to exchange data with the web site.
OutputStream os = null; InputStream is = null;

9.

Initialize a String object to store the response from the web site.
String result = "";

10. Create an OutputConnection object to send data over your connection.


try {

OutputConnection outputConn = (OutputConnection) connection;

11. Retrieve an OutputStream from your OutputConnection.


os = outputConn.openOutputStream(); String getCommand = "GET " + "/" + " HTTP/1.0\r\n\r\n"; os.write(getCommand.getBytes()); os.flush();

12. Send an HTTP GET command to the web server over your OutputStream. Convert the GET command into a byte array.
String getCommand = "GET " + "/" + " HTTP/1.0\r\n\r\n"; os.write(getCommand.getBytes()); os.flush();

13. Create an InputConnection object to receive data from your connection.


InputConnection inputConn = (InputConnection) connection;

20

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

14. Retrieve an InputStream from your InputConnection.


is = inputConn.openInputStream();

15. Retrieve the stream data and store it in a byte array.


byte[] data = net.rim.device.api.io.IOUtilities.streamToBytes(is); result = new String(data);

16. Catch any errors that might be generated by your procedure.


catch(Exception e) { result = "ERROR fetching content: " + e.toString(); }

17. Close your OutputStream.


if(os != null) { try { os.close(); } catch(IOException e) { // process the error condition } }

18. Close your InputStream.


if(is != null) { try { is.close(); } catch(IOException e) { } }

19. Close your Connection.


{ connection.close(); } catch(IOException ioe) { }

20. Call showContents() that you created in step 6.

21

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

} }

showContents(result);

Code sample: Retrieving a web page using the Network API


To make this code sample as generic as possible, the InputConnection and OutputConnection interfaces are used in place of the HttpConnection interface.
import import import import import import import import net.rim.device.api.io.transport.*; net.rim.device.api.io.transport.options.*; net.rim.device.api.ui.component.RichTextField; net.rim.device.api.ui.container.MainScreen; net.rim.device.api.ui.UiApplication; net.rim.device.api.util.Arrays; java.io.*; javax.microedition.io.*;

public class NetworkSample extends UiApplication { public static void main(String[] args) { NetworkSample app = new NetworkSample(); app.enterEventDispatcher(); } public NetworkSample() { new HTTPConnectionSetup(); } } class HTTPConnectionSetup { ConnectionFactory _factory = new ConnectionFactory(); public HTTPConnectionSetup() { // Create preference ordered list of transports int[] _intTransports = { TransportInfo.TRANSPORT_TCP_WIFI, TransportInfo.TRANSPORT_WAP2, TransportInfo.TRANSPORT_TCP_CELLULAR }; // Remove any transports that are not (currently) available for(int i = 0; i < _intTransports.length ; i++) { int transport = _intTransports[i]; if(!TransportInfo.isTransportTypeAvailable(transport) || !TransportInfo.hasSufficientCoverage(transport)) { 22

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Arrays.removeAt(_intTransports, i);

// Set options for TCP Cellular transport TcpCellularOptions tcpOptions = new TcpCellularOptions(); if(!TcpCellularOptions.isDefaultAPNSet()) { tcpOptions.setApn("My APN"); tcpOptions.setTunnelAuthUsername("user"); tcpOptions.setTunnelAuthPassword("password"); } // Set ConnectionFactory options if(_intTransports.length > 0) { _factory.setPreferredTransportTypes(_intTransports); } _factory.setTransportTypeOptions(TransportInfo.TRANSPORT_TCP_CELLULAR, tcpOptions); _factory.setAttemptsLimit(5); // Open a connection on a new thread Thread t = new Thread(new Runnable() { public void run() { ConnectionDescriptor cd = _factory.getConnection ("http://www.blackberry.com"); // If connection was successful, fetch and show the content from // the web server if(cd != null) { Connection c = cd.getConnection(); displayContent(c); } } }); t.start();

private void displayContent(final Connection conn) { // When the connection thread completes, show the data from the web server UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { UiApplication.getUiApplication().pushScreen(new HTTPOutputScreen(conn)); } }); }

23

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

} class HTTPOutputScreen extends MainScreen { RichTextField _rtfOutput = new RichTextField(); public HTTPOutputScreen(Connection conn) { // Create a container for the data, and put it on the screen _rtfOutput.setText("Retrieving data. Please wait..."); add(_rtfOutput); // Retrieve the data from the web server, using the connection, on a // separate thread ContentReaderThread t = new ContentReaderThread(conn); t.start(); } // After the data has been retrieved, display it public void showContents(final String result) { UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { _rtfOutput.setText(result); }

});

private final class ContentReaderThread extends Thread { private Connection _connection; ContentReaderThread(Connection conn) { _connection = conn; } public void run() { String result = ""; OutputStream os = null; InputStream is = null; try {

// Send HTTP GET to the server OutputConnection outputConn = (OutputConnection) _connection; os = outputConn.openOutputStream(); String getCommand = "GET " + "/" + " HTTP/1.0\r\n\r\n"; os.write(getCommand.getBytes()); os.flush();

24

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

// Get InputConnection and read the server's response InputConnection inputConn = (InputConnection) _connection; is = inputConn.openInputStream(); byte[] data = net.rim.device.api.io.IOUtilities.streamToBytes(is); result = new String(data); // is.close(); } catch(Exception e) { result = "ERROR fetching content: " + e.toString(); } finally { // Close OutputStream if(os != null) { try { os.close(); } catch(IOException e) { } } // Close InputStream if(is != null) { try { is.close(); } catch(IOException e) { } } // Close Connection try { _connection.close(); } catch(IOException ioe) { }

} }

// Show the response received from the web server, or an error message showContents(result);

25

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Code sample: Retrieving a web page using the GCF


This code sample uses the BlackBerry Mobile Data System transport. To make this code sample as generic as possible, the InputConnection and OutputConnection interfaces are used in place of the HttpConnection interface.
import import import import import net.rim.device.api.ui.component.RichTextField; net.rim.device.api.ui.container.MainScreen; net.rim.device.api.ui.UiApplication; java.io.*; javax.microedition.io.*;

public class NetworkSample extends UiApplication { public static void main(String[] args) { NetworkSample app = new NetworkSample(); app.enterEventDispatcher(); } public NetworkSample() { new HTTPConnectionSetup(); } } class HTTPConnectionSetup { public HTTPConnectionSetup() { Thread t = new Thread(new Runnable() { public void run() { Connection c = null; try { c = Connector.open("http://www.blackberry.com;deviceside=false"); } catch (IOException e) { e.printStackTrace(); } if(c != null) { displayContent(c); } } }); t.start();

private void displayContent(final Connection c) { // When the connection thread completes, show the data from the web server UiApplication.getUiApplication().invokeLater(new Runnable()

26

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

} }

});

public void run() { UiApplication.getUiApplication().pushScreen(new HTTPOutputScreen(c)); }

class HTTPOutputScreen extends MainScreen { RichTextField _rtfOutput = new RichTextField(); public HTTPOutputScreen(Connection conn) { // Create a container for the data, and put it on the screen _rtfOutput.setText("Retrieving data. Please wait..."); add(_rtfOutput); // Retrieve the data from the web server, using the connection, on a // separate thread ContentReaderThread t = new ContentReaderThread(conn); t.start(); } // After the data has been retrieved, display it public void showContents(final String result) { UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { _rtfOutput.setText(result); }

});

private final class ContentReaderThread extends Thread { private Connection _connection; ContentReaderThread(Connection conn) { _connection = conn; } public void run() { String result = ""; OutputStream os = null; InputStream is = null; try {

// Send HTTP GET to the server

27

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

OutputConnection outputConn = (OutputConnection) _connection; os = outputConn.openOutputStream(); String getCommand = "GET " + "/" + " HTTP/1.0\r\n\r\n"; os.write(getCommand.getBytes()); os.flush(); // Get InputConnection and read the server's response InputConnection inputConn = (InputConnection) _connection; is = inputConn.openInputStream(); byte[] data = net.rim.device.api.io.IOUtilities.streamToBytes(is); result = new String(data); // is.close(); } catch(Exception e) { result = "ERROR fetching content: " + e.toString(); } finally { // Close OutputStream if(os != null) { try { os.close(); } catch(IOException e) { } } // Close InputStream if(is != null) { try { is.close(); } catch(IOException e) { } } // Close Connection try { _connection.close(); } catch(IOException ioe) { }

// Show the response received from the web server, or an error message showContents(result);

28

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

} }

29

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Communication API

The Communication API simplifies the process of interacting with web services and other applications. The objects that you create using this API automate the process of finding an available network transport, creating a thread-safe connection, and negotiating an exchange of data with the URI or URL end point that you specify. The API is implemented in the net.rim.device.api.io.messaging package. Within the Communication API, URI and URL end points are called destinations. You can use objects that implement the SenderDestination interface to send data to a web service and access the response. Similarly, you can use objects that implement the ReceiverDestination interface to subscribe to a push service and provide access to new messages from that service. You must use the DestinationFactory class to create an object that implements one of the Destination subinterfaces that suits your requirements. Interface
BlockingSenderDestination

Description You can use this interface to send a message to a web service, but this object blocks thread execution while it waits for a response from the web service. Alternatively, BlockingSenderDestination can return a MessageFuture object. This allows thread execution to continue until you invoke one of the get() methods from the MessageFuture. When you invoke sendReceive() in BlockingSenderDestination to send a message and wait for a response, you should not invoke it from the main event thread. You can use this interface to send a message to a web service. In the parameter list, pass your implementation of the MessageListener interface to receive the response from the web service. You can use this interface to subscribe to a push service and block thread execution until you receive confirmation of your subscription request. You can use this interface to subscribe to a push service. In the parameter list, pass your implementation of MessageListener to receive push messages. You can use this interface to send data to a web service when you don't expect a response.

NonBlockingSenderDestination

BlockingReceiverDestination

NonBlockingReceiverDestination

FireAndForgetDestination

Data that you send to and receive from a web service is wrapped in a Message object. You can set the headers and content of the data that is sent to a web service in the Message object. Alternatively, you can allow the Communication API to choose reasonable default values for your request. For example, you can request a web page by invoking SenderDestination.send() without specifying an HTTP GET command.

30

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

MessageProcessor interface with your parser class, you can supply your parser object to the method in DestinationFactory that creates your Destination object. You can then retrieve the parsed response using Message.getObjectPayload().

You can also instruct the API to automatically parse the response data from a web service. If you implement the

The net.rim.device.api.io.parser packages contain message processors for a variety of standard data formats that are used on the Internet. The packages include parsers for: JSON RSS (RDF, Atom) SOAP XML To improve efficiency, the Communication API provides large responses from web services in an InputStream object. An application can request additional data as required rather than downloading a large amount of data at once and storing it in memory on the device. This approach enables you to make better use of both network bandwidth and memory.

Communicating with HTTP servers


To send a command to an HTTP server, you need a SenderDestination object to communicate with an end point. The SenderDestination object is responsible for queuing messages for delivery, and retrieving incoming messages for delivery. The DestinationFactory class creates and maintains a list of Destination objects that you can use to communicate with an end point. Before you create a SenderDestination, you should check whether one exists by invoking getSenderDestination(). You can access an existing destination by providing the name of the Context object that you supplied when you invoked any of the DestinationFactory.create...() methods. When you finish exchanging data with an end point, you should invoke DestinationFactory.release() or DestinationFactory.destory(). The release() method removes the association between a Destination and the inbound and outbound message queues. After you invoke release(), the API continues to attempt the delivery of messages in the queue. You can use release() when your application is not in a state to send and receive messages. In addition to removing the association between a Destination and the a message queue, destroy() also destroys the message queue. After you invoke destory(), any messages in the queue will be deleted. A message contains the details of your command, including the HTTP request method and any additional data that you require. If you do not specify all parameters for your message, default values are provided by the Communication API. After you send your message, you may need to listen for a response. For BlockingSenderDestination objects, you need to create a Thread object when you invoke one of the sendReceive() methods. For NonBlockingSenderDestination objects, you must create a MessageListener object to receive the response. In either case, you need to process a Message object that contains the response. By default, the body of the Message contains the raw response data. You can choose to specify a message processor from the net.rim.device.api.io.parser package, or create your own using the MessageProcessor interface.

31

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

If necessary, you can connect multiple message processors together. The MessageProcessorChain class shares memory between the MessageProcessor objects to improve efficiency. For example, if you receive video data that uses custom encoding and compression, you can separate the decoding and decompression logic into separate message processors, and then use MessageProcessorChain to group them together.

Request data using a BlockingSenderDestination object


1. Import the required classes and interfaces.
import net.rim.device.api.io.messaging.*; import net.rim.device.api.io.URI;

2.

Create a thread from which to call BlockingSenderDestination.sendReceive().


Thread t = new Thread( new Runnable() { public void run() {

3. 4. 5. 6.

Create a Message object to hold the response from the URL.


Message response = null;

Create a URI object to pass to the DestinationFactory class.


URI uri = new URI("http://www.blackberry.com");

Create a BlockingSenderDestination object.


BlockingSenderDestination bsd = null;

Retrieve the BlockingSenderDestination object for your context, if one exists.


try {

bsd = (BlockingSenderDestination) DestinationFactory.getSenderDestination ("MyContext", uri);

7.

If no BlockingSenderDestination exists, create one.


if(bsd == null) { bsd = DestinationFactory.createBlockingSenderDestination (new Context("MyContext"), uri); }

8. 9.

Send a message and wait for the response.


response = bsd.sendReceive();

If the web service sent a response, process the response.

32

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

if(response != null) { processResponse(response); }

10. Catch any errors that occur if the message could not be sent for some reason.
catch (Exception e) { // Process the error }

11. Release the BlockingSenderDestination.


finally { if(bsd != null) { bsd.release(); } }

} });

12. Start the thread.


t.start();

After you finish: If your processResponse() updates the UI, you must do so on the main event thread, not on the thread that you created in this task. For more information, read the knowledge base article at http:// supportforums.blackberry.com/t5/Java-Development/Manage-UI-interactions/ta-p/502378. For a complete code sample, see "Code sample: Requesting data using a BlockingSenderDestination object".

Code sample: Requesting data using a BlockingSenderDestination object


import import import import import import net.rim.device.api.io.messaging.*; net.rim.device.api.io.URI; net.rim.device.api.ui.*; net.rim.device.api.ui.component.*; net.rim.device.api.ui.container.*; java.io.*;

public class NetworkSample extends UiApplication { public static void main(String[] args) { NetworkSample app = new NetworkSample(); app.enterEventDispatcher(); } public NetworkSample() { pushScreen(new BlockingSenderSample());

33

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

class BlockingSenderSample extends MainScreen implements FieldChangeListener { ButtonField _btnBlock = new ButtonField(Field.FIELD_HCENTER); private static UiApplication _app = UiApplication.getUiApplication(); private String _result; public BlockingSenderSample() { _btnBlock.setChangeListener(this); _btnBlock.setLabel("Fetch page"); } add(_btnBlock);

public void fieldChanged(Field button, int unused) { if(button == _btnBlock) { Thread t = new Thread(new Runnable() { public void run() { Message response = null; String uriStr = "http://www.blackberry.com"; BlockingSenderDestination bsd = null; try { bsd = (BlockingSenderDestination) DestinationFactory.getSenderDestination ("CommAPISample", URI.create(uriStr)); if(bsd == null) { bsd = DestinationFactory.createBlockingSenderDestination (new Context("CommAPISample"), URI.create(uriStr) ); } // Send message and wait for response response = bsd.sendReceive(); if(response != null) { BSDResponse(response); }

} catch(Exception e)

34

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

// process the error } finally { if(bsd != null) { bsd.release(); } }

}); t.start(); } }

private void BSDResponse(Message msg) { if (msg instanceof ByteMessage) { ByteMessage reply = (ByteMessage) msg; _result = (String) reply.getStringPayload(); } else if(msg instanceof StreamMessage) { StreamMessage reply = (StreamMessage) msg; InputStream is = reply.getStreamPayload(); byte[] data = null; try { data = net.rim.device.api.io.IOUtilities.streamToBytes(is); } catch (IOException e) { // process the error } if(data != null) { _result = new String(data); } } _app.invokeLater(new Runnable() { public void run() { _app.pushScreen(new HTTPOutputScreen(_result)); } }); } } class HTTPOutputScreen extends MainScreen {

35

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

RichTextField _rtfOutput = new RichTextField(); public HTTPOutputScreen(String message) { _rtfOutput.setText("Retrieving data. Please wait..."); add(_rtfOutput); showContents(message); } // After the data has been retrieved, display it public void showContents(final String result) { UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { _rtfOutput.setText(result); }

});

Request data using a NonBlockingSenderDestination object


Before you begin: To request data using the NonBlockingSenderDestination class, create an object that implements the MessageListener interface. For more information, see "Implement the MessageListener interface". 1. Import the required classes and interfaces.
import net.rim.device.api.io.messaging.*; import net.rim.device.api.io.URI;

2. 3. 4. 5. 6.

Create a Message object to hold the response from the URL.


Message response = null;

Create a URI object to pass to the DestinationFactory class.


URI uri = new URI("http://www.blackberry.com");

Create a NonBlockingSenderDestination object.


NonBlockingSenderDestination nbsd = null;

Create a reference to your MessageListener.


MyMessageListener msgListener = new MyMessageListener();

Retrieve the NonBlockingSenderDestination object for your context, if one exists.

36

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

try {

nbsd = (BlockingSenderDestination) DestinationFactory.getSenderDestination ("MyContext", uri);

7.

If no NonBlockingSenderDestination exists, create one.


if(nbsd == null) { nbsd = DestinationFactory.createNonBlockingSenderDestination (new Context("MyContext"), uri, msgListener); }

8. 9.

Send a message to the web service.


nbsd.send();

Catch any errors that occur if the message could not be sent for some reason.
catch (Exception e) { // Process the error }

After you finish: Release the NonBlockingSenderDestination when you are done processing the response. For a complete code sample, see "Code sample: Request data using a NonBlockingSenderDestination object"

Implement the MessageListener interface


You can use the MessageListener interface to receive messages that are sent by a NonBlockingSenderDestination object, or push messages that are sent from a push initiator. 1. Import the required classes and interfaces.
import net.rim.device.api.io.messaging.*; import java.io.IOException; import java.io.InputStream;

2. 3.

Define a class that implements the MessageListener interface.


public class MyMessageListener implements MessageListener {

Implement onMessage().
public void onMessage(Destination dest, Message incomingMessage) {

4. 5.

Initialize a String variable to hold the response data.


String payload = null;

If the response is a ByteMessage object, retrieve the response as a String and assign it to payload.

37

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

if (incomingMessage instanceof ByteMessage) { ByteMessage reply = (ByteMessage) incomingMessage; payload = (String) reply.getStringPayload(); }

6.

If the response is a StreamMessage, retrieve the response as an InputStream object.


else if(incomingMessage instanceof StreamMessage) { StreamMessage reply = (StreamMessage) incomingMessage; InputStream is = reply.getStreamPayload();

a.

If the response is small, convert the contents of the stream into a byte array.
byte[] data = null; try { data = net.rim.device.api.io.IOUtilities.streamToBytes(is); } catch (IOException e) { // process the error }

b.

If the conversion was successful, convert the byte array to a String and assign it to payload.
if(data != null) { payload = new String(data); }

7.

If payload contains data, display it.


if(payload!=null) { synchronized(Application.getEventLock()) { UiApplication.getUiApplication().pushScreen (new HTTPOutputScreen(payload)); } }

After you finish: Implement onMessageCancelled() and onMessageFailed() to process other notifications. For a complete code sample, see "Code sample: Request data using a NonBlockingSenderDestination object"

Code sample: Requesting data using a NonBlockingSenderDestination object


import import import import import 38 net.rim.device.api.io.URI; net.rim.device.api.io.messaging.*; net.rim.device.api.ui.* net.rim.device.api.ui.component.ButtonField; net.rim.device.api.ui.container.MainScreen;

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

import net.rim.device.api.system.Application; import java.io.*; public class NetworkSample extends UiApplication { public static void main(String[] args) { NetworkSample app = new NetworkSample(); app.enterEventDispatcher(); } public NetworkSample() { pushScreen(new NonBlockingSenderSample()); } } class NonBlockingSenderSample extends MainScreen { implements FieldChangeListener

ButtonField _btnNonBlock = new ButtonField(Field.FIELD_HCENTER); private static UiApplication _app = UiApplication.getUiApplication(); public NonBlockingSenderSample() { _btnNonBlock.setChangeListener(this); _btnNonBlock.setLabel("Fetch page"); } add(_btnNonBlock);

public void fieldChanged(Field button, int unused) { if(button == _btnNonBlock) { NonBlockingSenderDestination destination = null; try { URI uri = URI.create("http://www.blackberry.com"); NBSDMsgListener responseListener = new NBSDMsgListener(); destination = (NonBlockingSenderDestination) DestinationFactory.getSenderDestination ("CommAPISample", uri); if (destination == null) { destination = DestinationFactory.createNonBlockingSenderDestination (new Context("CommAPISample"), uri, responseListener); } // Send message to retrieve the response destination.send();

39

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

} catch(Exception e) { // process the error } } } class NBSDMsgListener implements MessageListener { public void onMessage(Destination dest, Message msg) { String payload = null; if (msg instanceof ByteMessage) { ByteMessage reply = (ByteMessage) msg; payload = (String) reply.getStringPayload(); } else if(msg instanceof StreamMessage) { StreamMessage reply = (StreamMessage) msg; InputStream is = reply.getStreamPayload(); byte[] data = null; try { data = net.rim.device.api.io.IOUtilities.streamToBytes(is); } catch (IOException e) { } if(data != null) { payload = new String(data); } } if(payload!=null) { synchronized(Application.getEventLock()) { UiApplication.getUiApplication().pushScreen (new HTTPOutputScreen(payload)); } } }

public void onMessageCancelled(Destination arg0, int arg1) { // process message cancelled notification }

40

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

public void onMessageFailed(Destination arg0, MessageFailureException arg1) { // process message failed notification } } class HTTPOutputScreen extends MainScreen { RichTextField _rtfOutput = new RichTextField(); public HTTPOutputScreen(String message) { _rtfOutput.setText("Retrieving data. Please wait..."); add(_rtfOutput); showContents(message); } // After the data has been retrieved, display it public void showContents(final String result) { UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { _rtfOutput.setText(result); }

});

Send data using a FireAndForgetDestination object


1. Import the required classes and interfaces.
import net.rim.device.api.io.messaging.*; import net.rim.device.api.io.URI;

2. 3. 4.

Create a URI object to pass to the DestinationFactory class.


URI uri = new URI("http://www.example.com");

Create a FireAndForgetDestination object.


FireAndForgetDestination ffd = null;

Retrieve the FireAndForgetDestination object for your context, if one exists.


try {

ffd = (FireAndForgetDestination) DestinationFactory.getSenderDestination ("MyContext", uri);

5.

If no FireAndForgetDestination exists, create one.

41

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

if(ffd == null) { ffd = DestinationFactory.createFireAndForgetDestination (new Context("MyContext"), uri); }

6.

Create a ByteMessage object and populate it with information to send to a web service.
ByteMessage myMsg = ffd.createByteMessage(); myMsg.setStringPayload("I love my BlackBerry device!");

7. 8. 9.

Cast your message as an HTTPMessage to set the HTTP method that you want to use.
((HttpMessage) myMsg).setMethod(HttpMessage.POST);

Send the message to the web service.


ffd.sendNoResponse(myMsg);

Catch any errors that occur if the message could not be sent for some reason.
catch (Exception e) { // Process the error }

Parsing a common Internet data format


You can configure a Destination object to return a Java object that contains data parsed from a standard format, such as JSON. To retrieve the data structure in a Java object, you should: 1. Specify a MessageProcessor object when you invoke DestinationFactory.create...(). 2. Retrieve the response from your Destination. 3. Extract the data from the Message object that is returned in the response. Code sample The following code sample demonstrates the three actions that are required to retrieve a Java object that contains a JSON data structure.
import net.rim.device.api.io.messaging.* import net.rim.device.api.io.parser.json.* // Specify a MessageProcessor when you create your Destination BlockingSenderDestination bsd = DestinationFactory(myContext, myURI, new JSONMessageProcessor()); // Retrieve the response Message response = bsd.sendReceive(); // Extract the Java object that contains the JSON data structure Object payload = response.getObjectPayload();

42

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Parse a JSON data structure


This task uses a TreeField to display the contents of a JSON data structure. Before you begin: Retrieve a Java object that contains a JSON data structure. Pass that object to the constructor of the class developed in this task. 1. Import the required classes and interfaces.
import net.rim.device.api.ui.*; import net.rim.device.api.ui.component.*; import net.rim.device.api.ui.container.MainScreen;

2.

Define a MainScreen class that implements TreeFieldCallback interface.


public class JSONOutputScreen extends MainScreen implements TreeFieldCallback { private TreeField _treeField;

3.

Create a constuctor that accepts an Object as a parameter, creates the UI, and initiates the parsing code.
public JSONOutputScreen(Object JSONData) { _treeField = new TreeField(this, Field.FOCUSABLE); add(_treeField); initializeTree(JSONData); }

4.

Create an initializeTree() method to clear any existing data from the TreeField.
void initializeTree(Object obj) { int parentNode = 0; _treeField.deleteAll();

5.

Determine whether the current node in the JSON object is a JSONArray or a JSONObject. Invoke the appropriate populateTreeArray() method.
try {

if(obj instanceof JSONArray) { parentNode = populateTreeArray (_treeField, (JSONArray) obj, parentNode); } else if(obj instanceof JSONObject) { parentNode = populateTreeObject (_treeField, (JSONObject) obj,

43

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

parentNode);

6.

Catch any errors, and specify where the TreeField should add new data.
catch(JSONException e) { // Process error } } _treeField.setCurrentNode(parentNode);

7.

Implement populateTreeArray(TreeField, JSONArray, int).


int populateTreeArray(TreeField tree, JSONArray o, int p) throws JSONException { Object temp;

8. 9.

Add a node to the TreeField.


int newParent = tree.addChildNode(p, "Array " + p);

Iterate through the elements in this node of the JSONArray.


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

10. Retrieve the current JSONArray.


temp = o.get(i);

11. If the node is empty, go to the next node.


if(temp == null || temp.toString().equalsIgnoreCase("null")) { continue; }

12. If this node contains a nested JSON structure, parse the object recursively. Again, choose the most appropriate version of populateTreeArray().
if(temp instanceof JSONArray) { populateTreeArray(tree, (JSONArray) temp, newParent); } else if(temp instanceof JSONObject) { populateTreeObject(tree, (JSONObject) temp, newParent); }

13. This node must contain data. Add the data to the tree.
else { newParent = tree.addSiblingNode(newParent, temp.toString()); }

44

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

} } return newParent;

14. Implement populateTreeArray(TreeField, JSONObject, int). The code is similar to steps 7 through 13, with the following alterations: a. Change the method signature from step 7.
int populateTreeArray(TreeField tree, JSONObject o, int p) throws JSONException {

b. c.

Create a JSONArray containing the names of the elements.


JSONArray jsonArray = o.names();

Iterate over the newly created JSONArray instead of the JSONObject passed as a parameter. For more information, see step 9.
for(int i = 0; i < jsonArray.length(); ++i) {

d.

From the JSONObject, retrieve the value for each name in jsonArray. For more information, see step 10.
temp = o.get(jsonArray.getString(i));

e.

Ensure that you add both the name and value to the tree. For more information, see step 13.
tree.addSiblingNode(newParent, a.getString(i) + ": " + temp.toString());

15. Implement DrawTreeItem().


public void drawTreeItem(TreeField treeField, Graphics graphics, int node, int y, int width, int indent) { if(treeField == _treeField) { Object cookie = _treeField.getCookie(node); if(cookie instanceof String) { String text = (String) cookie; graphics.drawText(text, indent, y, Graphics.ELLIPSIS, width); } } } }

45

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Code sample: Parsing a JSON data structure


The following code sample demonstrates one way to parse a JSON data structure. You can use a similar process to parse JSON or other data formats that are provided by the Message Processing API.
import import import import import import import net.rim.device.api.io.URI; net.rim.device.api.io.messaging.*; net.rim.device.api.ui.* net.rim.device.api.ui.component.*; net.rim.device.api.ui.container.*; java.io.*; org.json.me.*;

public class NetworkSample extends UiApplication { public static void main(String[] args) { NetworkSample app = new NetworkSample(); app.enterEventDispatcher(); } public NetworkSample() { pushScreen(new ParseJSONSample()); } } class ParseJSONSample extends MainScreen implements FieldChangeListener { ButtonField _btnJSON = new ButtonField(Field.FIELD_HCENTER); private static UiApplication _app = UiApplication.getUiApplication(); public ParseJSONSample() { _btnJSON.setChangeListener(this); _btnJSON.setLabel("Fetch page"); } add(_btnJSON);

public void fieldChanged(Field button, int unused) { if(button == _btnJSON) { Thread t = new Thread(new Runnable() { public void run() { Message response = null; String uriStr = "http://docs.blackberry.com/sampledata.json"; BlockingSenderDestination bsd = null; try 46

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

bsd = (BlockingSenderDestination) DestinationFactory.getSenderDestination ("CommAPISample", URI.create(uriStr)); if(bsd == null) { bsd = DestinationFactory.createBlockingSenderDestination (new Context("CommAPISample"), URI.create(uriStr), new JSONMessageProcessor() ); } // Send message and wait for response response = bsd.sendReceive(); _json = response.getObjectPayload(); if(_json != null) { _app.invokeLater(new Runnable() { public void run() { _app.pushScreen(new JSONOutputScreen(_json)); } } });

} catch(Exception e) { System.out.println(e.toString()); } finally { if(bsd != null) { bsd.release(); } }

}); t.start(); } } class JSONOutputScreen extends MainScreen implements TreeFieldCallback { private TreeField _treeField;

47

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

public JSONOutputScreen(Object JSONData) { _treeField = new TreeField(this, Field.FOCUSABLE); add(_treeField); setTree(JSONData); } void setTree(Object obj) { int parentNode = 0; _treeField.deleteAll(); try {

} catch(JSONException e) { System.out.println(e.toString()); } }

if(obj instanceof JSONArray) { parentNode = populateTreeArray (_treeField, (JSONArray) obj, parentNode); } else if(obj instanceof JSONObject) { parentNode = populateTreeObject (_treeField, (JSONObject) obj, parentNode); }

_treeField.setCurrentNode(parentNode);

// Populate the trees with JSON arrays int populateTreeArray(TreeField tree, JSONArray o, int p) throws JSONException { Object temp; int newParent; newParent = tree.addChildNode(p, "Array " + p); for(int i = 0; i < o.length(); ++i) { temp = o.get(i); if(temp == null || temp.toString().equalsIgnoreCase("null")) { continue; } if(temp instanceof JSONArray) { // Array of arrays populateTreeArray(tree, (JSONArray) temp, newParent);

48

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

} }

} else if(temp instanceof JSONObject) { // Array of objects populateTreeObject(tree, (JSONObject) temp, newParent); } else { // other values newParent = tree.addSiblingNode(newParent, temp.toString()); }

return newParent;

// Populate the tree with JSON objects int populateTreeObject(TreeField tree, JSONObject o, int p) throws JSONException { Object temp; int newParent = tree.addChildNode(p, "Object" + p); JSONArray a = o.names(); for(int i = 0; i < a.length(); ++i) { temp = o.get(a.getString(i)); if(temp == null || temp.toString().equalsIgnoreCase("null")) { continue; } if(temp instanceof JSONArray) { populateTreeArray(tree, (JSONArray) temp, newParent); } else if(temp instanceof JSONObject) { populateTreeObject(tree, (JSONObject) temp, newParent); } else { tree.addSiblingNode (newParent, a.getString(i) + ": " + temp.toString()); }

} }

return newParent;

public void drawTreeItem(TreeField treeField, Graphics graphics, int node, int y, int width, int indent) { if(treeField == _treeField)

49

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

} }

Object cookie = _treeField.getCookie(node); if(cookie instanceof String) { String text = (String) cookie; graphics.drawText(text, indent, y, Graphics.ELLIPSIS, width); }

public boolean onSavePrompt() { // Suppress the save dialog return true; } }

Sending login information to an HTTP server


A Destination object can supply login information, such as a user name and password, when a web server requests it. Login information is stored in the Context object that you supply when you create a Destination using the DestinationFactory class. Code sample
context = new Context("DemoContext", new CredentialsCollector() { public UsernamePasswordCredentials getBasicAuthenticationCredentials (String aeID, Hashtable properties) { // Provide or retrieve authentication credentials here. // For example, you could display a dialog box to ask your user // to enter a username and password, then return them from // this method. return new UsernamePasswordCredentials("username", "password"); } });

50

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Subscribing to a push initiator

You can use the Communication API to send a subscription request to a content provider's URI. In addtition to the SenderDestination object that sends the subscription request, you need to create a ReceiverDestination object that defines the MessageListener object to which the BlackBerry device should deliver incoming push messages from a given URI. The following table describes the components that are involved in a subscription request. Component
SenderDestination

Subscription message

Description This component sends the subscription message to the content provider. This component is optional. You can send a subscription message using any type of network connection. For example, you can use the Network API to create an HTTPConnection and send the subscription parameters manually. The Communication API can create a properly formed subscription message for you. You can invoke
BpsSubscriptionMessageBuilder.createB yteSubscriptionMessage() to retrieve a ByteMessage object that is configured for your SenderDestination, NonBlockingReceiverDestination, and the MessageListener where you want to receive

NonBlockingReceiverDestination

InboundDestinationConfiguration

incoming push messages. This component associates a particular URI with a MessageListener where you want to receive incoming push messages, and an InboundDestinationConfiguration object. This component specifies a variety of push service parameters, such as an indicator that specifies whether your application should be started when a new push message arrives. You can create an InboundDestinationConfiguration using the
InboundDestinationConfigurationFactor y class.

MessageListener

This component processes incoming push messages.

51

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Subscribe to a push initiator


This task focuses on creating a subscription message and the NonBlockingReceiverDestination object for a Push Service subscription. You must send your subscription message using a SenderDestination object, or by creating a network connection manually. Before you begin: Obtain an application ID and the local port number that your application should use to listen for incoming messages. These details are provided to the content provider that creates a server-side push application. 1. 2. 3. Import the required classes and interfaces.
import net.rim.device.api.io.messaging.*;

Initialize a NonBlockingReceiverDestination variable to manage the subscription.


NonBlockingReceiverDestination nbrd = null;

Create a MessageListener object to process incoming push messages.


try {

MyMessageListener pushListener = new MyMessageListener();

4. 5.

Create a URI object with the port information that the content provider assigns to you.
URI pushURI = URI.create("http://:101");

Create an InboundDestinationConfiguration object to set parameters for the push subscription.


InboundDestinationConfiguration config = InboundDestinationConfigurationFactory.createBPSConfiguration (true, // start this application when a push message arrives false, // allow other applications to receive these push messages false, // do not store these messages (persistence not supported) "12-Ab234cD5eF67h890", // application ID, BPSuri); // BlackBerry Push Service URI

6.

Create a NonBlockingReceiverDestination.
nbrd = DestinationFactory.createNonBlockingReceiverDestination (config, pushURI, pushListener);

7.

Create a SenderDestination to send a subscription message.


NonBlockingSenderDestination bpsDestination = DestinationFactory.createNonBlockingSenderDestination (myContext, uri, responseListener);

8.

Configure a subscription message.


ByteMessage subMsg = BpsSubscriptionMessageBuilder.createByteSubscriptionMessage (bpsDestination, nbrd, "user", "pwd");

9.

Send the subscription message.

52

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

bpsDestination.send(subMsg);

53

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Working with radios

There may be cases where you need to turn on a radio on a BlackBerry device to use a particular network transport. For example, you may want your BlackBerry device application to connect over Wi-Fi to make efficient use of bandwidth. Or, you may want to compare your application's performance when you use different wireless technologies. You can use the net.rim.device.api.system.RadioInfo class to gather information about the wireless technologies that are available on a device. Using the rim.device.api.system.Radio class, you can manage the radios on the device. You should also implement the net.rim.device.api.system.RadioStatusListener interface to receive notifications about changes in radio status. The wireless technologies that are available on BlackBerry devices are grouped into three wireless access families. Wireless access family 3GPP CDMA WLAN Description This family includes GPRS, EDGE, UMTS GERAN, UTRAN, and GAN. This family includes CDMA2000 and EVDO. This family includes IEEE 802.11, 802.11a, 802.11b, 802.11g.

Query a radio's availability and change its status


You can use the RadioInfo and Radio classes to determine whether a particular radio technology is supported on a BlackBerry device, and to turn on or turn off the radio. For more information, see the API reference for the BlackBerry Java SDK. 1. Import the required classes and interfaces.
import net.rim.device.api.system.Radio; import net.rim.device.api.system.RadioInfo;

2. 3.

Retrieve a bit field of supported wireless access families.


int intSupportedWAFs = RadioInfo.getSupportedWAFs();

Check if the wireless access family that you want to use is available on the device. Perform a bitwise AND operation that combines the intSupportedWAFs bit field and the constant for the wireless access family that you want to use. If the family is available, the result will be nonzero.
if ((intSupportedWAFs & RadioInfo.WAF_WLAN) !=0 ) {

4.

Retrieve a bit field of available radios.


int intSupportedWAFs = RadioInfo.getSupportedWAFs(); int intActiveWAFs = RadioInfo.getActiveWAFs();

5.

intActiveWAFs and the constant for the radio returns 0.

Check if the radio that you want to use is turned off. If it is turned off, a bitwise AND operation applied to

54

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

if ((intActiveWAFs & RadioInfo.WAF_WLAN) = 0) {

6.

If the radio is turned off, then turn it on.


} Radio.activateWAFs(RadioInfo.WAF_WLAN);

Code sample: Controlling radios


import import import import net.rim.device.api.system.*; net.rim.device.api.ui.*; net.rim.device.api.ui.component.*; net.rim.device.api.ui.container.*;

public class NetworkSample extends UiApplication { public static void main(String[] args) { NetworkSample app = new NetworkSample(); app.enterEventDispatcher(); } public NetworkSample() { pushScreen(new RadioControlScreen()); } } class RadioControlScreen extends MainScreen implements FieldChangeListener { boolean[] _intRadioOn = new boolean[3]; ButtonField _btn3G, _btnCDMA, _btniDEN, _btnWiFi; public RadioControlScreen() { VerticalFieldManager vfm = new VerticalFieldManager(Field.FIELD_HCENTER); int wafs = RadioInfo.getSupportedWAFs(); if ((wafs & RadioInfo.WAF_3GPP) != 0 ) { _btn3G = new ButtonField("3G Radio"); _btn3G.setChangeListener(this); vfm.add(_btn3G); } if ((wafs & RadioInfo.WAF_CDMA) != 0 ) { _btnCDMA = new ButtonField("CDMA Radio"); _btnCDMA.setChangeListener(this); vfm.add(_btnCDMA); } if ((wafs & RadioInfo.WAF_WLAN) != 0 )

55

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

_btnWiFi = new ButtonField("WiFi Radio"); _btnWiFi.setChangeListener(this); vfm.add(_btnWiFi);

wafs = RadioInfo.getActiveWAFs(); if ((wafs & RadioInfo.WAF_3GPP) != 0 ) { _intRadioOn[0] = true; _btn3G.setLabel("3G Radio is on"); } if ((wafs & RadioInfo.WAF_CDMA) != 0 ) { _intRadioOn[1] = true; _btnCDMA.setLabel("CDMA Radio is on"); } if ((wafs & RadioInfo.WAF_WLAN) != 0 ) { _intRadioOn[2] = true; _btnWiFi.setLabel("WiFi Radio is on"); } add(vfm); StandardTitleBar tb = new StandardTitleBar(); tb.addTitle("Radio Control Demo"); tb.addSignalIndicator(); setTitleBar(tb); } public void fieldChanged(Field field, int context) { if (field instanceof ButtonField) { if(field == _btn3G) { if (_intRadioOn[0]) { Radio.deactivateWAFs(RadioInfo.WAF_3GPP); _btn3G.setLabel("3G Radio is off"); _intRadioOn[0] = false; } else { Radio.activateWAFs(RadioInfo.WAF_3GPP); _btn3G.setLabel("3G Radio is on"); _intRadioOn[0] = true; } } else if(field == _btnCDMA) { if (_intRadioOn[1]) { Radio.deactivateWAFs(RadioInfo.WAF_CDMA); _btnCDMA.setLabel("CDMA Radio is off"); _intRadioOn[1] = false;

56

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

} } }

} else { Radio.activateWAFs(RadioInfo.WAF_CDMA); _btnCDMA.setLabel("CDMA Radio is on"); _intRadioOn[1] = true; } } else if(field == _btnWiFi) { if (_intRadioOn[2]) { Radio.deactivateWAFs(RadioInfo.WAF_WLAN); _btnWiFi.setLabel("WiFi Radio is off"); _intRadioOn[2] = false; } else { Radio.activateWAFs(RadioInfo.WAF_WLAN); _btnWiFi.setLabel("WiFi Radio is on"); _intRadioOn[2] = true; } }

57

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Near Field Communication

BlackBerry devices that are equipped with a Near Field Communication (NFC) radio enable an application to interact with smart tags, smart accessories, and other NFC-enabled devices. Some examples of smart accessories and NFCenabled devices include bluetooth speakers, smart docks, and so on. NFC technology is designed to transfer small amounts of data over a short distance. In many cases, the data on a smart tag refers to another information source or a data channel. You can use smart tags to: provide a URL where a user can retrieve more information about an advertisement on a smart poster, such as a movie or a coupon provide pairing information for a Bluetooth accessory provide identification information for a smart dock
net.rim.device.api.io.nfc.readerwriter and the net.rim.device.api.io.nfc.ndef packages

The NFC API enables you to read and write smart tags formatted according to the NDEF Technical Specification. The

include classes and interfaces that enable you to read and write NDEF-formatted smart tags.

The net.rim.device.api.io.nfc.readerwriter package also includes programming elements that enable you to communicate with ISO14443 smart tags.

Working with smart tags


The NFC feature on a BlackBerry device is typically activated by a user when the user taps a smart tag. If you registered a listener that matches the configuration of the smart tag that a user taps, the device can notifiy your application that a tag is available. You can implement the net.rim.device.api.io.nfc.ndef.NDEFMessageListener interface to receive messages from a smart tag that is configured according to the NDEF Technical Specification. The BlackBerry device provides an NDEFMessage object that contains the data from the smart tag to an NDEFMessageListener. Applications that register an NDEFMessageListener object can restrict the Record Type Definition and record type that trigger the application. You can implement the net.rim.device.api.io.nfc.readerwriter.DetectionListener interface to enable your application to receive notification of a connection to any smart tag that conforms to the ISO14443 standard. When invoked, a DetectionListener receives a Target object that contains the URI that is required to open a connection to the tag. When a device detects a smart tag, the device notifies applications that registered relevant listener objects. Only one DetectionListener object can access a smart tag at a time while the smart tag is within the range of the NFC radio. When one DetectionListener finishes with the smart tag, another DetectionListener can open a connection to the smart tag if it is still in range.

Create an NDEF tag writer


1. Import the required classes and interfaces.

58

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.String; import javax.microedition.io.Connector; import import import import import import net.rim.device.api.io.nfc.NFCException; net.rim.device.api.io.nfc.ndef.*; net.rim.device.api.io.nfc.readerwriter.*; net.rim.device.api.ui.*; net.rim.device.api.ui.component.LabelField; net.rim.device.api.ui.container.*;

2.

Declare your application class and start your application.


public class NDEFWriterDemo extends UiApplication { public static void main(String[] args) { new NDEFWriterDemo().enterEventDispatcher(); }

3.

In your application's constructor, create a status screen and instantiate your implementation of the DetectionListener interface. You create a status screen in step 25. You implement a DetectionListener in step 10.
public NDEFWriterDemo() { NDEFWriterScreen screen = new NDEFWriterScreen(); NDEFWriterListener listener = new NDEFWriterListener(screen);

4.

Invoke a method to register your implementation of DetectionListener. You delcare a registerListener method in step 6.
registerListener(listener);

5.

Add your screen object to the display stack.


} pushScreen(screen);

6.

Create a registerListener() method.


public void registerListener(NDEFWriterListener listener) {

7.

Retrieve the system instance of ReaderWriterManager.


ReaderWriterManager nfc; try { nfc = ReaderWriterManager.getInstance();

8.

Register your implementation of DetectionListener. Indicate that you want to listen for the NDEF tag target type.

59

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

nfc.addDetectionListener(listener, new int[]{Target.NDEF_TAG});

9.

Process any errors that occur.


catch (NFCException e) { // add your error handling code here }

10. Declare your implementation of DetectionListener.


private class NDEFWriterListener implements DetectionListener {

11. Create an instance variable to hold a reference to the status screen and assign a value to the status screen variable in your constructor.
private NDEFWriterScreen display; public NDEFWriterListener(NDEFWriterScreen screen) { super(); display = screen; }

12. Create a createSmartTag method to define the content to write to a smart tag.
private NDEFMessage createSmartTag() throws IOException {

13. Create an NDEF record to write to the smart tag.


NDEFRecord titleRec = new NDEFRecord(); titleRec.setId("1"); titleRec.setType(NDEFRecord.TNF_WELL_KNOWN, "T"); ByteArrayOutputStream payload1 = new ByteArrayOutputStream(); payload1.write((byte) 0x05); // status byte - length of encoding payload1.write("en-US".getBytes()); // encoding payload1.write("My Title".getBytes()); // title payload1.flush(); titleRec.setPayload(payload1.toByteArray());

14. Create a second NDEF record to write to the smart tag.


NDEFRecord uriRec = new NDEFRecord(); uriRec.setId("2"); uriRec.setType(NDEFRecord.TNF_WELL_KNOWN, "U"); ByteArrayOutputStream payload2 = new ByteArrayOutputStream(); payload2.write((byte) 0x01); // abbreviation: http://www. payload2.write("blackberry.com".getBytes()); // uri

60

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

payload2.flush(); uriRec.setPayload(payload2.toByteArray());

15. Create an NDEF message and populate it with your NDEF records.
NDEFMessage ndefMessage = new NDEFMessage(); ndefMessage.setRecords(new NDEFRecord[] {titleRec, uriRec});

16. Set your NDEFMessage to be the first message on the smart tag.
NDEFMessage rootMessage = new NDEFMessage(); byte[] rootPayload = ndefMessage.getBytes(); NDEFRecord rootRec = new NDEFRecord(); rootRec.setType(NDEFRecord.TNF_WELL_KNOWN, "Sp"); rootRec.setPayload(rootPayload); rootMessage.setRecords(new NDEFRecord[] {rootRec});

17. Return the NDEFMessage to the invoking method.


} return rootMessage;

18. Declare the onTargetDetected method.


public void onTargetDetected(Target target) {

19. Create a variable for the connection to the smart tag.


NDEFTagConnection c = null;

20. Invoke the display.message() method to update the message on the status screen.
display.message("Tag detected. Attempting to write data.");

21. Create an NDEFMessage to write to the smart tag.


try { NDEFMessage smartTag = createSmartTag();

22. Open a connection to the smart tag. Cast the connection using the NDEFTagConnection interface. Retrieve the URI for the connection using the Target.getUri() method.
c = (NDEFTagConnection)Connector.open( target.getUri(Target.NDEF_TAG)); c.write(smartTag);

23. Update the message on the status screen.


} display.message("Tag detected. Attempting to write data.");

24. Process any errors that occur.


catch (NFCException e) { display.message("Could not write to tag."); 61

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

// add your error handling code here

25. Declare a status screen class and create an instance variable to hold a reference to a LabelField control.
private class NDEFWriterScreen extends MainScreen { private LabelField lbl;

26. Declare a constructor for your status screen. Initialize your label and add it to the screen.
public NDEFWriterScreen() { lbl = new LabelField("Tap a smart tag to write data.", Field.FIELD_HCENTER| Field.FIELD_VCENTER); add(lbl); }

27. Create a message() function to update the text in the label when tag related events occur.
public void message(String msg) { lbl.setText(msg); }

Code sample: Creating an NDEF tag writer


import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.String; import javax.microedition.io.Connector; import import import import import import import import import net.rim.device.api.ui.Field; net.rim.device.api.ui.UiApplication; net.rim.device.api.ui.component.LabelField; net.rim.device.api.ui.container.MainScreen; net.rim.device.api.io.nfc.NFCException; net.rim.device.api.io.nfc.ndef.NDEFMessage; net.rim.device.api.io.nfc.ndef.NDEFRecord; net.rim.device.api.io.nfc.ndef.NDEFTagConnection; net.rim.device.api.io.nfc.readerwriter.*;

public class NDEFWriterDemo extends UiApplication { public static void main(String[] args) { new NDEFWriterDemo().enterEventDispatcher(); }

62

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

public NDEFWriterDemo() { // detect whether or not you // registered a listener already // if not, then register a listener NDEFWriterScreen screen = new NDEFWriterScreen(); NDEFWriterListener listener = new NDEFWriterListener(screen); registerListener(listener); pushScreen(screen); } public void registerListener(NDEFWriterListener listener) { ReaderWriterManager nfc; try { nfc = ReaderWriterManager.getInstance(); nfc.addDetectionListener(listener, new int[]{Target.NDEF_TAG}); // save your registration state in persistent storage } catch (NFCException e) { // error handling code }

private class NDEFWriterListener implements DetectionListener { private NDEFWriterScreen display; public NDEFWriterListener(NDEFWriterScreen screen) { super(); display = screen; } private class NDEFWriterListener implements DetectionListener { private NDEFWriterScreen display; public NDEFWriterListener(NDEFWriterScreen screen) { super(); display = screen; } private NDEFMessage createSmartTag() throws IOException { NDEFRecord titleRec = new NDEFRecord(); titleRec.setId("1"); titleRec.setType(NDEFRecord.TNF_WELL_KNOWN, "T"); ByteArrayOutputStream payload1 = new ByteArrayOutputStream(); payload1.write((byte) 0x05); // status byte - length of encoding payload1.write("en-US".getBytes()); // encoding

63

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

payload1.write("My Title".getBytes()); // title payload1.flush(); titleRec.setPayload(payload1.toByteArray()); NDEFRecord uriRec = new NDEFRecord(); uriRec.setId("2"); uriRec.setType(NDEFRecord.TNF_WELL_KNOWN, "U"); ByteArrayOutputStream payload2 = new ByteArrayOutputStream(); payload2.write((byte) 0x01); // abbreviation: http://www. payload2.write("blackberry.com".getBytes()); // uri payload2.flush(); uriRec.setPayload(payload2.toByteArray()); NDEFMessage ndefMessage = new NDEFMessage(); ndefMessage.setRecords(new NDEFRecord[] {titleRec, uriRec}); NDEFMessage rootMessage = new NDEFMessage(); byte[] rootPayload = ndefMessage.getBytes(); NDEFRecord rootRec = new NDEFRecord(); rootRec.setType(NDEFRecord.TNF_WELL_KNOWN, "Sp"); rootRec.setPayload(rootPayload); rootMessage.setRecords(new NDEFRecord[] {rootRec}); } return rootMessage; public void onTargetDetected(Target target) { NDEFTagConnection c = null; display.message("Tag detected. Attempting to write data."); try {

NDEFMessage smartTag = createSmartTag();

c = (NDEFTagConnection)Connector.open( target.getUri(Target.NDEF_TAG)); c.write(smartTag); display.message("Tag detected. Attempting to write data."); } catch (NFCException e) { display.message("Could not write to tag."); // add your error handling code here }

private class NDEFWriterScreen extends MainScreen { private LabelField lbl; public NDEFWriterScreen() {

64

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

lbl = new LabelField("Tap a smart tag to write data.", Field.FIELD_HCENTER|Field.FIELD_VCENTER); add(lbl);

public void message(String msg) { lbl.setText(msg); }

Create an NDEF tag reader


1. Import the required classes and interfaces.
import java.lang.String; import import import import import import net.rim.device.api.ui.*; net.rim.device.api.ui.component.*; net.rim.device.api.ui.container.*; net.rim.device.api.io.nfc.NFCException; net.rim.device.api.io.nfc.readerwriter.*; net.rim.device.api.io.nfc.ndef.*;

2.

Declare your application class and start your application.


public class NDEFReaderDemo extends UiApplication { public static void main(String[] args) { new NDEFReaderDemo().enterEventDispatcher(); }

3.

In your application's constructor, add a screen to the display stack to allow a user to interact with your application. You create this screen in step 11.
public NDEFReaderDemo() { pushScreen(NDEFReaderScreen()); }

4.

Create a registerListener() function.


public void registerListener(NDEFReaderListener listener) {

5.

Attempt to retrieve the system instance of ReaderWriterManager.


ReaderWriterManager nfc; try

65

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

{ nfc = ReaderWriterManager.getInstance();

6.

Register your implementation of NDEFMessageListener. Indicate that you want to listen for a smart poster.
nfc.addNDEFMessageListener(listener, NDEFRecord.TNF_WELL_KNOWN, "Sp", true);

7.

Process any errors that occur.


catch (NFCException e) { Dialog.alert(e.toString()); }

8.

Create a similar method to deregister the listener if required.


public void deregisterListener() { try { ReaderWriterManager nfc = ReaderWriterManager.getInstance(); nfc.removeNDEFMessageListener(NDEFRecord.TNF_WELL_KNOWN, "Sp"); } catch(NFCException e) { Dialog.alert(e.toString()); } }

9.

Declare your implementation of NDEFMessageListener. Add an instance variable to keep a reference to the UI, and assign a value to it in the constructor.
private class NDEFReaderListener implements NDEFMessageListener { private NDEFReaderScreen display; private NDEFReaderListener(NDEFReaderScreen screen) { super(); display = screen; }

10. Implement the onNDEFMessageDetected() method.Pass the NDEF records as a parameter to the screen's constructor.
public void onNDEFMessageDetected(NDEFMessage msg) { NDEFReaderDemo.this.invokeLater(new Runnable() { public void run() { display.displayRecs(msg.getRecords()); }

66

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

}); }

11. Declare a screen class to display the NDEF records from the smart poster. Create instance variables to keep references to the buttons on the screen.
private class NDEFReaderScreen extends MainScreen implements FieldChangeListener { ButtonField btn1, btn2;

12. In the constructor, create your buttons and add them to the screen.
private NDEFReaderScreen() { btn1 = new ButtonField("Register Persistent Listener",Field.FIELD_HCENTER| Field.FIELD_VCENTER); btn1.setChangeListener(this); add(btn1); btn2 = new ButtonField("Deregister Persistent Listener",Field.FIELD_HCENTER| Field.FIELD_VCENTER); btn2.setChangeListener(this); add(btn2); }

13. Create a displayRecs method to display any records you receive from the smart tag. Determine whether any records were passed to this method.
public void displayRecs(NDEFRecord[] records) { int numRecords = records.length; if (numRecords > 0) {

14. If NDEF records exist, create an array of LabelField objects and add them to a vertical field manager. Add the vertical field manager to the screen to contain the labels.
LabelField lbl[] = new LabelField[numRecords]; VerticalFieldManager vfm = new VerticalFieldManager(); for (int j = numRecords - 1; j >= 0; j--) { lbl[j] = new LabelField(); String record = "ID: " + records[j].getId() + ", Type: " + records[j].getType() + ", TNF: " + records[j].getTypeNameFormat() + ", Payload: " + records[j].getPayload(); lbl[j].setText(record); vfm.add(lbl[j]); } add(vfm);

15. If no NDEF records were read from the tag, then add a label to the screen to inform the user.

67

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

else

LabelField lbl = new LabelField("This tag contains no records", Field.FIELD_HCENTER|Field.FIELD_VCENTER); add(lbl);

16. Implement the fieldChanged method to respond when the user presses the button.
public void fieldChanged(Field field, int context) { if (field == btn1) { registerListener(new NDEFReaderListener(this)); } else if (field == btn2) { deregisterListener(); } } }

Code sample: Creating an NDEF tag reader


import java.lang.String; import import import import import import net.rim.device.api.ui.*; net.rim.device.api.ui.component.*; net.rim.device.api.ui.container.*; net.rim.device.api.io.nfc.NFCException; net.rim.device.api.io.nfc.readerwriter.*; net.rim.device.api.io.nfc.ndef.*;

public class NDEFReaderDemo extends UiApplication { public NDEFReaderDemo() { pushScreen(NDEFReaderScreen()); } public NDEFReaderDemo() { pushScreen(NDEFReaderScreen()); } public void registerListener(NDEFReaderListener listener) { try { ReaderWriterManager nfc = ReaderWriterManager.getInstance(); nfc.addNDEFMessageListener(new NDEFReaderListener(), NDEFRecord.TNF_WELL_KNOWN, "Sp", true); // save your registration state in persistent storage

68

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

} catch(NFCException e) { Dialog.alert(e.toString()); } } public void deregisterListener() { try { ReaderWriterManager nfc = ReaderWriterManager.getInstance(); nfc.removeNDEFMessageListener(NDEFRecord.TNF_WELL_KNOWN, "Sp"); } catch(NFCException e) { Dialog.alert(e.toString()); } } private class NDEFReaderListener implements NDEFMessageListener { private NDEFReaderScreen display; private NDEFReaderListener(NDEFReaderScreen screen) { super(); display = screen; } public void onNDEFMessageDetected(NDEFMessage msg) { NDEFReaderDemo.this.invokeLater(new Runnable() { public void run() { display.displayRecs(msg.getRecords()); } }); }

private class NDEFReaderScreen extends MainScreen implements FieldChangeListener { ButtonField btn1, btn2; private NDEFReaderScreen() { btn1 = new ButtonField("Register Persistent Listener",Field.FIELD_HCENTER| Field.FIELD_VCENTER); btn1.setChangeListener(this); add(btn1); btn2 = new ButtonField("Deregister Persistent Listener",Field.FIELD_HCENTER| Field.FIELD_VCENTER); btn2.setChangeListener(this); add(btn2); } public void displayRecs(NDEFRecord[] records)

69

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

int numRecords = records.length; if (numRecords > 0) { LabelField lbl[] = new LabelField[numRecords]; VerticalFieldManager vfm = new VerticalFieldManager(); for (int j = numRecords - 1; j >= 0; j--) { lbl[j] = new LabelField(); String record = "ID: " + records[j].getId() + ", Type: " + records[j].getType() + ", TNF: " + records[j].getTypeNameFormat() + ", Payload: " + records[j].getPayload(); lbl[j].setText(record); vfm.add(lbl[j]); } add(vfm); } else { LabelField lbl = new LabelField("This tag contains no records", Field.FIELD_HCENTER|Field.FIELD_VCENTER); add(lbl); } }

public void fieldChanged(Field field, int context) { if (field == btn1) { registerListener(new NDEFReaderListener(this)); } else if (field == btn2) { deregisterListener(); } } }

Communicate with an ISO14443 smart tag


1. Import the required classes and interfaces.
import java.io.IOException; import java.lang.String; import javax.microedition.io.Connector; import import import import import import net.rim.device.api.ui.Field; net.rim.device.api.ui.UiApplication; net.rim.device.api.ui.component.LabelField; net.rim.device.api.ui.container.MainScreen; net.rim.device.api.io.nfc.NFCException; net.rim.device.api.io.nfc.readerwriter.*;

70

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

2.

Declare your application class and start your application.


public class ISO14443Demo extends UiApplication { public static void main(String[] args) { new ISO14443Demo().enterEventDispatcher(); }

3.

In your application's constructor, invoke a function to register your implementation of DetectionListener.


public ISO14443Demo() { registerListener(); }

4.

Create a registerListener() function.


public void registerListener() {

5.

Attempt to retrieve the system instance of ReaderWriterManager.


ReaderWriterManager nfc; try { nfc = ReaderWriterManager.getInstance();

6.

Register your implementation of DetectionListener.


} nfc.addDetectionListener(new ISO14443Listener());

7.

Process any errors that occur.


catch (NFCException e) { // add your error handling code here }

8.

Declare your implementation of DetectionListener.


private class ISO14443Listener implements DetectionListener {

9.

Implement the onTargetDetected() method. Create local variables to hold references to the following resources: the connection to the smart tag the command to send to the smart tag the response from the smart tag
public void onTargetDetected(Target target) { ISO14443Part3Connection c = null;

71

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

// make sure to follow the specification for the // manufacturer and model of your tag // the command below is provided as a sample only byte[] iso14443Command = {(byte) 0x30, (byte) 0x03}; byte[] response = null;

10. Use Connector.open() to open a connection to the smart tag. Cast the connection using the ISO14443Part3 interface. Retrieve the URI for the connection using the Target.getUri() method.
try { c = (ISO14443Part3Connection)Connector.open( target.getUri(Target.ISO_14443_3));

11. Send your command to the smart tag and retrieve the response.
} response = c.transceive(iso14443Command);

12. Process any errors that occur.


catch (NFCException e) { // add your error handling code here // make sure to set a non-null value for response }

13. Add a screen to the display stack to show the response from the smart tag. Pass the response variable as a parameter to the screen's constructor.
} pushScreen(new ISO14443DemoStatusScreen(response));

14. Declare a screen class to display the response data from the smart tag. In the constructor, initialize a LabelField object. Populate the label with the smart tag response data, and add the label to the screen to display the data.
private class ISO14443DemoStatusScreen extends MainScreen { public ISO14443DemoStatusScreen(byte[] response) { LabelField lbl = new LabelField(response, Field.FIELD_HCENTER| Field.FIELD_VCENTER); add(lbl); } } }

Code sample: Communicating with an ISO 14443 tag


import java.io.IOException; import java.lang.String; import javax.microedition.io.Connector; import net.rim.device.api.ui.Field;

72

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

import import import import import

net.rim.device.api.ui.UiApplication; net.rim.device.api.ui.component.LabelField; net.rim.device.api.ui.container.MainScreen; net.rim.device.api.io.nfc.NFCException; net.rim.device.api.io.nfc.readerwriter.*;

public class ISO14443Demo extends UiApplication { public static void main(String[] args) { new ISO14443Demo().enterEventDispatcher(); } public ISO14443Demo() { // detect whether or not you // registered a listener already // if not, then register a listener registerListener(); } public void registerListener() { ReaderWriterManager nfc; try { nfc = ReaderWriterManager.getInstance(); nfc.addDetectionListener(new ISO14443Listener()); // save your registration state in persistent storage } catch (NFCException e) { // error handling code }

private class ISO14443Listener implements DetectionListener { public void onTargetDetected(Target target) { ISO14443Part3Connection c = null; // make sure to follow the specification for the // manufacturer and model of your tag // the command below is provided as a sample only byte[] iso14443Command = {(byte) 0x30, (byte) 0x03}; = null; try { c = (ISO14443Part3Connection)Connector.open( target.getUri(Target.ISO_14443_3)); response = c.transceive(ISO14443Command); } catch (IOException e) {

byte[] response

73

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

} }

// error handling code // make sure to set a non-null value for response

pushScreen(new ISO14443DemoStatusScreen(response));

private class ISO14443DemoStatusScreen extends MainScreen { public ISO14443DemoStatusScreen(byte[] response) { LabelField lbl = new LabelField(response, Field.FIELD_HCENTER| Field.FIELD_VCENTER); add(lbl); } } }

74

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Glossary
3GPP Third Generation Partnership Project AES Advanced Encryption Standard API application programming interface APN access point name BlackBerry MDS BlackBerry Mobile Data System CDMA Code Division Multiple Access EDGE Enhanced Data Rates for Global Evolution EVDO Evolution Data Optimized GAN generic access network GERAN GSM-EDGE Radio Access Network GCF Generic Connection Framework GPRS General Packet Radio Service GSM Global System for Mobile Communications HTTP Hypertext Transfer Protocol

75

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

HTTPS Hypertext Transfer Protocol over Secure Sockets Layer IP Internet Protocol JSON JavaScript Object Notation RDF Resource Description Framework RSS Really Simply Syndication SOAP Simple Object Access Protocol SSL Secure Sockets Layer TCP Transmission Control Protocol TLS Transport Layer Security Triple DES Triple Data Encryption Standard UDP User Datagram Protocol URI Uniform Resource Identifier URL Uniform Resource Locator UMTS Universal Mobile Telecommunications System UTRAN UMTS Terrestrial Radio Access Network

76

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

VPN Virtual Private Network WAP Wireless Application Protocol WLAN wireless local area network WTLS Wireless Layer Transport Security XML Extensible Markup Language

77

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Provide feedback
To provide feedback on this deliverable, visit www.blackberry.com/docsfeedback.

78

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Document revision history


Date 31 May 2011 Description Changed the following topics: Networking and connectivity overview Network connections Added the following topics: Code sample: Creating an NDEF tag reader Code sample: Creating an NDEF tag writer Code sample: Communicating with an ISO14444 tag Communicate with an ISO14444 smart tag Create an NDEF tag reader Create an NDEF tag writer Near Field Communication Working with smart tags Changed the following topics: Architecture: Network Transports Communicating with HTTP servers Network tranport options First draft released.

8 November 2010

27 September 2010

79

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

Legal notice

10

2011 Research In Motion Limited. All rights reserved. BlackBerry, RIM, Research In Motion, and related trademarks, names, and logos are the property of Research In Motion Limited and are registered and/or used in the U.S. and countries around the world. 3GPP, UMTS are trademarks of the European Telecommunications Standards Institute. Java, JavaScript are trademarks of Oracle America, Inc. CDMA2000 is a trademark of the Telecommunications Industry Association. WiFi is a trademark of the Wi-Fi Alliance. All other trademarks are the property of their respective owners. This documentation including all documentation incorporated by reference herein such as documentation provided or made available at www.blackberry.com/go/docs is provided or made accessible "AS IS" and "AS AVAILABLE" and without condition, endorsement, guarantee, representation, or warranty of any kind by Research In Motion Limited and its affiliated companies ("RIM") and RIM assumes no responsibility for any typographical, technical, or other inaccuracies, errors, or omissions in this documentation. In order to protect RIM proprietary and confidential information and/or trade secrets, this documentation may describe some aspects of RIM technology in generalized terms. RIM reserves the right to periodically change information that is contained in this documentation; however, RIM makes no commitment to provide any such changes, updates, enhancements, or other additions to this documentation to you in a timely manner or at all. This documentation might contain references to third-party sources of information, hardware or software, products or services including components and content such as content protected by copyright and/or third-party web sites (collectively the "Third Party Products and Services"). RIM does not control, and is not responsible for, any Third Party Products and Services including, without limitation the content, accuracy, copyright compliance, compatibility, performance, trustworthiness, legality, decency, links, or any other aspect of Third Party Products and Services. The inclusion of a reference to Third Party Products and Services in this documentation does not imply endorsement by RIM of the Third Party Products and Services or the third party in any way. EXCEPT TO THE EXTENT SPECIFICALLY PROHIBITED BY APPLICABLE LAW IN YOUR JURISDICTION, ALL CONDITIONS, ENDORSEMENTS, GUARANTEES, REPRESENTATIONS, OR WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY CONDITIONS, ENDORSEMENTS, GUARANTEES, REPRESENTATIONS OR WARRANTIES OF DURABILITY, FITNESS FOR A PARTICULAR PURPOSE OR USE, MERCHANTABILITY, MERCHANTABLE QUALITY, NON-INFRINGEMENT, SATISFACTORY QUALITY, OR TITLE, OR ARISING FROM A STATUTE OR CUSTOM OR A COURSE OF DEALING OR USAGE OF TRADE, OR RELATED TO THE DOCUMENTATION OR ITS USE, OR PERFORMANCE OR NON-PERFORMANCE OF ANY SOFTWARE, HARDWARE, SERVICE, OR ANY THIRD PARTY PRODUCTS AND SERVICES REFERENCED HEREIN, ARE HEREBY EXCLUDED. YOU MAY ALSO HAVE OTHER RIGHTS THAT VARY BY STATE OR PROVINCE. SOME JURISDICTIONS MAY NOT ALLOW THE EXCLUSION OR LIMITATION OF IMPLIED WARRANTIES AND CONDITIONS. TO THE EXTENT PERMITTED BY LAW, ANY IMPLIED WARRANTIES OR CONDITIONS RELATING TO THE DOCUMENTATION TO THE EXTENT THEY CANNOT BE EXCLUDED AS SET OUT ABOVE, BUT CAN BE LIMITED, ARE HEREBY LIMITED TO NINETY (90) DAYS FROM THE DATE YOU FIRST ACQUIRED THE DOCUMENTATION OR THE ITEM THAT IS THE SUBJECT OF THE CLAIM. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW IN YOUR JURISDICTION, IN NO EVENT SHALL RIM BE LIABLE FOR ANY TYPE OF DAMAGES RELATED TO THIS DOCUMENTATION OR ITS USE, OR PERFORMANCE OR NONPERFORMANCE OF ANY SOFTWARE, HARDWARE, SERVICE, OR ANY THIRD PARTY PRODUCTS AND SERVICES REFERENCED HEREIN INCLUDING WITHOUT LIMITATION ANY OF THE FOLLOWING DAMAGES: DIRECT,
80

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, INDIRECT, SPECIAL, PUNITIVE, OR AGGRAVATED DAMAGES, DAMAGES FOR LOSS OF PROFITS OR REVENUES, FAILURE TO REALIZE ANY EXPECTED SAVINGS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, LOSS OF BUSINESS OPPORTUNITY, OR CORRUPTION OR LOSS OF DATA, FAILURES TO TRANSMIT OR RECEIVE ANY DATA, PROBLEMS ASSOCIATED WITH ANY APPLICATIONS USED IN CONJUNCTION WITH RIM PRODUCTS OR SERVICES, DOWNTIME COSTS, LOSS OF THE USE OF RIM PRODUCTS OR SERVICES OR ANY PORTION THEREOF OR OF ANY AIRTIME SERVICES, COST OF SUBSTITUTE GOODS, COSTS OF COVER, FACILITIES OR SERVICES, COST OF CAPITAL, OR OTHER SIMILAR PECUNIARY LOSSES, WHETHER OR NOT SUCH DAMAGES WERE FORESEEN OR UNFORESEEN, AND EVEN IF RIM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW IN YOUR JURISDICTION, RIM SHALL HAVE NO OTHER OBLIGATION, DUTY, OR LIABILITY WHATSOEVER IN CONTRACT, TORT, OR OTHERWISE TO YOU INCLUDING ANY LIABILITY FOR NEGLIGENCE OR STRICT LIABILITY. THE LIMITATIONS, EXCLUSIONS, AND DISCLAIMERS HEREIN SHALL APPLY: (A) IRRESPECTIVE OF THE NATURE OF THE CAUSE OF ACTION, DEMAND, OR ACTION BY YOU INCLUDING BUT NOT LIMITED TO BREACH OF CONTRACT, NEGLIGENCE, TORT, STRICT LIABILITY OR ANY OTHER LEGAL THEORY AND SHALL SURVIVE A FUNDAMENTAL BREACH OR BREACHES OR THE FAILURE OF THE ESSENTIAL PURPOSE OF THIS AGREEMENT OR OF ANY REMEDY CONTAINED HEREIN; AND (B) TO RIM AND ITS AFFILIATED COMPANIES, THEIR SUCCESSORS, ASSIGNS, AGENTS, SUPPLIERS (INCLUDING AIRTIME SERVICE PROVIDERS), AUTHORIZED RIM DISTRIBUTORS (ALSO INCLUDING AIRTIME SERVICE PROVIDERS) AND THEIR RESPECTIVE DIRECTORS, EMPLOYEES, AND INDEPENDENT CONTRACTORS. IN ADDITION TO THE LIMITATIONS AND EXCLUSIONS SET OUT ABOVE, IN NO EVENT SHALL ANY DIRECTOR, EMPLOYEE, AGENT, DISTRIBUTOR, SUPPLIER, INDEPENDENT CONTRACTOR OF RIM OR ANY AFFILIATES OF RIM HAVE ANY LIABILITY ARISING FROM OR RELATED TO THE DOCUMENTATION. Prior to subscribing for, installing, or using any Third Party Products and Services, it is your responsibility to ensure that your airtime service provider has agreed to support all of their features. Some airtime service providers might not offer Internet browsing functionality with a subscription to the BlackBerry Internet Service. Check with your service provider for availability, roaming arrangements, service plans and features. Installation or use of Third Party Products and Services with RIM's products and services may require one or more patent, trademark, copyright, or other licenses in order to avoid infringement or violation of third party rights. You are solely responsible for determining whether to use Third Party Products and Services and if any third party licenses are required to do so. If required you are responsible for acquiring them. You should not install or use Third Party Products and Services until all necessary licenses have been acquired. Any Third Party Products and Services that are provided with RIM's products and services are provided as a convenience to you and are provided "AS IS" with no express or implied conditions, endorsements, guarantees, representations, or warranties of any kind by RIM and RIM assumes no liability whatsoever, in relation thereto. Your use of Third Party Products and Services shall be governed by and subject to you agreeing to the terms of separate licenses and other agreements applicable thereto with third parties, except to the extent expressly covered by a license or other agreement with RIM. Certain features outlined in this documentation require a minimum version of BlackBerry Enterprise Server, BlackBerry Desktop Software, and/or BlackBerry Device Software.

81

RIM Confidential and Proprietary Information - Beta Customers Only. Content and software are subject to change.

The terms of use of any RIM product or service are set out in a separate license or other agreement with RIM applicable thereto. NOTHING IN THIS DOCUMENTATION IS INTENDED TO SUPERSEDE ANY EXPRESS WRITTEN AGREEMENTS OR WARRANTIES PROVIDED BY RIM FOR PORTIONS OF ANY RIM PRODUCT OR SERVICE OTHER THAN THIS DOCUMENTATION. Research In Motion Limited 295 Phillip Street Waterloo, ON N2L 3W8 Canada Research In Motion UK Limited Centrum House 36 Station Road Egham, Surrey TW20 9LF United Kingdom Published in Canada

82

You might also like