BlackBerry Application Developer Guide Volume 2
BlackBerry Application Developer Guide Volume 2
Development Environment
Version 4.0.2
At the time of publication, this documentation complies with BlackBerry JDE Version 4.0.2.
© 2005 Research In Motion Limited. All rights reserved. The BlackBerry and RIM families of related marks, images and symbols are the exclusive
properties of Research In Motion Limited. RIM, Research In Motion, BlackBerry and 'Always On, Always Connected' are registered with the U.S.
Patent and Trademark Office and may be pending or registered in other countries.
Microsoft, Windows, and Outlook are registered trademarks of Microsoft Corporation in the United States and/or other countries. Java is a trademark
of Sun Microsystems, Inc. in the U.S. and other countries. IBM, Lotus, and Domino are trademarks of International Business Machines Corporation in
the United States, other countries or both. All other brands, product names, company names, trademarks, and service marks are the properties of
their respective owners.
The handheld and/or associated software are protected by copyright, international treaties and various patents, including one or more of the
following U.S. patents: 6,278,442; 6,271,605; 6,219,694; 6,075,470; 6,073,318; D,445,428; D,433,460; D,416,256. Other patents are registered
or pending in various countries around the world. Please visit www.rim.net/patents.shtml for a current listing of applicable patents.
This document is provided “as is” and Research In Motion Limited (RIM) assumes no responsibility for any typographical, technical, or other
inaccuracies in this document. RIM reserves the right to periodically change information that is contained in this document; however, RIM makes no
commitment to provide any such changes, updates, enhancements, or other additions to this document to you in a timely manner or at all. RIM
MAKES NO REPRESENTATIONS, WARRANTIES, CONDITIONS, OR COVENANTS, EITHER EXPRESS OR IMPLIED (INCLUDING, WITHOUT LIMITATION,
ANY EXPRESS OR IMPLIED WARRANTIES OR CONDITIONS OF FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, MERCHANTABILITY,
DURABILITY, TITLE, OR RELATED TO THE PERFORMANCE OR NON-PERFORMANCE OF ANY SOFTWARE REFERENCED HEREIN, OR PERFORMANCE
OF ANY SERVICES REFERENCED HEREIN). IN CONNECTION WITH YOUR USE OF THIS DOCUMENTATION, NEITHER RIM NOR ITS AFFILIATED
COMPANIES AND THEIR RESPECTIVE DIRECTORS, OFFICERS, EMPLOYEES, OR CONSULTANTS SHALL BE LIABLE TO YOU FOR ANY DAMAGES
WHATSOEVER BE THEY DIRECT, ECONOMIC, COMMERCIAL, SPECIAL, CONSEQUENTIAL, INCIDENTAL, EXEMPLARY, OR INDIRECT DAMAGES,
EVEN IF RIM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, INCLUDING, WITHOUT LIMITATION, LOSS OF BUSINESS REVENUE OR
EARNINGS, LOST DATA, DAMAGES CAUSED BY DELAYS, LOST PROFITS, OR A FAILURE TO REALIZE EXPECTED SAVINGS.
This document might contain references to third-party sources of information and/or third-party web sites (“Third-Party Information”). RIM does not
control, and is not responsible for, any Third-Party Information, including, without limitation, the content, accuracy, copyright compliance, legality,
decency, links, or any other aspect of Third-Party Information. The inclusion of Third-Party Information in this document does not imply endorsement
by RIM of the third party in any way. Any dealings with third parties, including, without limitation, compliance with applicable licenses, and terms
and conditions are solely between you and the third party. RIM shall not be responsible or liable for any part of such dealings.
Published in Canada
Contents
Using controlled APIs .................................................................................................................................... 5
BlackBerry controlled APIs.............................................................................................................................................5
Code signatures.................................................................................................................................................................6
Index............................................................................................................................................................. 133
1
Using controlled APIs
• BlackBerry controlled APIs
• Code signatures
Package Description
net.rim.blackberry.api.browser This package enables applications to invoke the BlackBerry Browser. See
“Displaying web content in the browser” on page 47 for more information.
net.rim.blackberry.api.invoke This package enables applications to invoke BlackBerry applications, such as
tasks, messages, MemoPad, and phone. See “Starting BlackBerry applications”
on page 79 for more information.
net.rim.blackberry.api.mail This package enables applications to interact with the BlackBerry messages
application to send, receive, and open messages. See “Working with messages”
on page 13 for more information.
net.rim.blackberry.api.mail.event This package defines messaging events and listener interfaces to manage mail
events. See “Mail events” on page 13 for more information.
net.rim.blackberry.api.menuitem This package enables you to add custom menu items to BlackBerry applications,
such as the address book, calendar, and messages. See “Adding menu items to
BlackBerry applications” on page 80 for more information.
net.rim.blackberry.api.options This package enables you to add items to the handheld options. See “Adding
option items” on page 43 for more information
net.rim.blackberry.api.pdap This package enables applications to interact with BlackBerry personal
information management (PIM) applications, including address book, tasks,
and calendar. Most of the same functionality is provided by the MIDP package
javax.microedition.pim. See “PIM APIs” on page 23 for more information.
net.rim.blackberry.api.phone This package provides access to advanced features of the phone application.
See “Phone API” on page 73 for more information.
net.rim.blackberry.api.phone.phonelogs This package provides access to the phone call history. See “Accessing and
managing phone logs” on page 75 for more information.
net.rim.device.api.browser.field This package enables applications to display a browser field within their user
interface. See “Displaying web content in a browser field” on page 48 for more
information.
net.rim.device.api.browser.plugin This package enables you to add support for additional MIME types to the
BlackBerry Browser. See “Supporting additional MIME types” on page 62 for
more information.
net.rim.device.api.crypto.* These packages provide data security capabilities, including data encryption
and decryption, digital signatures, data authentication, and certificate
management. See the API Reference for more information.
net.rim.device.api.io.http This package enables applications to register with the BlackBerry Browser as
provider for one or more URLs. See “Registering as an HTTP filter” on page 67
for more information.
BlackBerry Application Developer Guide
Package Description
net.rim.device.api.notification This package provides methods to trigger event notifications and respond to
system-wide and application-specific events. See “Notification API” on page
109 for more information.
net.rim.device.api.servicebook This package enables applications to add, delete, and access service book
entries. See “Accessing setup and configuration information” on page 107 for
more information.
net.rim.device.api.synchronization This package enables applications to perform backup and restore operations on
custom data. See “Adding support for backing up persistent data” on page 98
for more information.
net.rim.device.api.system This package provides classes that enable functionality such as persistent data
storage, interprocess communication (IPC), SMS, network communication using
datagrams, and application management.
• See “Application manager” on page 123 for more information.
• See “Using datagram connections” on page 98 for more information.
• See “Storing persistent data” on page 83 for more information.
Code signatures
RIM tracks the use of some sensitive APIs in the BlackBerry JDE for security and export reasons. In the
API Reference, a lock icon or the text signed indicates sensitive classes or methods. In the
documentation for a class that contains signed methods, select or clear the SHOW Signed option at the
top of the page to view or hide signed methods.
If you use signed classes or methods in your applications, the .cod files must be digitally signed by RIM
before you can load them onto BlackBerry devices.
Note: To test and debug your code before receiving code signatures, use the simulator. Code must be signed only for
deployment to BlackBerry devices.
Use the Signature Tool, which is installed with the BlackBerry JDE, to request the appropriate signatures
for your .cod files.
Note: You never send your actual code to RIM. The Signature Tool sends an SHA-1 hash of your code file so that the signing
authority system can generate the necessary signature.
See “Registering for code signing” on page 8 for more information on .csi files. See “Requesting code
signatures” on page 9 for more information on .csl and .cso files.
6
1: Using controlled APIs
Optional signatures
You can load applications onto BlackBerry devices without optional .cso signatures. These signatures are
only required if their corresponding methods are invoked during runtime.
When the application calls a method that requires a signature, the VM verifies that the application has
this authorization. If the VM does not find these optional signatures, the application stops.
Signing limitations
There are several situations in which the code signing process does not proceed.
Client parameters
The signing authority administrator can limit your access to signatures by specifying a limit using both
time and frequency parameters. These parameters are defined in your .csi file. Be aware of these possible
limitations when applying for signatures.
Parameter Definition
# of Requests This parameter sets the number of requests you can make using a particular .csi file. After you make
the maximum number of requests, the .csi file is invalid and you can no longer make signature requests
using this file. Contact your signing authority administrator to apply for another .csi file.
Requests are limited for security reasons; however, the signing authority administrator can allow you
to make an infinite number.
Expiry Date This parameter sets the expiry date for your .csi file. After your .csi file expires, you can no longer make
signature requests using this file. Contact your signing authority administrator and apply for another
.csi file.
To request a change in these .csi parameters, contact your signing authority administrator.
Lost data
You cannot perform any code signing requests without your .csi file. Your registration key is stored within
your .csi file. None of your signature requests can be sent to the signing authority system if the Signature
Tool cannot find this key and sign your requests with it.
7
BlackBerry Application Developer Guide
If your system stops responding, and you lose data or even entire file structures, you might discover that
you have also lost the ability to perform signing requests. If you lose your .csi file, the Signature Tool
cannot communicate with the signing authority system on your behalf.
If you lose your .csi file, contact your signing authority administrator and request a new one.
6. Click Register.
7. Click Exit.
8
1: Using controlled APIs
6. Click OK.
Warning: If you have already registered for code signing with a previous version of the SDK, back up the following files,
which are located in the BlackBerry JDE bin folder, before you install a new version of the BlackBerry JDE:
• Sigtool.db
• Sigtool.csk
If these files are lost, you must register again with RIM.
3. Click Add.
4. In the Look In drop-down list, click the folder in which the .cod file is located.
5. Click a .cod file.
6. Click Open.
7. Click Request.
8. Type your private key password.
9. Click OK.
9
BlackBerry Application Developer Guide
10
2
Integrating messages
• Mail API
• Working with messages
• Managing folders
• Managing attachments
Mail API
The BlackBerry mail API, in the net.rim.blackberry.api.mail and
net.rim.blackberry.mail.event packages, enables applications to send, receive, and access
messages using the messages application.
Notes: The BlackBerry mail API provides access to messages in the messages list, but not to other message types, such as
SMS messages, PIN messages, or phone-call logs. For access to phone-call logs, use the Phone Log API
(net.rim.blackberry.api.phonelogs). See “Accessing and managing phone logs” on page 75 for more information.
Check for a NoClassDefFoundError when your application first accesses the Mail API. This error is thrown if the system
administrator restricts access to the Mail API using application control. See “Application control” on page 12 of the
BlackBerry Application Developer Guide Volume 1: Fundamentals for more information.
Messages
A Message object consists of a set of attributes, such as subject, sender, and recipients, and a message
body (its contents). See “Multipart messages” on page 12 for more information.
The following classes and interfaces define supported message attributes:
Multipart messages
The mail API supports multipart messages. The Multipart abstract class provides a container for one or
more BodyPart objects. Multipart provides methods to retrieve and set its subparts.
Each BodyPart consists of header fields (attributes) and contents (body). The mail API provides four
implementations of BodyPart.
Message storage
The Folder class represents a local mailbox folder. Several folder types are defined, including INBOX,
OUTBOX, SENT, and OTHER. You can use these folder types to retrieve folders for retrieving or saving
messages.
The Store class models the underlying message storage and provides methods for finding and retrieving
folders. Folders exist in a hierarchy, as the following example demonstrates:
Mailbox - Aisha Wahl
Inbox
Projects
In Progress
Complete
Personal
A standard delimiter character separates each folder in the hierarchy, which you can retrieve using
getSeparator(). You can list all the folders in a Store object, list the subfolders in a folder, or find a
folder based on a search string.
The Folder class defines methods for retrieving messages or subfolders, saving messages, and deleting
messages.
Note: Multiple Folder instances can refer to the same folder on the BlackBerry device. As a result, you should always invoke
addFolderListener() and removeFolderListener() on the same Folder object. Use Folder.equals() to
determine whether two Folder objects refer to the same folder.
12
2: Integrating messages
Mail events
The BlackBerry mail event package (net.rim.blackberry.api.mail.event) defines the following
messaging events and listeners for each event:
Event Description
FolderEvent This event triggers when a message in a folder is added or removed.
MessageEvent This event triggers when a message changes (body, header, or flags).
StoreEvent This event triggers when a message is added to, or removed from, the message store in a batch operation
(for example, when the BlackBerry device is synchronized with the desktop).
The MailEvent class is the base class for these mail event classes. The MailEvent class defines an
abstract dispatch() method to invoke the appropriate listener method for each event.
The EventListener interface provides a common interface for the FolderListener and
MessageListener interfaces.
try {
Store store = Session.waitForDefaultSession().getStore();
} catch (NoSuchServiceException e) {
System.out.println(e.toString());
}
store.addStoreListener(this);
13
BlackBerry Application Developer Guide
The second parameter of more() is a Boolean value that specifies whether to retrieve only the next
section of the body part (false) or all remaining sections of the body part (true).
Open a message
Retrieve the message store and the folder that contains the message.
Store store = Session.waitForDefaultSession.getStore();
Folder folder = Store.getFolder("SampleFolder");
Retrieve the message objects from the folder. Iterate through the array and retrieve information, such as
the sender and subject, to display to the user.
Message[] msgs = folder.getMessages();
When a user selects a message from the list, invoke methods on the Message object to retrieve the
appropriate fields and body contents to display to the user.
Message msg = msgs[0]; // Retrieve the first message.
Address[] recipients = msg.getRecipients(Message.RecipientType.TO)
Date sent = msg.getSentDate();
Address from = msg.getFrom();
String subject = msg.getSubject();
14
2: Integrating messages
Object o = msg.getContent();
// Verify that the message is not multipart.
if ( o instanceof String ) {
String body = (String)o;
}
//...
Note: Invoke getBodyText() on a message to retrieve the plain text contents as a String. If the message does not
contain plain text, the method returns null.
Send a message
To send messages, use a Transport object, which represents the messaging transport protocol.
Create a message
Create a Message object, and specify a folder in which to save a copy of the sent message.
Store store = Session.getDefaultInstance().getStore();
Folder[] folders = store.list(Folder.SENT);
Folder sentfolder = folders[0];
Message msg = new Message(sentfolder);
Specify recipients
Create an array of Address objects, and then add each address to the array. Your application should
catch an AddressException, which is thrown if an address is invalid.
Address toList[] = new Address[1];
try {
toList[0]= new Address("[email protected]", "Aisha Wahl");
} catch(AddressException e) {
System.out.println(e.toString());
}
Add recipients
Invoke Message.addRecipients(). Provide the type of recipient (TO, CC, or BCC) and the array of
addresses to add as parameters to this method. If your message has multiple types of recipients, invoke
addRecipients() once each.
msg.addRecipients(Message.RecipientType.TO, toList);
15
BlackBerry Application Developer Guide
Reply to a message
To create a message as a reply to an existing message, invoke Message.reply(Boolean). As a
parameter to this method, specify true to reply to all message recipients or false to reply only to the
sender.
Store store = Session.waitForDefaultSession().getStore();
Folder[] folders = store.list(INBOX);
Folder inbox = folders[0];
Message[] messages = folder.getMessages();
if( messages.length > 0 ) {
Message msg = messages[0];
}
Message reply = msg.reply(true);
Transport.send(reply);
Forward a message
Invoke forward() on an existing Message object.
Note: The subject line of a forwarded message is set automatically to FW:<original_subject>.
Add recipients
Create an array of addresses, and then invoke addRecipients(int, Address[]).
Address toList[] = new Address[1];
toList[0]= new Address("[email protected]", "Katie Laird");
fwdmsg.addRecipients(Message.RecipientType.TO, toList);
16
2: Integrating messages
try {
fwdmsg.setContent("This is a forwarded message.");
} catch(MessagingException e) {
System.out.println(e.getMessage());
}
Code example
Example: BasicMail.java
/**
* BasicMail.java
* Copyright (C) 2001-2005 Research In Motion Limited.
*/
package com.rim.samples.docs.basicmail;
import net.rim.blackberry.api.mail.*;
import net.rim.blackberry.api.mail.event.*;
import net.rim.device.api.system.*;
17
BlackBerry Application Developer Guide
}
try {
msg.addRecipients(Message.RecipientType.TO, toList);
} catch (MessagingException e) {
System.out.println(e.toString());
}
// Add CC Recipients.
Address ccList[] = new Address[1];
try {
ccList[0]= new Address("[email protected]", "Katie Laird");
} catch(AddressException e) {
System.out.println(e.toString());
}
try {
msg.addRecipients(Message.RecipientType.CC, ccList);
} catch (MessagingException e) {
System.out.println(e.toString());
}
// Add the subject.
msg.setSubject("A Test Email");
// Add the message body.
try {
msg.setContent("This is a test message.");
} catch(MessagingException e) {
// Handle messaging exceptions.
}
// Send the message.
try {
Transport.send(msg);
} catch(MessagingException e) {
System.out.println(e.getMessage());
}
System.out.println("Email sent successfully.");
System.exit(0);
}
}
Managing folders
To list, retrieve, and search for folders, retrieve a Store object by invoking getStore() on the default
session.
Store store = Session.waitForDefaultSession().getStore();
18
2: Integrating messages
The findFolder(String) method returns an array of folders that match the specified string, or an
empty array if a matching folder is not found.
Retrieve a folder by ID
Invoke getID() to retrieve the folder ID, and then invoke getFolder() with the ID as a parameter.
Folder[] folders = store.list();
long id = folders[0].getId();
Folder f2 = store.getFolder(id);
File a message
Invoke appendMessage(Message) on a Folder object.
Message msg = new Message();
//...
Folder folder = store.getFolder("Inbox");
folder.appendMessage(msg);
Managing attachments
The mail API enables you to open incoming message attachments and to create outgoing attachments
on the BlackBerry device. A message attachment is represented as a separate BodyPart on a Multipart
message.
19
BlackBerry Application Developer Guide
AttachmentHandlerManager m = AttachmentHandlerManager.getInstance();
CustomAttachmentHandler ah = new CustomAttachmentHandler();
m.addAttachmentHandler(ah);
Retrieving attachments
The SupportedAttachmentPart class represents an attachment with a corresponding viewer on the
BlackBerry device. An attachment that does not have a viewer on the BlackBerry device is represented as
an UnsupportedAttachmentPart.
20
2: Integrating messages
21
BlackBerry Application Developer Guide
22
3
Integrating PIM functions
• PIM APIs
• Using the address book
• Using tasks
• Using the calendar
PIM APIs
The Java personal information management (PIM) APIs (javax.microedition.pim) and the BlackBerry
personal digital assistant profile (PDAP) APIs (net.rim.blackberry.api.pdap) enable you to access
the calendar, tasks, and address book on the BlackBerry device.
Note: As of version 4.0, the net.rim.blackberry.api.pim package is deprecated. The classes from this package are
now available in the javax.microedition.pim and net.rim.blackberry.api.pdap packages.
The PIM class is an abstract class that provides methods for accessing PIM databases on the BlackBerry
device. Invoke PIM.getInstance() to retrieve a PIM object.
Note: Check for a ControlledAccessException when your application first accesses the PIM API. This runtime exception
is thrown if the system administrator restricts access to the PIM API using application control. See the BlackBerry
Application Developer Guide Volume 1: Fundamentals for more information.
PIM lists
The PIMList interface represents the common functionality of all contact, event, or task lists. A list
contains zero or more items, represented by subclasses of PIMItem. Use PIM lists to organize related
items and to retrieve some or all of the items in the list.
Note: On BlackBerry devices, each ContactList, ToDoList, or EventList instance refers to the native database on the
BlackBerry device. Third-party applications cannot create custom lists.
PIM items
The PIMItem interface represents the common functionality of an item in a list. The Contact, Event,
and ToDo interfaces extend PIMItem. A PIM item represents a collection of data for a single entry, such
as a calendar appointment or a contact.
When you create a PIM item in a particular PIM list, the item remains associated with that list as long as
it exists. You can also import or export data in PIM items using standard formats, such as iCal and vCard.
Fields
A PIM item stores data in fields.
Each PIMItem interface—Contact, Event, or ToDo—defines unique integer IDs for each field that it
supports. For example, the Contact interface defines fields to store an internet messaging address
(EMAIL), name (FORMATTED_NAME), and phone number (TEL).
BlackBerry Application Developer Guide
Each field has a data type ID, such as INT, BINARY, DATE, BOOLEAN, or STRING. To retrieve the data type
of a field, invoke PIMList.getFieldDataType(int). The data type determines which method you use
to get or set field data. For example, if the data type for a field is STRING, invoke
PIMItem.addString(String) to add a value, PIMItem.setString(String) to change an existing
value, and PIMItem.getString() to retrieve a value.
Before you attempt to set or retrieve a field value, verify that the method supports the field by invoking
PIMList.isSupportedField(int).
A field can have an associated descriptive label to display to users. To retrieve a field label, invoke
PIMList.getFieldLabel(int).
Listeners
Your implementation of the PIMListListener interface receives notification when an item in a list
changes. The PIMListListener interface provides three methods:
Method Description
itemAdded(PIMItem) invoked when an item is added to a list
itemRemoved(PIMItem) invoked when an item is removed from a list
itemUpdated(PIMItem, PIMItem) invoked when an item changes
ContactList cl = (ContactList)PIM.getInstance().openPIMList(
PIM.CONTACT_LIST, PIM.WRITE_ONLY);
((BlackBerryPIMList)cl).addListener(new PIMListListener() {
public void itemAdded(PIMItem item) {
System.out.println(" ITEM ADDED: " + ((Contact)item).getString(Contact.UID,
0));
}
public void itemUpdated(PIMItem oldItem, PIMItem newItem) {
System.out.println(" ITEM UPDATED: " +
((Contact)oldItem).getString(Contact.UID, 0) + " to " +
((Contact)newItem).getString(Contact.UID, 0));
}
public void itemRemoved(PIMItem item) {
System.out.println(" ITEM REMOVED: " +
((Contact)item).getString(Contact.UID, 0));
}
});
Note: The listener remains associated with the BlackBerry device database even after the corresponding PIMList object
has been deleted. To remove the listener, invoke BlackBerryPIMList.removeListener().
Method Description
choose(Contact, int, boolean) Launches the address book so that the user can select an address.
void lookup(Contact, RemoteLookupListener) Initiates a remote lookup.
void lookup(String, RemoteLookupListener) Initiates a remote lookup.
24
3: Integrating PIM functions
Constant Description
BlackBerryContact.PIN provides access to the PIN field
BlackBerryContact.USER1 through provide access to the USER1 through USER4 fields
USER4
Invoke BlackBerryPIMList.setFieldLabel() to define labels for the USER1 through USER4 fields.
The change takes effect immediately; you do not need to commit the change.
Create a contact
Invoke createContact() on a contact list.
Contact contact = contactList.createContact();
Note: The contact is not added to the database until you commit it. See “Save a contact” on page 27 for more information.
25
BlackBerry Application Developer Guide
26
3: Integrating PIM functions
For fields that support multiple values, verify that the maximum number of values is not exceeded before
adding another value.
if (contact.countValues(Contact.EMAIL) < contactList.maxValues(Contact.EMAIL)) {
contact.addString(Contact.EMAIL, Contact.ATTR_NONE,
"[email protected]");
}
Save a contact
Invoke commit(). Before you commit the change, invoke isModified() to determine whether any
contact fields have changed since the contact was last saved.
if(contact.isModified()) {
contact.commit();
}
27
BlackBerry Application Developer Guide
For a particular contact, invoke PIMItem.getFields() to retrieve an array of IDs for fields that have
data. Invoke PIMItem.getString() to retrieve the field values.
ContactList contactList = (ContactList)PIM.getInstance().openPIMList(
PIM.CONTACT_LIST, PIM.READ_WRITE);
Enumeration enum = contactList.items();
while (enum.hasMoreElements()) {
Contact c = (Contact)enum.nextElement();
int[] fieldIds = c.getFields();
int id;
for(int index = 0; index < fieldIds.length; ++index) {
id = fieldIds[index];
if(c.getPIMList().getFieldDataType(id) == Contact.STRING) {
for(int j=0; j < c.countValues(id); ++j) {
String value = c.getString(id, j);
System.out.println(c.getPIMList().getFieldLabel(id) + "=" + value);
}
}
}
}
Import a contact
Invoke fromSerialFormat(), which returns an array of PIM items. To create a new contact using the
PIM item, invoke ContactList.importContact()
Note: The enc parameter specifies the character encoding to use when writing to the output stream. Supported character
encodings include "UTF8," "ISO-8859-1," and "UTF-16BE." This parameter cannot be null.
28
3: Integrating PIM functions
Delete a contact
Invoke removeContact() on a contact list.
contactList.removeContact(contact);
Code example
The following example demonstrates how to display a screen that enables users to add new contacts to
the address book. After you save a contact, open the address book to verify that the contact was saved.
Example: ContactsDemo.java
/**
* ContactsDemo.java
* Copyright (C) 2002-2005 Research In Motion Limited.
*/
package com.rim.samples.docs.contactsdemo;
import java.io.*;
import java.util.*;
import javax.microedition.pim.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.i18n.*;
import net.rim.device.api.system.*;
import net.rim.device.api.util.*;
import com.rim.samples.docs.baseapp.*;
import net.rim.blackberry.api.pdap.*;
29
BlackBerry Application Developer Guide
}
public ContactsDemo() {
_contactScreen = new ContactScreen();
pushScreen(_contactScreen);
}
protected void onExit() {
}
// Inner class. Creates a Screen to add a contact.
public static final class ContactScreen extends MainScreen {
private EditField _first, _last, _email, _phone, _pin;
private SaveMenuItem _saveMenuItem;
private class SaveMenuItem extends MenuItem {
private SaveMenuItem() {
super(null, 0, 100000, 5);
}
public String toString() {
return "Save";
}
public void run() {
onSave();
}
}
public ContactScreen() {
_saveMenuItem = new SaveMenuItem();
setTitle(new LabelField("Contacts Demo", LabelField.ELLIPSIS |
LabelField.USE_ALL_WIDTH));
_first = new EditField("First Name: ", "");
add(_first);
_last = new EditField("Last Name: ", "");
add(_last);
_email = new EditField("Email Address: ", "",
BasicEditField.DEFAULT_MAXCHARS, BasicEditField.FILTER_EMAIL);
add(_email);
_phone = new EditField("Work Phone: ", "",
BasicEditField.DEFAULT_MAXCHARS, BasicEditField.FILTER_PHONE);
add(_phone);
_pin = new EditField("PIN:", "", 8, BasicEditField.FILTER_HEXADECIMAL);
add(_pin);
}
protected boolean onSave() {
String firstName = _first.getText();
String lastName = _last.getText();
String email = _email.getText();
String phone = _phone.getText();
String pin = _pin.getText();
// Verify that a first or last name and email has been entered.
if ((firstName.equals("") && lastName.equals("")) || email.equals("")) {
Dialog.inform("You must enter a name and an email address!");
return false;
} else {
try {
ContactList contactList =
(ContactList)PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.WRITE_ONLY);
Contact contact = contactList.createContact();
String[] name = new
String[contactList.stringArraySize(Contact.NAME)];
30
3: Integrating PIM functions
Using tasks
Use an instance of the ToDoList class to store a list of tasks or to-do items. Create one or more ToDo
objects to store data for each task, such as summary, priority, due date, and status.
31
BlackBerry Application Developer Guide
return;
}
Create a task
Invoke createToDo() on a task list.
ToDo task = todoList.createToDo();
Note: The task is not added to the database until you commit it. See “Save a task” on page 33 for more information.
if (task.isSupportedField(ToDo.SUMMARY)) {
task.addString(ToDo.SUMMARY, ToDo.ATTR_NONE, "Create project plan");
}
if (task.isSupportedField(ToDo.DUE)) {
Date date = new Date();
task.addDate(ToDo.DUE, ToDo.ATTR_NONE, (date + 17280000));
}
if (task.isSupportedField(ToDo.NOTE)) {
task.addString(ToDo.NOTE, ToDo.ATTR_NONE, "Required for meeting");
}
if (task.isSupportedField(ToDo.PRIORITY)) {
task.addInt(Todo.PRIcORITY, ToDo.ATTR_NONE, 2);
}
Constant Value
STATUS_NOT_STARTED 1
STATUS_IN_PROGRESS 2
STATUS_COMPLETED 3
STATUS_WAITING 4
STATUS_DEFERRED 5
32
3: Integrating PIM functions
if (task.countValues(ToDo.SUMMARY) > 0) {
task.setString(ToDo.SUMMARY, 0, ToDo.ATTR_NONE, "Review notes");
}
Save a task
Invoke commit(). Before you save, invoke isModified() to determine whether any task fields have
changed since the task was last saved.
if(task.isModified()) {
task.commit();
}
while (enum.hasMoreElements()) {
ToDo task = (ToDo)enum.nextElement();
int[] fieldIds = task.getFields();
int id;
for(int index = 0; index < fieldIds.length; ++index) {
id = fieldIds[index];
if(task.getPIMList().getFieldDataType(id) == STRING) {
for(int j=0; j < task.countValues(id); ++j) {
String value = task.getString(id, j);
System.out.println(task.getFieldLable(id) + "=" + value);
}
}
}
}
33
BlackBerry Application Developer Guide
Import a task
Invoke fromSerialFormat(), which returns an array of PIMItem objects. To create a new task using the
PIM items, invoke ToDoList.importToDo().
Note: The enc parameter specifies the character encoding to use when writing to the output stream. Supported character
encodings include "UTF8," "ISO-8859-1," and "UTF-16BE." This parameter cannot be null.
Delete a task
Invoke removeToDo() on a task list.
todoList.removeToDo(task);
34
3: Integrating PIM functions
todoList.close();
} catch (PimException e) {
// Handle exception.
}
Code example
Example: TaskDemo.java
/**
* TaskDemo.java
* Copyright (C) 2002-2005 Research In Motion Limited.
*/
package com.rim.samples.docs.taskdemo;
import java.io.*;
import java.util.*;
import javax.microedition.pim.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.i18n.*;
import net.rim.device.api.system.*;
import net.rim.device.api.util.*;
import com.rim.samples.docs.baseapp.*;
35
BlackBerry Application Developer Guide
public TaskScreen() {
_saveMenuItem = new SaveMenuItem();
setTitle(new LabelField("Tasks Demo",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH));
_summary = new EditField("Task Summary: ", "");
add(_summary);
// In TODO.Priority, 0 to 9 is highest to lowest priority.
String[] choices = {"High", "Normal", "Low"};
_priority = new ObjectChoiceField("Priority: ", choices, 1);
add(_priority);
String[] status = { "Not Started", "In Progress", "Completed",
"Waiting on someone else", "Deferred" };
_status = new ObjectChoiceField("Status: ", status, 0);
add(_status);
_due = new DateField("Due: ", System.currentTimeMillis() + 3600000,
DateField.DATE_TIME);
add(_due);
_note = new EditField("Extra Notes: ", "");
add(_note);
}
protected boolean onSave() {
try {
ToDoList todoList = (ToDoList)PIM.getInstance().
openPIMList(PIM.TODO_LIST, PIM.WRITE_ONLY);
ToDo task = todoList.createToDo();
task.addDate(ToDo.DUE, ToDo.ATTR_NONE, _due.getDate());
task.addString(ToDo.SUMMARY, ToDo.ATTR_NONE, _summary.getText());
task.addString(ToDo.NOTE, ToDo.ATTR_NONE, _note.getText());
task.addInt(ToDo.PRIORITY, ToDo.ATTR_NONE,
_priority.getSelectedIndex());
// ToDo.EXTENDED_FIELD_MIN_VALUE + 9 represents status.
// Add 1 to selected index so that values are correct.
// See the RIM Implementation Notes in the API docmentation for
ToDo.
task.addInt(ToDo.EXTENDED_FIELD_MIN_VALUE + 9, ToDo.ATTR_NONE,
_status.getSelectedIndex() + 1);
// Save task to handheld tasks.
task.commit();
_summary.setText("");
_note.setText("");
_due.setDate(null);
_priority.setSelectedIndex(1); // Reset to “Normal” priority.
_status.setSelectedIndex(0); // Reset to “Not Started” status.
return true;
} catch (PIMException e) {
return false;
}
}
protected void makeMenu(Menu menu, int instance) {
menu.add(_saveMenuItem);
super.makeMenu(menu, instance);
}
}
}
36
3: Integrating PIM functions
Create an appointment
Invoke createEvent() on an event list.
Event event = eventList.createEvent();
Note: The appointment is not added to the database until you commit the change. See “Save an appointment” on page
38 for more information.
if (event.isSupportedField(Event.SUMMARY)) {
event.addString(Event.SUMMARY, Event.ATTR_NONE, "Meet with customer");
}
if (event.isSupportedField(Event.LOCATION)) {
event.addString(Event.LOCATION, Event.ATTR_NONE, "Conference Center");
}
Date start = new Date(System.currentTimeMillis() + 8640000);
if (event.isSupportedField(Event.START)) {
event.addDate(Event.START, Event.ATTR_NONE, start);
}
if (event.isSupportedField(Event.END)) {
event.addDate(Event.END, Event.ATTR_NONE, start + 72000000);
}
37
BlackBerry Application Developer Guide
if (event.isSupportedField(Event.ALARM)) {
if (event.countValues(Event.ALARM) > 0) {
event.removeValue(Event.ALARM,0);
event.setInt(Event.ALARM, 0, Event.ATTR_NONE, 396000);
}
}
Save an appointment
Tip: The importEvent() method saves the appointment, so you do not have to invoke commit().
Invoke commit(). Before you save the appointment, invoke isModified() to determine whether any of
the appointment fields have changed since the appointment was last saved.
if(event.isModified()) {
event.commit();
}
38
3: Integrating PIM functions
Enumeration e = eventList.items();
while (e.hasMoreElements()) {
Event event = (Event)e.nextElement();
PIM.getInstance().toSerialFormat(event, byteStream, "UTF8", dataFormats[0]);
}
39
BlackBerry Application Developer Guide
Import an appointment
Invoke fromSerialFormat(java.io.InputStream is, java.lang.String enc), which returns an
array of PIMItem objects. Invoke EventList.importEvent() to add a new appointment.
Note: The enc parameter specifies the character encoding to use when writing to the output stream. Supported character
encodings include "UTF8," "ISO-8859-1," and "UTF-16BE." This parameter cannot be null.
// Convert an existing appointment into a iCal and then import the iCal as a new
// appointment.
String[] dataFormats = PIM.eventSerialFormats();
// Write appointment to iCal.
ByteArrayOutputStream os = new ByteArrayOutputStream();
PIM.getInstance().toSerialFormat(event, os, "UTF8", dataFormats[0]);
// Import appointment from iCal.
ByteArrayInputStream is = new ByteArrayInputStream(outputStream.toByteArray());
PIMItem[] pi = PIM.getInstance().fromSerialFormat(is, "UTF8");
EventList eventList = (EventList)PIM.getInstance().openPIMList(
PIM.EVENT_LIST, PIM.READ_WRITE);
Event event2 = eventList.importEvent((Event)pi[0]);
Code example
The following example displays a screen that enables users to create new, recurring appointments in the
calendar. You could combine this sample with ContactsDemo.java to allow the user to invite attendees
to the meeting. See “ContactsDemo.java” on page 29 for more information.
After you save an appointment, click the Calendar icon to verify that the appointment was saved.
Example: EventDemo.java
/**
* EventDemo.java
* Copyright (C) 2002-2005 Research In Motion Limited.
*/
package com.rim.samples.docs.eventdemo;
import java.io.*;
import java.util.*;
import javax.microedition.pim.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.i18n.*;
40
3: Integrating PIM functions
import net.rim.device.api.system.*;
import net.rim.device.api.util.*;
import com.rim.samples.docs.baseapp.*;
41
BlackBerry Application Developer Guide
openPIMList(PIM.EVENT_LIST, PIM.WRITE_ONLY);
event = eventList.createEvent();
event.addString(Event.SUMMARY, PIMItem.ATTR_NONE,
_subject.getText());
event.addString(Event.LOCATION, PIMItem.ATTR_NONE,
_location.getText());
event.addDate(Event.END, PIMItem.ATTR_NONE, _endTime.getDate());
event.addDate(Event.START, PIMItem.ATTR_NONE,
_startTime.getDate());
if(_repeat.getSelectedIndex() != 0) {
event.setRepeat(setRule());
}
// Save the appointment to the Calendar.
event.commit();
//reset fields on screen
_subject.setText("");
_location.setText("");
_endTime.setDate(null);
_startTime.setDate(null);
_repeat.setSelectedIndex(0);
return true;
} catch (PIMException e) {
System.err.println(e);
}
return false;
}
private RepeatRule setRule() {
RepeatRule rule = new RepeatRule();
int index = _repeat.getSelectedIndex();
if (index == 0) {
rule.setInt(RepeatRule.FREQUENCY, RepeatRule.DAILY);
}
if (index == 1) {
rule.setInt(RepeatRule.FREQUENCY, RepeatRule.WEEKLY);
}
if (index == 2) {
rule.setInt(RepeatRule.FREQUENCY, RepeatRule.MONTHLY);
}
if (index == 3) {
rule.setInt(RepeatRule.FREQUENCY, RepeatRule.YEARLY);
}
return rule;
}
protected void makeMenu(Menu menu, int instance) {
menu.add(_saveMenuItem);
menu.addSeparator();
super.makeMenu(menu, instance);
}
}
}
42
4
Adding handheld options
• Options API
• Adding option items
Options API
The BlackBerry options API, in the net.rim.blackberry.api.options package, enables you to add
items to the handheld options. Use this capability to add system-wide options to the BlackBerry device
that multiple applications can use.
When users click the Options icon on the Home screen, a list of options, such as AutoText, Date/Time,
and Firewall, appears. The user can select one of these items to view a screen for that particular option.
The screen displays one or more fields. Typically, the user can change the value of each field.
Store options
To store the option value that is currently selected, implement the Persistable interface. In your
implementation, define methods for setting the selected option value, and for committing and retrieving
an option value in the persistent store.
Note: If you implement the Persistable interface as an inner class, make it—and its get(), set(), and commit()
methods—public so that other applications can access your options data.
See “Managing persistent data” on page 85 for more information on storing persistent data.
Code example
This example demonstrates the use of the options facilities.
Example: DemoOptionsProvider.java
/**
* DemoOptionsProvider.java
* Copyright 2002-2005 Research In Motion Limited.
*/
package com.rim.samples.docs.demooptionsprovider;
import net.rim.blackberry.api.options.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.i18n.*;
import net.rim.device.api.system.*;
import net.rim.device.api.util.*;
44
4: Adding handheld options
45
BlackBerry Application Developer Guide
}
private static OptionsDemoData load() {
PersistentObject persist = PersistentStore.getPersistentObject(
OptionsDemoData.ID );
OptionsDemoData contents = (OptionsDemoData)persist.getContents();
synchronized( persist ) {
if( contents == null ) {
contents = new OptionsDemoData();
persist.setContents( contents );
persist.commit();
}
}
return contents;
}
}
}
46
5
BlackBerry Browser
• Browser APIs
• Displaying web content in the browser
• Displaying web content in a browser field
• Supporting additional MIME types
• Registering as an HTTP filter
Browser APIs
API name and package Description
Browser application API This API enables applications to display web content, including supported image types, HTML and WML
(net.rim.blackberry.api.browser) pages, by invoking the BlackBerry Browser. It also enables applications to supply a referrer, HTTP headers
and post data in an HTTP request. See “Displaying web content in the browser” on page 47 for more
information.
Browser field API This API enables an application to retrieve web content for display in a browser field, which is included
(net.rim.blackberry.api.browser. in the application UI. This API also enables applications to configure the appearance of the browser field,
field) such as by eliminating the scroll bar or specifying displaying the browser field in only a portion of the
screen. See “Displaying web content in a browser field” on page 48 for more information.
Browser page API This API enables applications to add support for additional MIME types. By registering as rendering
(net.rim.blackberry.api.browser. provider for a MIME type when the BlackBerry device starts, all subsequent browser sessions will support
plugin) the additional MIME type. See “Supporting additional MIME types” on page 62 for more information.
HTTP Filter API This API enables applications to register with the browser as provider for one or more URLs. See
(net.rim.device.api.io.http) “Registering as an HTTP filter” on page 67 for more information.
To retrieve a different session, invoke getSession(). This method retrieves a browser configuration
service record according to its unique ID (UID). See “Service book API” on page 107 for more
information.
BlackBerry Application Developer Guide
Code sample
The following excerpt from the Restaurants.java sample creates a menu item that displays a web page in
the browser.
private MenuItem browserItem = new
MenuItem(_resources.getString(MENUITEM_BROWSER), 110, 12) {
public void run() {
synchronized(store) {
String websiteUrl = websitefield.getText();
if (websiteUrl.length == 0) {
Dialog.alert(_resources.getString(ALERT_NO_WEBSITE));
} else {
BrowserSession visit = Browser.getDefaultSession();
visit.displayPage(websiteUrl);
}
}
}
};
The RenderingApplication interface defines the callback functionality a rendering session requires to
assist with handling URL resources. Your implementation of the RenderingApplication interface
displays web content in a browser field.
48
5: BlackBerry Browser
_renderingApplication = new
BasicRenderingApplication(_callBackApplication);
BrowserField field =
_renderingApplication.getBrowserField("www.blackberry.com");
_callBackApplication.displayBrowserField(field);
}
}
Handle events
Your implementation of eventOccurred() handles events, such as a URL request.
public Object eventOccurred(Event event) {
int eventId = event.getUID();
switch (eventId) {
case Event.EVENT_URL_REQUESTED : {
UrlRequestedEvent e = (UrlRequestedEvent) event;
// This is a regular request.
String absoluteUrl = e.getURL();
HttpConnection conn = null;
OutputStream out = null;
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
FormData postData = e.getPostData();
if (postData == null) {
conn.setRequestMethod(HttpConnection.GET);
} else {
conn.setRequestMethod(HttpConnection.POST);
byte[] postBytes = postData.getBytes();
conn.setRequestProperty(
HttpProtocolConstants.HEADER_CONTENT_LENGTH,
String.valueOf(postBytes.length));
if (conn.getRequestProperty(
HttpProtocolConstants.HEADER_CONTENT_TYPE) == null) {
conn.setRequestProperty(
HttpProtocolConstants.HEADER_CONTENT_TYPE,
postData.getContentType());
}
out = conn.openOutputStream();
out.write(postBytes);
}
HttpHeaders requestHeaders = e.getHeaders();
if (requestHeaders != null) {
/* From
http://www.w3.org/Protocols/rfc2616/rfc2616-
sec15.html#sec15.1.3
...
Clients SHOULD NOT include a Referer header field in a
49
BlackBerry Application Developer Guide
50
5: BlackBerry Browser
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
} catch (IOException e1) {
}
BrowserField browserField = getBrowserField(conn,
e.getOriginalEvent());
_callbackApplication.displayBrowserField(browserField);
break;
}
case Event.EVENT_CLOSE :
// Close the appication.
break;
case Event.EVENT_SET_HEADER :// no cache support
case Event.EVENT_SET_HTTP_COOKIE : // no cookie support
case Event.EVENT_HISTORY : // no history support
case Event.EVENT_LOADING_IMAGES :// no progress bar is supported
case Event.EVENT_EXECUTING_SCRIPT : // no progress bar is supported
case Event.EVENT_FULL_WINDOW : // no full window support
case Event.EVENT_STOP : // no stop loading support
default :
}
return null;
}
51
BlackBerry Application Developer Guide
}
}
Code example
The following example consists of three files: BasicRenderingApplication.java,
BrowserFieldHandlerApplication.java, and BrowserFieldSampleApp.java.
package com.rim.samples.docs.browser;
import java.io.IOException;
import java.io.OutputStream;
52
5: BlackBerry Browser
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.browser.field.*;
import net.rim.device.api.io.http.HttpHeaders;
import net.rim.device.api.io.http.HttpProtocolConstants;
import net.rim.device.api.system.Application;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.component.Status;
import com.rim.samples.docs.browser.BrowserFieldHandlerApplication.*;
/**
* Invoked when an event occurs.
*/
public Object eventOccurred(Event event) {
int eventId = event.getUID();
switch (eventId) {
case Event.EVENT_URL_REQUESTED : {
UrlRequestedEvent e = (UrlRequestedEvent) event;
53
BlackBerry Application Developer Guide
54
5: BlackBerry Browser
}
case Event.EVENT_BROWSER_CONTENT_CHANGED : {
// Browser field title might have changed. Update title.
break;
}
case Event.EVENT_REDIRECT : {
RedirectEvent e = (RedirectEvent) event;
switch (e.getType()) {
case RedirectEvent.TYPE_SINGLE_FRAME_REDIRECT :
// Show redirect message.
Application.getApplication().invokeAndWait(new Runnable() {
public void run() {
Status.show("");
}
});
break;
case RedirectEvent.TYPE_JAVASCRIPT :
case RedirectEvent.TYPE_META :
case RedirectEvent.TYPE_300_REDIRECT :
}
String absoluteUrl = e.getLocation();
HttpConnection conn = null;
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
} catch (IOException e1) {
}
BrowserContent browserField = getBrowserField(conn,
e.getOriginalEvent());
_callbackApplication.displayBrowserField(browserField);
break;
}
case Event.EVENT_CLOSE :
// Close the appication.
break;
55
BlackBerry Application Developer Guide
}
/**
* Retrieves the pixels of width available for provided browser content.
*/
public int getAvailableWidth(BrowserContent browserField) {
// Field has full screen.
return Graphics.getScreenWidth();
}
/**
* Retrieves the history position for provided browser content.
*/
public int getHistoryPosition(BrowserContent browserField) {
// No history support.
return 0;
}
/**
* Retrieves cookies associated with a provided URL.
*/
public String getHTTPCookie(String url) {
// No cookie support.
return null;
}
/**
* Retrieves the specified resource.
*/
public HttpConnection getResource( RequestedResource resource, BrowserContent
referrer) {
if (resource == null) {
return null;
}
// Check if this is cache-only request.
if (resource.isCacheOnly()) {
// No cache support.
return null;
}
String url = resource.getUrl();
if (url == null) {
return null;
}
// If referrer is null, return the connection.
if (referrer == null) {
HttpConnection conn;
try {
return (HttpConnection) Connector.open(resource.getUrl());
} catch (IOException e) {
return null;
}
} else {
// If referrer is provided, set up the connection on a
// separate thread.
Application.getApplication().invokeLater(
new RetrieveThread(resource, referrer));
}
return null;
}
56
5: BlackBerry Browser
/**
* Invokes the provided runnable object.
*/
public void invokeRunnable(Runnable runnable) {
(new Thread(runnable)).run();
}
}
class RenderingThread implements Runnable {
BrowserContent _browserField;
RenderingThread(BrowserContent field) {
_browserField = field;
}
public void run() {
try {
_browserField.finishLoading();
} catch (RenderingException e) {
}
}
}
package com.rim.samples.docs.browser;
import java.io.IOException;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.browser.field.*;
import net.rim.device.api.io.http.HttpHeaders;
import net.rim.device.api.io.http.HttpProtocolConstants;
import net.rim.device.api.system.Application;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.component.Status;
57
BlackBerry Application Developer Guide
import com.rim.samples.docs.browser.BrowserFieldHandlerApplication.*;
/**
* Invoked when an event occurs.
*/
public Object eventOccurred(Event event) {
int eventId = event.getUID();
switch (eventId) {
case Event.EVENT_URL_REQUESTED : {
UrlRequestedEvent e = (UrlRequestedEvent) event;
// this is a regular request
String absoluteUrl = e.getURL();
HttpConnection conn = null;
OutputStream out = null;
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
byte[] postData = e.getPostData();
if (postData == null) {
58
5: BlackBerry Browser
conn.setRequestMethod(HttpConnection.GET);
} else {
conn.setRequestMethod(HttpConnection.POST);
conn.setRequestProperty(
HttpProtocolConstants.HEADER_CONTENT_LENGTH,
String.valueOf(postData.length));
out = conn.openOutputStream();
out.write(postData);
}
HttpHeaders requestHeaders = e.getHeaders();
if (requestHeaders != null) {
/* From
http://www.w3.org/Protocols/rfc2616/rfc2616-
sec15.html#sec15.1.3
...
Clients SHOULD NOT include a Referer header field in a
(non-secure) HTTP request if the referring page was
transferred with a secure protocol.*/
String referer = requestHeaders.getPropertyValue("referer");
boolean sendReferrer = true;
if (referer != null && referer.startsWith("https:") &&
!absoluteUrl.startsWith("https:")) {
sendReferrer = false;
}
int size = requestHeaders.size();
for (int i = 0; i < size; i++) {
String header = requestHeaders.getPropertyKey(i);
// Remove refer header if needed.
if ( !sendReferrer && header.equals("referrer")) {
requestHeaders.removeProperty(i);
continue;
}
conn.setRequestProperty( header,
requestHeaders.getPropertyValue( i ) );
}
}
} catch (IOException e1) {
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e2) {
}
}
}
BrowserContent browserField = getBrowserField(conn, e);
_callbackApplication.displayBrowserField(browserField);
break;
}
case Event.EVENT_BROWSER_CONTENT_CHANGED : {
// Browser field title might have changed. Update title.
break;
}
case Event.EVENT_REDIRECT : {
RedirectEvent e = (RedirectEvent) event;
switch (e.getType()) {
59
BlackBerry Application Developer Guide
case RedirectEvent.TYPE_SINGLE_FRAME_REDIRECT :
// Show redirect message.
Application.getApplication().invokeAndWait(new Runnable() {
public void run() {
Status.show("");
}
});
break;
case RedirectEvent.TYPE_JAVASCRIPT :
case RedirectEvent.TYPE_META :
case RedirectEvent.TYPE_300_REDIRECT :
}
String absoluteUrl = e.getLocation();
HttpConnection conn = null;
try {
conn = (HttpConnection) Connector.open(absoluteUrl);
} catch (IOException e1) {
}
BrowserContent browserField = getBrowserField(conn,
e.getOriginalEvent());
_callbackApplication.displayBrowserField(browserField);
break;
}
case Event.EVENT_CLOSE :
// Close the appication.
break;
60
5: BlackBerry Browser
/**
* Retrieves the history position for provided browser content.
*/
public int getHistoryPosition(BrowserContent browserField) {
// No history support.
return 0;
}
/**
* Retrieves cookies associated with a provided URL.
*/
public String getHTTPCookie(String url) {
// No cookie support.
return null;
}
/**
* Retrieves the specified resource.
*/
public HttpConnection getResource( RequestedResource resource, BrowserContent
referrer) {
if (resource == null) {
return null;
}
// Check if this is cache-only request.
if (resource.isCacheOnly()) {
// No cache support.
return null;
}
String url = resource.getUrl();
if (url == null) {
return null;
}
// If referrer is null, return the connection.
if (referrer == null) {
HttpConnection conn;
try {
return (HttpConnection) Connector.open(resource.getUrl());
} catch (IOException e) {
return null;
}
} else {
// If referrer is provided, set up the connection on a
// separate thread.
Application.getApplication().invokeLater(
new RetrieveThread(resource, referrer));
}
return null;
}
/**
* Invokes the provided runnable object.
*/
public void invokeRunnable(Runnable runnable) {
(new Thread(runnable)).run();
}
}
class RenderingThread implements Runnable {
61
BlackBerry Application Developer Guide
BrowserContent _browserField;
RenderingThread(BrowserContent field) {
_browserField = field;
}
public void run() {
try {
_browserField.finishLoading();
} catch (RenderingException e) {
}
}
}
62
5: BlackBerry Browser
if (context == null) {
throw new RenderingException("No Context is passed into Provider");
}
63
BlackBerry Application Developer Guide
context.getRenderingApplication(),
context.getRenderingSession().getRenderingOptions(), context.getFlags());
VerticalFieldManager vfm = new VerticalFieldManager(Manager.VERTICAL_SCROLL);
vfm.add(new LabelField("Mime type: ") );
vfm.add(new LabelField(ACCEPT[0]));
vfm.add(new SeparatorField());
vfm.add(new LabelField("Content of the resource file: \n"));
vfm.add(new SeparatorField());
try {
HttpConnection conn = context.getHttpConnection();
InputStream in = conn.openInputStream();
byte[] data = IOUtilities.streamToBytes(in);
vfm.add(new LabelField(new String(data)));
} catch (IOException e) {
// TODO Implement.
e.printStackTrace();
}
browserContentBaseImpl.setContent(vfm);
browserContentBaseImpl.setTitle(ACCEPT[0]);
// Set browser page context, this will tell the browser how to display this
// field.
browserContentBaseImpl.setBrowserPageContext(this);
return browserContentBaseImpl;
}
Code example
The following example consists of two files, LoaderApp.java, which adds support for the new MIME type
when the BlackBerry device starts, and BrowserPlugin.java, which contains a class that extends
BrowserContentProvider.
64
5: BlackBerry Browser
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.browser.field.*;
import net.rim.device.api.browser.plugin.*;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.VerticalFieldManager;
/**
* Create a file with xxtest extension and associate that type with
* application/x-vnd.rim.xxxtest mime type on any server.
*/
public final class BrowserPlugin extends BrowserContentProvider implements
BrowserPageContext {
/**
* Retrieves list of mime types this provider can accept given a set of rendering
options.
* @param context Rendering options in place this provider should consider.
* @return Array of mime types this provider will accept, given the provided
rendering options.
*/
public String[] getAccept(RenderingOptions context) {
// Return subset of getSupportedMimeTypes() if accept depends in rendering
options.
// For example HTML can be disabled in the rendering options, and
HTMLConverter would remove
// html MIME types.
return ACCEPT;
}
/**
* Retrieves a browser content capable of rendering the mime content this
provider can handle.
* @param context Provider context object provided by rendering session.
65
BlackBerry Application Developer Guide
if (context == null) {
throw new RenderingException("No Context is passed into Provider");
}
try {
HttpConnection conn = context.getHttpConnection();
InputStream in = conn.openInputStream();
int numBytes = in.available();
byte[] data = new byte[numBytes];
in.read(data, 0, numBytes);
vfm.add(new LabelField(new String(data)));
} catch (IOException e) {
e.printStackTrace();
}
browserContentBaseImpl.setContent(vfm);
browserContentBaseImpl.setTitle(ACCEPT[0]);
// Set browser page context. This tells the browser how to display this
field.
browserContentBaseImpl.setBrowserPageContext(this);
return browserContentBaseImpl;
}
/**
* Retrieves all the mime content types supported by this provider.
* @return Mime types this converter supports.
*/
/**
* Retrieves value of specified property as a boolean value.
66
5: BlackBerry Browser
if (id == BrowserPageContext.DISPLAY_STYLE) {
// Disable the scroll bar.
return BrowserPageContext.STYLE_NO_VERTICAL_SCROLLBAR;
}
return 0;
}
/**
* Retrieves value of specified property as an object.
* @param id ID of property to query.
* @param defaultValue Expected default value of property.
* @return Current value of property.
*/
67
BlackBerry Application Developer Guide
Code example
The following example consists of two files, PackageManager.java, which registers the filter on startup,
and Protocol.java, which defines the filter behavior.
import net.rim.device.api.io.http.HttpFilterRegistry;
/**
* This class runs on startup of the device and registers the necessary http
filters.
*/
final class PackageManager
{
public static void libMain(String[] args) {
HttpFilterRegistry.registerFilter("www.blackberry.com",
"com.rim.samples.docs.httpfilterdemo.filter");
}
}
/**
* Protocol.java
* Copyright (C) 2004 Research In Motion Limited. All rights reserved.
*/
package com.rim.samples.docs.httpfilterdemo.filter;
import net.rim.device.api.io.FilterBaseInterface;
import java.io.*;
import javax.microedition.io.*;
/**
* This class implements a simple pass through mechanism that writes out the http
response headers to System.out.
*/
68
5: BlackBerry Browser
/**
* Defined by FilterBaseInterface.
* This method opens a filtered Http Connection.
*/
public Connection openFilter( String name, int mode, boolean timeouts ) throws
IOException {
_subConnection = (HttpConnection)Connector.open("http:" + name +
";usefilter=false", mode, timeouts);
if (_subConnection != null) {
return this;
}
// Returns the protocol name of the URL of this HttpConnection. e.g., http or
https.
public String getProtocol() {
return _subConnection.getProtocol();
}
// Returns the host information of the URL of this HttpConnection. e.g. host
name or IPv4 address.
public String getHost() {
return _subConnection.getHost();
}
/**
* Returns the ref portion of the URL of this HttpConnection.
* RFC2396 specifies the optional fragment identifier as the the text after the
crosshatch (#)
* character in the URL. This information may be used by the user agent as
additional
* reference information after the resource is successfully retrieved. The
format and
* interpretation of the fragment identifier is dependent on the media
type[RFC2046] of
* the retrieved information.
*/
public String getRef() {
return _subConnection.getRef();
}
69
BlackBerry Application Developer Guide
// Returns the network port number of the URL for this HttpConnection.
public int getPort() {
return _subConnection.getPort();
}
// Get the current request method. e.g. HEAD, GET, POST The default value is
GET.
public String getRequestMethod() {
return _subConnection.getRequestMethod();
}
// Set the method for the URL request, one of: GET, POST, HEAD, subject to
protocol restrictions. The default method is GET.
public void setRequestMethod(String method) throws IOException {
_subConnection.setRequestMethod(method);
}
// Returns the value of the named general request property for this connection.
public String getRequestProperty(String key) {
return _subConnection.getRequestProperty(key);
}
// Sets the general request property. If a property with the key already
exists, overwrite its value with the new value.
// Note: HTTP requires all request properties which can legally have multiple
instances with the
// same key to use a comma-separated list syntax which enables multiple
properties to be appended into a single property.
public void setRequestProperty(String key, String value) throws IOException {
System.out.println("Request property <key, value>: " + key + ", " + value );
_subConnection.setRequestProperty(key, value);
}
// Gets the HTTP response message, if any, returned along with the response
code from a server.
public String getResponseMessage() throws IOException {
return _subConnection.getResponseMessage();
}
70
5: BlackBerry Browser
// Returns the value of the last-modified header field. The result is the
number of milliseconds since January 1, 1970 GMT.
public long getLastModified() throws IOException {
return _subConnection.getLastModified();
}
// Returns the value of the named field parsed as date. The result is the
// number of milliseconds since January 1, 1970 GMT represented by the named
field.
public long getHeaderFieldDate(String name, long def) throws IOException {
return _subConnection.getHeaderFieldDate(name, def);
}
// Returns a string describing the encoding of the content which the resource
connected to is providing.
public String getEncoding() {
return _subConnection.getEncoding();
}
71
BlackBerry Application Developer Guide
72
6
Accessing the phone
application
• Phone API
• Listening for phone events
• Accessing and managing phone logs
Phone API
The phone API (net.rim.blackberry.api.phone) provides access to advanced features of the phone
application, such as enabling applications to inject DTMF tones into active calls.
Notes: To simply invoke the phone application and place a phone call, use the invocation API
(net.rim.blackberry.api.invoke). See “Starting BlackBerry applications” on page 79 for more information.
Check for a ControlledAccessException when your application first accesses the phone API. This runtime exception is
thrown if the system administrator restricts access to the phone API using application control. See the BlackBerry
Application Developer Guide Volume 1: Fundamentals for more information.
Invoke sendDTMFTone().
Method Description
callAdded(int) This method is invoked when a call is added to a conference call.
callAnswered(int) This method is invoked when a user answers a call (user driven).
callConferenceCallEstablished(int) This method is invoked when a conference call is established.
callConnected(int) This method is invoked when the network indicates a connected event
(network driven).
callDirectConnectConnected(int) This method is invoked when a direct-connect call is connected.
callDirectConnectDisconnected(int) This method is invoked when a direct-connect call is disconnected.
callDisconnected(int) This method is invoked when a call is disconnected.
callEndedByUser(int) This method is invoked when a user ends the call.
74
6: Accessing the phone application
Method Description
callFailed(int, int) This method is invoked when a call fails.
callHeld(int) This method is invoked when a call goes on hold.
callIncoming(int) This method is invoked when a new call arrives.
callInitiated(int) This method is invoked when an outgoing call is initiated by the BlackBerry
device.
callRemoved(int) This method is invoked when a call is removed from a conference call.
callResumed(int) This method is invoked when a held call resumes.
callWaiting(int) This method is invoked when a call is waiting.
conferenceCallDisconnected(int) This method is invoked when a conference call is ended (all members are
disconnected).
75
BlackBerry Application Developer Guide
Add the phone call to the phone log at the next available index
Invoke PhoneLogs.addCall().
_logs.addCall(conferenceCall);
Replace the call log at a given index with a new call log
Invoke PhoneLogs.swapCall().
_logs.swapCall(conferenceCall, 0, FOLDER_NORMAL_CALLS);
Note: The swapCall() method deletes the call at the given index.
Code example
The following code example calculates the time spent on the phone with a given participant.
Example: PhoneLogsDemo.java
/**
* PhoneLogsDemo.java
76
6: Accessing the phone application
import net.rim.blackberry.api.phone.phonelogs.*;
import java.lang.*;
import com.rim.samples.docs.baseapp.*;
import net.rim.device.api.system.Application;
77
BlackBerry Application Developer Guide
78
7
Communicating with
BlackBerry applications
• Starting BlackBerry applications
• Adding menu items to BlackBerry applications
• Code example
Tips: The BlackBerry Browser is invoked from the browser application API (net.rim.blackberry.api.browser). See
"Displaying web content in the browser" on page 47 for more information.
The phone API (net.rim.blackberry.api.phone) provides access to advanced features of the phone application. See
"Phone API" on page 73 for more information.
The following excerpt from the Restaurants.java code example creates a menu item that invokes the
phone application to call a restaurant.
private MenuItem phoneItem = new MenuItem(_resources.getString(MENUITEM_PHONE),
110, 12) {
public void run() {
synchronized(store) {
String phoneNumber = phonefield.getText();
if ( phoneNumber.length == 0 ) {
Dialog.alert(_resources.getString(ALERT_NO_PHONENUMBER));
} else {
PhoneArguments call = new PhoneArguments(PhoneArguments.ARG_CALL,
phoneNumber);
BlackBerry Application Developer Guide
Invoke.invokeApplication(Invoke.APP_TYPE_PHONE, call);
}
}
}
};
80
7: Communicating with BlackBerry applications
new ContactsDemo().enterEventDispatcher();
} else {
throw new IllegalStateException( "Context is null, expected a Contact
instance");
}
Dialog.alert("Viewing a message in the messaging view");
return null;
}
Define a unique ID
Use the hash of the package name as the unique long ID for the application menu item repository.
long ID = 0x7cab1e23b72a0033L; // Hash of com.rim.samples.docs.menuitem.
Code example
The following code example creates a menu item that appears when a user views a contact in the
address book. When a user clicks the menu item, the Contacts Demo application appears.
Example: DemoAppMenuItem.java
/**
* DemoApplicationMenuItem.java
* Copyright (C) 2003-2005 Research In Motion Limited.
*/
package com.rim.samples.docs.menuitem;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.component.Dialog.*;
import net.rim.blackberry.api.menuitem.*;
import javax.microedition.pim.*;
import net.rim.device.api.pdap.*;
81
BlackBerry Application Developer Guide
import com.rim.samples.docs.contactsdemo.*;
DemoAppMenuItem() {
ApplicationMenuItemRepository amir =
ApplicationMenuItemRepository.getInstance();
amir.addMenuItem(ApplicationMenuItemRepository.MENUITEM_ADDRESSCARD_VIEW,
new SampleMenuItem());
}
82
8
Storing persistent data
• Persistent storage options
• Managing persistent data
• Memory management and persistent objects
• Managing custom objects
Add a record
Invoke addRecord().
int id = store.addRecord(_data.getBytes(), 0, data.length());
Retrieve a record
Invoke getRecord(int, byte[], int). Provide a record ID, a byte array, and an offset as parameters
to this method.
byte[] data = new byte[store.getRecordSize(id)];
BlackBerry Application Developer Guide
Parameter Description
filter This parameter specifies a RecordFilter object to retrieve a subset of record store records (if null, all
record store records are returned).
comparator This parameter specifies a RecordComparator object to determine the order in which records are
returned (if null, records are returned in an undefined order).
keepUpdated This parameter determines whether the enumeration is kept current with changes to the record store.
Feature Description
Data storage MIDP records store data only as byte arrays. In contrast, the BlackBerry APIs enable you to save any Object
in the persistent store. As a result, searching for stored data is much faster than in the record model. To store
custom object types, the custom type’s class must implement the Persistable interface.
Data sharing In MIDP, each RecordStore belongs to a single MIDlet suite and a MIDlet can only access record stores
that are created by a MIDlet in the same suite. In the BlackBerry persistence model, however, data can be
shared between applications, at the discretion of the application that creates the data. Code signing ensures
that only authorized applications can access the data.
Note: The BlackBerry persistence API is available only with handheld software version 3.6 or later. For earlier versions of
handheld software, you must use MIDP record stores.
84
8: Storing persistent data
If the BlackBerry device deletes messages or calendar appointments because of low memory, the data is
not deleted from the desktop messaging program. See “Memory management and persistent objects” on
page 89 for more information.
Note: Users can view the current amount of available data storage by clicking Status in the handheld options.
Security
By default, applications on the BlackBerry device that have been digitally signed by RIM can access your
data in the persistent store. Contact RIM for information on controlling access to your data.
Administrative control
With the BlackBerry Enterprise Server version 3.5 Service Pack 2 or later for Microsoft® Exchange or
BlackBerry Enterprise Server version 2.2 or later for IBM® Lotus® Domino®, system administrators can
use IT policies to control the use of persistent storage by third-party applications.
Administrators can set the application control item ALLOW_USE_PERSISTENT_STORE to TRUE or FALSE.
By default, third-party applications are allowed to use persistent storage
(ALLOW_USE_PERSISTENT_STORE is TRUE).
Note: This policy item does not affect the use of the MIDP record store.
Data integrity
To maintain the integrity of data in persistent storage, partial updates are not made if an error occurs
during a commit.
Note: Data integrity can be compromised when the VM performs an emergency garbage collection due to low memory. In
this case, outstanding transactions are committed immediately. If the BlackBerry device fails during this operation, the
partially completed transactions are committed when the BlackBerry device starts. Outstanding transactions are not
committed during normal garbage collection.
85
BlackBerry Application Developer Guide
• java.lang.Short
• java.lang.String
• java.util.Vector
• java.util.Hashtable
Note: When you persist an object, any persistable objects that it refers to are also persisted.
Each PersistentObject is identified by a unique long key. This key is typically a hash of the fully
qualified package name.
Note: When an application is deleted from a BlackBerry device, all persistent objects created by that application are also
deleted.
Note: Include a comment in your code to indicate the string used to generate the long key.
86
8: Storing persistent data
If you have a number of objects that you want to commit to the store, you can commit them in a batch
transaction. To do this, invoke PersistentStore.getSynchObject() to retrieve the persistent store
monitor locking object. Then synchronize on that object, and invoke commit() as necessary. When you
release the synchronization on the monitor object, all your transactions are committed at once. If any
commit in the batch fails, then the entire batch transaction fails. If you invoke forceCommit() while
synchronized on the monitor object, this object is immediately committed and is not part of the batch
transaction.
Note: When an application first accesses a database, it should verify the order of any indexes and recreate the index if a
problem exists. Applications should also be able to identify and correct any problems with corrupt or missing data. See
"Data integrity" on page 85 for more information.
Delete a database
To delete a database, invoke PersistentStore.destroyPersistentObject(). Provide a unique key
for the PersistentObject as a parameter.
Notes: The PersistentObject is used as the root database for the application. By deleting it, you permanently remove
all persistent data that the application has stored.
If the .cod file that defines a PersistentStore is deleted, all persistent objects created by that .cod are also deleted.
To delete individual data, simply treat the data as normal objects and remove references to it. The data is
garbage collected automatically.
Code example
This code example demonstrates how to create an application for users to view their current user name
and password, type a new user name and password, and save changes.
Example: UserInfo.java
/**
* UserInfo.java
* Copyright (C) 2001-2005 Research In Motion Limited. All rights reserved.
*/
87
BlackBerry Application Developer Guide
package com.rim.samples.docs.userinfo;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.system.*;
import net.rim.device.api.util.*;
import java.util.*;
import net.rim.device.api.i18n.*;
import com.rim.samples.docs.baseapp.*;
import com.rim.samples.docs.resource.*;
static {
_resources = ResourceBundle.getBundle(
UserInfoResource.BUNDLE_ID, UserInfoResource.BUNDLE_NAME);
store = PersistentStore.getPersistentObject(0xa1a569278238dad2L);
}
Dialog.inform(_resources.getString(APP_SUCCESS));
usernamefield.setText(null);
passwordfield.setText(null);
}
};
88
8: Storing persistent data
}
}
}
};
public UserInfo() {
MainScreen mainScreen = new MainScreen();
mainScreen.setTitle(new LabelField(
_resources.getString(APPLICATION_TITLE)));
mainScreen.add(usernamefield);
mainScreen.add(passwordfield);
mainScreen.add(separator);
mainScreen.add(currentusernamefield);
mainScreen.add(currentpasswordfield);
mainScreen.addKeyListener(this);
mainScreen.addTrackwheelListener(this);
pushScreen(mainScreen);
}
public void makeMenu( Menu menu, int instance ) {
menu.add(saveItem);
menu.add(getItem);
super.makeMenu(menu, 0);
}
public void onExit() {
Dialog.alert(_resources.getString(APP_EXIT));
}
}
89
BlackBerry Application Developer Guide
Each persistent object on the BlackBerry device consumes a persistent object handle and an object
handle. For example, a record that consists of 10 String fields consumes 11 object handles—one for the
record and one for each of the strings. If the record is persistent, it consumes an additional 11 persistent
object handles.
Use the following techniques to limit the number of persistent object handles your application
consumes:
• Use primitives instead of objects when possible. A primitive, such as an int or a char, does not
consume an object handle.
• Group objects using the Object Grouping API (net.rim.device.api.system.ObjectGroup). A
grouped object consumes only one object handle.
Notes: Grouped objects are read-only. Invoke ObjectGroup.expandGroup() to ungroup the objects before making
changes. After you have finished making changes, invoke ObjectGroup.createGroup() to group the objects.
Objects should only be ungrouped when necessary. There is a performance penalty applied when objects are
ungrouped because the system creates a copy of the grouped object and allocates handles to each of the objects
inside the group.
See the Memory Best Practices for the BlackBerry Java Development Environment whitepaper for more
information.
90
8: Storing persistent data
The following code sample implements the Persistable interface as an inner class. It defines an
Object array with four elements to store a restaurant name, address, phone number, and specialty, and
methods to retrieve and set values for Object elements.
Note: A class must explicitly implement Persistable for objects of the class to be saved persistently. This requirement
applies even to subclasses. For example, if class A implements Persistable, and it has a subclass B, objects of subclass B
cannot be stored persistently unless class B also implements Persistable.
Saving an object
Define an object
The following code sample creates a RestaurantInfo object and uses its set methods to define its
components.
RestaurantInfo info = new RestaurantInfo();
info.setElement(RestaurantInfo.NAME, namefield.getText());
info.setElement(RestaurantInfo.ADDRESS,addressfield.getText());
info.setElement(RestaurantInfo.PHONE, phonefield.getText());
info.setElement(RestaurantInfo.SPECIALTY, specialtyfield.getText());
91
BlackBerry Application Developer Guide
_data.addElement(info);
Note: Synchronize on the persistent object when you make changes so that other threads cannot make changes to the
object at the same time.
Retrieve an object
To retrieve the most recently saved object, invoke _data.lastElement() .
public void run() {
synchronized(store) {
_data = (Vector)store.getContents();
if (!_data.isEmpty()) { RestaurantInfo info =
(RestaurantInfo)_data.lastElement();
namefield.setText(info.getElement(RestaurantInfo.NAME));
addressfield.setText(info.getElement(RestaurantInfo.ADDRESS));
phonefield.setText(info.getElement(RestaurantInfo.PHONE));
specialtyfield.setText(info.getElement(
RestaurantInfo.SPECIALTY));
}
}
}
Code example
This code example demonstrates how to create an application that enables users to store information
about a favorite restaurant.
This code example enables users to save information about multiple restaurants and view information
about the most recently saved restaurant.
Example: Restaurants.java
/**
* Restaurants.java
* Copyright (C) 2004-2005 Research In Motion Limited.
*/
package com.rim.samples.docs.restaurants;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.system.*;
import net.rim.device.api.util.*;
import java.util.*;
92
8: Storing persistent data
import net.rim.device.api.i18n.*;
import net.rim.blackberry.api.invoke.*;
import net.rim.blackberry.api.browser.*;
import com.rim.samples.docs.baseapp.*;
import com.rim.samples.docs.resource.*;
info.setElement(RestaurantInfo.NAME, namefield.getText());
info.setElement(RestaurantInfo.ADDRESS, addressfield.getText());
info.setElement(RestaurantInfo.PHONE, phonefield.getText());
info.setElement(RestaurantInfo.WEBSITE, phonefield.getText());
info.setElement(RestaurantInfo.SPECIALTY,
specialtyfield.getText());
_data.addElement(info);
synchronized(store) {
store.setContents(_data);
store.commit();
}
Dialog.inform(_resources.getString(APP_SUCCESS));
namefield.setText(null);
addressfield.setText(null);
phonefield.setText("");
websitefield.setText("");
specialtyfield.setText("");
}
};
93
BlackBerry Application Developer Guide
websitefield.setText(info.getElement(RestaurantInfo.WEBSITE));
specialtyfield.setText(info.getElement(RestaurantInfo.SPECIALTY));
}
}
}
};
94
8: Storing persistent data
app.enterEventDispatcher();
}
private static final class RestaurantInfo implements Persistable {
// Data.
private String[] _elements;
// Fields.
public static final int NAME = 0;
public static final int ADDRESS = 1;
public static final int PHONE = 2;
public static final int WEBSITE = 3;
public static final int SPECIALTY = 4;
public RestaurantInfo() {
_elements = new String[4];
for ( int i = 0; i < _elements.length; ++i) {
_elements[i] = new String("");
}
}
public Restaurants() {
MainScreen mainScreen = new MainScreen();
mainScreen.setTitle(new LabelField(
_resources.getString(APPLICATION_TITLE)));
namefield = new AutoTextEditField(
_resources.getString(FIELD_NAME), "");
addressfield = new AutoTextEditField(
_resources.getString(FIELD_ADDRESS), "");
phonefield = new EditField(
_resources.getString(FIELD_PHONE), "", Integer.MAX_VALUE,
BasicEditField.FILTER_PHONE);
websitefield = new EditField(
_resources.getString(FIELD_WEBSITE), "", Integer.MAX_VALUE,
BasicEditField.FILTER_URL);
specialtyfield = new EditField(
_resources.getString(FIELD_SPECIALTY), "",
Integer.MAX_VALUE, BasicEditField.FILTER_DEFAULT);
mainScreen.add(namefield);
mainScreen.add(addressfield);
mainScreen.add(phonefield);
mainScreen.add(websitefield);
mainScreen.add(specialtyfield);
mainScreen.addKeyListener(this);
mainScreen.addTrackwheelListener(this);
95
BlackBerry Application Developer Guide
pushScreen(mainScreen);
}
96
9
Backing up and restoring
persistent data
• Synchronization API
• Adding support for backing up persistent data
Synchronization API
The synchronization API, in the net.rim.device.api.synchronization package, enables your
application to integrate with the BlackBerry Desktop Software to perform two tasks:
• back up a database to a desktop file and restore it later
• synchronize data with a desktop application
Note: The BlackBerry Desktop Software requires that backup data use the following format:
Length<2> Type<1> Data<n>
To ensure that the data is in the appropriate format, use one of the write methods in the
net.rim.device.api.synchronization.ConverterUtilities class.
Data backup
The BlackBerry Desktop Software provides a Backup and Restore tool that enables users to save
BlackBerry device data to a file on their desktop, and use this file to restore data to the BlackBerry
device.
When an application implements the synchronization API, the desktop software backs up and restores
the application database along with the other BlackBerry device databases. You can also use the
synchronization API to create data archives or to populate application databases when the BlackBerry
device first connects to the computer.
Data synchronization
The desktop software provides an Intellisync tool to synchronize the BlackBerry device with the
applications on the user computer.
Where backup and restore performs a bulk load of data between the BlackBerry device and a desktop
backup file, synchronization compares the data that exists in a desktop application with the data on the
BlackBerry device to merge the data.
To synchronize data with a desktop application, write a plug-in for the desktop software using the
BlackBerry Desktop API. The BlackBerry JDE also includes a sample synchronization application with a
desktop plug-in.
Note: There are no restrictions on the format that you use to store data for backup. The only requirement is that the
application read and write data in the format used by the desktop plug-in application.
BlackBerry Application Developer Guide
Synchronization API
Implement the following interfaces provided by the synchronization API:
Interface Description
SyncConverter converts data between the SyncObject format required on the BlackBerry device and a serialized format
required on the desktop
SyncCollection represents the collection of synchronization objects for an application
SyncObject represents an object that can be backed up and restored to the user computer
The SerialSyncManager class provides access to the synchronization manager, in particular to register
new objects for synchronization.
Note: To back up and restore a very small amount of data, such as application configuration options, you can extend the
SyncItem class and implement its abstract methods. The SyncItem class implements the SyncCollection,
SyncConverter, and SyncObject interfaces for you.
Define a unique ID
Define a _uid variable. Your implementation of getUID() returns a unique ID to use for synchronization
operations.
Define a constructor
Your constructor implementation accepts a unique ID as a parameter and sets the _uid variable to this
value.
Note: Each synchronization object that is stored on the BlackBerry device must have an associated ID that is unique to its
application. The UIDGenerator sets this value ID by default.
98
9: Backing up and restoring persistent data
if (args[i].startsWith("init")) {
startup = true;
}
}
if (startup) {
//enable application for synchronization on startup
SerialSyncManager.getInstance().enableSynchronization(new
RestaurantsSync());
} else {
RestaurantsSync app = new RestaurantsSync();
app.enterEventDispatcher();
}
}
Code example
This code example demonstrates how to enable desktop software to back up and restore persistent data
for your application. This example modifies the Restaurants.java code example to implement the
synchronization API.
Example: RestaurantsSync.java
/**
* RestaurantsSync.java
* Copyright (C) 2001-2005 Research In Motion Limited. All rights reserved.
*/
99
BlackBerry Application Developer Guide
package com.rim.samples.docs.restaurantssync;
import java.io.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.system.*;
import net.rim.device.api.util.*;
import java.util.*;
import net.rim.device.api.i18n.*;
import net.rim.device.api.synchronization.*;
import com.rim.samples.docs.resource.*;
import com.rim.samples.docs.baseapp.*;
synchronized(store) {
store.setContents(_data);
store.commit();
}
Dialog.inform(_resources.getString(APP_SUCCESS));
namefield.setText(null);
addressfield.setText(null);
phonefield.setText("");
specialtyfield.setText("");
}
};
100
9: Backing up and restoring persistent data
static {
_resources = ResourceBundle.getBundle(RestaurantsSyncResource.BUNDLE_ID,
RestaurantsSyncResource.BUNDLE_NAME);
store = PersistentStore.getPersistentObject(KEY);
synchronized (store) {
_data = (Vector)store.getContents();
if ( _data == null ) {
_data = new Vector();
store.setContents( _data );
store.commit();
}
}
}
public static void main(String[] args) {
boolean startup = false;
for (int i=0; i<args.length; ++i) {
if (args[i].startsWith("init")) {
startup = true;
}
}
if (startup) {
// Enable application for synchronization on startup.
SyncManager.getInstance().enableSynchronization(
RestaurantsSync.getInstance());
} else {
RestaurantsSync app = new RestaurantsSync();
app.enterEventDispatcher();
}
}
101
BlackBerry Application Developer Guide
public RestaurantInfo() {
_elements = new String[4];
for ( int i = 0; i < _elements.length; ++i) {
_elements[i] = "";
}
}
public RestaurantInfo(int uid) {
_elements = new String[4];
for (int i = 0; i < _elements.length; ++i) {
_elements[i] = "";
}
_uid = uid;
}
// SyncConverter methods.
public SyncObject convert(DataBuffer data, int version, int UID) {
try {
RestaurantInfo info = new RestaurantInfo(UID);
while(data.available() > 0) {
int length = data.readShort();
byte[] bytes = new byte[length];
switch (data.readByte()) {
case FIELDTAG_NAME:
data.readFully(bytes);
//trim null-terminator
info.setElement(RestaurantInfo.NAME,
new String(bytes).trim());
break;
case FIELDTAG_PHONE:
data.readFully(bytes);
info.setElement(RestaurantInfo.PHONE,
new String(bytes).trim());
break;
case FIELDTAG_ADDRESS:
102
9: Backing up and restoring persistent data
data.readFully(bytes);
info.setElement(RestaurantInfo.ADDRESS,
new String(bytes).trim());
break;
case FIELDTAG_SPECIALTY:
data.readFully(bytes);
info.setElement(RestaurantInfo.SPECIALTY,
new String(bytes).trim());
break;
default:
data.readFully(bytes);
break;
}
}
return info;
} catch (EOFException e) {
System.err.println(e.toString());
}
return null;
}
103
BlackBerry Application Developer Guide
store = PersistentStore.getPersistentObject(KEY);
_data = (Vector)store.getContents();
}
public void endTransaction() {
store.setContents(_data);
store.commit();
}
public SyncConverter getSyncConverter() {
return this;
}
public String getSyncName() {
return "Restaurant Synchronization Demo";
}
public String getSyncName(Locale locale) {
return getSyncName();
}
public int getSyncObjectCount() {
store = PersistentStore.getPersistentObject(KEY);
_data = (Vector)store.getContents();
return _data.size();
}
public SyncObject[] getSyncObjects() {
SyncObject[] array = new SyncObject[_data.size()];
for (int i = _data.size() - 1; i >= 0; --i) {
array[i] = (SyncObject)_data.elementAt(i);
}
return array;
}
public SyncObject getSyncObject(int uid) {
for (int i = _data.size() -1; i>= 0; --i) {
SyncObject so = (SyncObject)_data.elementAt(i);
if (so.getUID() == uid ) return so;
}
return null;
}
public int getSyncVersion() {
return 1;
}
public boolean addSyncObject(SyncObject object) {
_data.addElement(object);
return true;
}
public boolean removeAllSyncObjects() {
_data.removeAllElements();
return true;
}
public void clearSyncObjectDirty(SyncObject object) {
// Not applicable.
}
public boolean isSyncObjectDirty(SyncObject object) {
return false;
}
public boolean removeSyncObject(SyncObject object) {
return false;
}
104
9: Backing up and restoring persistent data
105
BlackBerry Application Developer Guide
106
10
Accessing setup and
configuration information
• Service book API
To view the service book on BlackBerry devices, users click Service Book under the handheld options.
The ServiceBook class maintains a collection of ServiceRecord objects. Each ServiceRecord object
is identified by a unique ID (UID) and connection ID (CID).
CID Description
CMIME The compressed multipurpose mail extensions (CMIME) CID defines messaging connections.
ALP The address lookup protocol (ALP) CID defines connections for wireless Global Address List searches.
IPPP The IP Proxy Protocol (IPPP) CID defines HTTP connections using the Mobile Data Service.
BrowserConfig The browser configuration (BrowserConfig) CID defines BlackBerry and WAP browser connections.
Sync The data synchronization (Sync) CID defines connections for wireless data synchronization.
WAP The wireless application protocol (WAP) CID defines WAP gateway connections.
CICAL The compressed iCalendar (CICAL) CID defines connections for wireless calendar synchronization.
GUID Description
GUID_SB_ADDED The GUID for the global event that is sent when a service book is added.
GUID_SB_BR_END The GUID for the global event that is sent when service book backup-restore ends.
GUID_SB_BR_START The GUID for the global event that is sent when service book backup-restore starts.
GUID_SB_CHANGED The GUID for the global event that is sent when a service book is changed.
GUID_SB_OTA_SWITCH The GUID for the global event that is sent when all service records are inserted due to a move
BlackBerry Enterprise Server command over the air.
GUID_SB_OTA_UPDATE The GUID for the global event that is sent when all service records are updated for a UID over the
air.
GUID_SB_REMOVED The GUID for the global event that is sent when a service book is deleted.
108
11
Managing notifications
• Notification API
• Adding an event
• Responding to events
• Customizing system notifications
Notification API
The notification API (net.rim.device.api.notification) enables you to add custom events for your
application and define the type of notification that users receive when custom events occur.
Note: Check for a ControlledAccessException when your application first accesses the notification API. This runtime
exception is thrown if the system administrator restricts access to the notification API using application control. See the
BlackBerry Application Developer Guide Volume 1: Fundamentals for more information.
With immediate events, the BlackBerry device provides notification to the user as soon as the event
occurs, using a system notification, such as a flashing LED, vibration, or tune. An application cannot
request a specific type of notification. In the handheld profiles list, users control how they receive
notification of immediate events by choosing an active profile and setting profile options. To add custom
system notifications for immediate events, implement the Consequence interface.
With deferred events, the BlackBerry device schedules events in a queue according to their priority.
When the event occurs, applications that are affected by the event can provide a custom notification to
the user, typically by displaying a user interface element such as a dialog box. To listen for deferred
events, implement the NotificationsEngineListener interface. The BlackBerry device does not
provide system-wide notification for deferred events.
Adding events
Register a new event source
Create a unique long ID
Define a long ID for each notification event.
public static final long ID_1 = 0xdc5bf2f81374095L;
Note: Use the IDE to convert a String to a long to create a long identifier for your application:
1. In the IDE text pane, type a string.
2. Select the string, right-click, and then click Convert “string” to Long.
BlackBerry Application Developer Guide
Note: The priority level applies to deferred events only. Immediate events occur as soon as they are triggered.
When you trigger a deferred event, you specify an expiry time. The user might not receive notification of a lower-priority
event, if the event expires before higher-priority events complete.
110
11: Managing notifications
Parameter Description
sourceID identifier of the application that starts the event (as specified when you invoked registerSource())
eventID application-specific event identifier
eventReference application-specific event cookie
context optional context object
In most cases, do not use immediate events because the BlackBerry device event notification does not
adequately indicate to the user what has happened. For example, if the BlackBerry device vibrates, it
would be difficult for the user to know whether an event has occurred in your application or whether a
new message has arrived. If you do use immediate events, consider implementing a custom notification,
such as a particular tune, to distinguish your application events from other BlackBerry device events. See
“Customizing system notifications” on page 116 for more information.
The negotiateDeferredEvent(long, long, Object, long, int, Object) method accepts the
following parameters:
Parameter Description
sourceID identifier of the application that starts the event (as specified when you invoked registerSource())
eventID application-specific event identifier
eventReference application-specific event cookie
timeout event expiry time, in milliseconds, relative to time when the method is invoked (the timeout is ignored
unless the trigger is OUT_OF_HOLSTER_TRIGGER)
trigger either NotificationsConstants.OUT_OF_HOLSTER_TRIGGER, which specifies that the event occurs when
the BlackBerry device is disconnected from the computer; or
NotificationsConstants.MANUAL_TRIGGER, which specifies that the application itself triggers this
event
context optional object that can store additional, arbitrary parameters to control the state or behavior of an event
notification
111
BlackBerry Application Developer Guide
Cancel an event
Cancel an immediate event
Invoke cancelImmediateEvent(long, long, Object, Object), and then specify the source and
event IDs.
NotificationsManager.cancelImmediateEvent(ID_1, 0, this, null);
Code example
Example: NotificationDemo.java
/**
* NotificationsDemo.java
* Copyright (C) 2001-2005 Research In Motion Limited. All rights reserved.
*/
package com.rim.samples.docs.notifications;
import net.rim.device.api.notification.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.system.*;
import net.rim.device.api.util.*;
import com.rim.samples.docs.baseapp.*;
112
11: Managing notifications
public NotificationsDemo() {
MainScreen mainScreen = new MainScreen();
mainScreen.setTitle("Notification Demo App");
mainScreen.addKeyListener(this);
mainScreen.addTrackwheelListener(this);
NotificationsManager.registerNotificationsEngineListener(ID_1,
new NotificationsEngineListenerImpl(this));
pushScreen(mainScreen);
}
113
BlackBerry Application Developer Guide
menu.add(triggerItem);
menu.add(deferItem);
menu.add(cancelItem);
super.makeMenu(menu, instance);
}
114
11: Managing notifications
Responding to events
Your implementation of NotificationsEngineListener defines custom notification. Register your
implementation by invoking negotiateDeferredEvent(). You do not need to implement the listener if
you trigger immediate events, for which the BlackBerry device provides standard system notification.
Define notification
Your implementation of proceedWithDeferredEvent() defines how to notify the user when the event
occurs, such as by displaying a dialog box. This method is invoked when the listener proceeds with the
event (no other higher priority events are in the queue).
115
BlackBerry Application Developer Guide
Define a unique ID
Define a unique ID for this consequence.
116
11: Managing notifications
Define constants
Declare DATA and TYPE constants for the application. These constants are used when identifying the
type of incoming data from the SyncConverter when convert() is invoked. They are arbitrary
identifiers for data that is appropriate to this application.
private static final int TYPE = 'n' << 24 | 'o' << 16 | 't' << 8 | 'd';
private static final byte[] DATA = new byte[] {'m', 'y', '-', 'c',
'o', 'n', 'f', 'i', 'g', '-', 'o', 'b', 'j', 'e', 'c', 't'};
private static final Configuration CONFIG = new Configuration(DATA);
Create a tune
Create a tune to be played as part of the consequence for event notifications.
private static final short BFlat = 466; // 466.16
private static final short TEMPO = 125;
private static final short d16 = 1 * TEMPO;
private static final short dpause = 10; // 10 millisecond pause
private static final short[] TUNE = new short[] {BFlat, d16, pause, BFlat};
private static final int VOLUME = 80; // Percentage volume.
Define a notification
Your implementation of startNotification() defines the notification for this consequence. In the
following code sample, the LED flashes and a tune is played.
public void startNotification(long consequenceID, long sourceID, long eventID,
Object configuration, Object context) {
LED.setConfiguration(500, 250, LED.BRIGHTNESS_50);
LED.setState(LED.STATE_BLINKING);
Alert.startAudio(TUNE, VOLUME);
Alert.startBuzzer(TUNE, VOLUME);
}
Stop a notification
Your implementation of stopNotification() stops notification for this consequence.
public void stopNotification(long consequenceID, long sourceID,
long eventID, Object configuration, Object context) {
LED.setState(LED.STATE_OFF);
Alert.stopAudio();
Alert.stopBuzzer();
}
117
BlackBerry Application Developer Guide
118
11: Managing notifications
Register a consequence
If you create a custom Consequence implementation, register it with the NotificationsManager by
invoking registerNotificationsObjects(long, Consequence).
NotificationsManager.registerConsequence(ConsequenceImpl.ID, new
ConsequenceImpl());
To register the consequence when the BlackBerry device starts, perform this registration in a library
project. See “Registering the event source when the BlackBerry device starts” on page 110 for more
information.
Code example
Example: ConsequenceDemo.java
/**
* ConsequenceDemo.java
* Copyright (C) 2001-2005 Research In Motion Limited. All rights reserved.
*/
package com.rim.samples.docs.notifications;
import net.rim.device.api.synchronization.*;
import net.rim.device.api.notification.*;
import net.rim.device.api.system.*;
import net.rim.device.api.util.*;
import java.io.*;
119
BlackBerry Application Developer Guide
private static final short BFlat = 466; // The actual value is 466.16.
private static final short TEMPO = 125;
private static final short d16 = 1 * TEMPO;
private static final short pause = 10; // 10 millisecond pause.
private static final short[] TUNE = new short[] {BFlat, d16, pause, BFlat};
private static final int VOLUME = 80; // Percentage volume.
Alert.startAudio(TUNE, VOLUME);
Alert.startBuzzer(TUNE, VOLUME);
}
120
11: Managing notifications
121
BlackBerry Application Developer Guide
122
12
Managing applications
• Application manager
• Managing code modules
• Managing code modules
Application manager
The virtual machine (VM) on BlackBerry devices has an application manager that functions as the central
dispatcher of operating system events for other Java applications.
The net.rim.device.api.system.ApplicationManager class enables applications to interact with
the application manager to perform the following actions:
• interact with processes, such as retrieving the IDs for foreground applications
• post global events to the system
• lock or unlock the BlackBerry device, or determine whether the BlackBerry device is locked
• run an application immediately or at a specific time
To use any of the ApplicationManager methods, you must first retrieve a reference to the current
application manager by invoking getApplicationManager().
ApplicationManager manager = ApplicationManager.getApplicationManager();
ApplicationDescriptor descriptor =
ApplicationDescriptor.currentApplicationDescriptor();
String appname = descriptor.getName();
BlackBerry Application Developer Guide
To post a global event to a particular application, invoke postGlobalEvent(int, long, int, int,
Object, Object).
The processID parameter specifies the ID of the process to which to post the event. To retrieve a
process ID, invoke getProcessId(ApplicationDescriptor). The guid parameter specifies a global
unique identifier (GUID) for the event. The data and object parameters specify additional information
for the event.
To post a global event to all applications, use one of the following forms of postGlobalEvent():
124
12: Managing applications
ApplicationDescriptor template =
ApplicationDescriptor.currentApplicationDescriptor();
String[] args = { "admin", "secure" };
ApplicationDescriptor newdescriptor = new ApplicationDescriptor(template, args);
The runApplication() method creates a new process and invokes the exported main() method in the
specified descriptor, using its arguments. The new process moves to the foreground if possible.
125
BlackBerry Application Developer Guide
A code module is a .cod file, the compiled archive of a single project in the IDE. To view a list of third-
party applications installed on BlackBerry devices, in the handheld options, click Applications. Click the
Properties menu item to view information about each application.
Invoke methods of the CodeModuleManager class to retrieve specific information. Provide the module
handle as a parameter to these methods.
String name = CodeModuleManager.getModuleName( handle );
String vendor = CodeModuleManager.getModuleVendor( handle );
String description = CodeModuleManager.getModuleDescription( handle );
int version = CodeModuleManager.getModuleVersion( handle );
int size = CodeModuleManager.getModuleCodeSize( handle );
int timestamp = CodeModuleManager.getModuleTimestamp( handle );
Create a module
Invoke createNewModule(). Provide the size of the module in bytes as a parameter.
126
12: Managing applications
This method returns the module handle or 0 if the module cannot be created.
To add data to the module when you create it, invoke the following form of createNewModule().
Provide as parameters the length in bytes of the entire module, a byte array to add to the module, and
the length parameter specifies the number of bytes from the byte array to add to the start of the
module.
static int createNewModule(int, byte[], int);
Note: A module must have the correct format for a .cod file. You can write data into a code module in increments, as long
as you know the offset at which to add data.
The saveNewModule(int) method returns one of the result codes that are defined in the
CodeModuleManager class, such as CMM_OK if the module is saved successfully.
127
BlackBerry Application Developer Guide
128
13
Sharing runtime objects
between applications
• Sharing runtime objects
130
Glossary
A JAR
ALX Java Archive
Application Loader XML JRE
APN Java Runtime Environment
Access Point Name
K
C KVM
CA Kilobyte virtual machine
Certificate Authority L
cHTML LDAP
Compact Hypertext Markup Language Lightweight Directory Access Protocol
CLDC
LTPA
Connected Limited Device Configuration
Lightweight Third-Party Authentication
G
M
GUI MB
graphical user interface megabyte
GUID MHz
globally unique identifier megahertz
I MIDlet
i18n MIDP application
internationalization MIDP
IP Mobile Information Device Profile
Internet Protocol MIME
IPPP Multipurpose Internet Mail Extensions
IP Proxy Protocol O
ISDN OCSP
Integrated Services Digital Network Online Certificate Status Protocol
J P
JAD
PAP
Java Application Descriptor
Password Authentication Protocol
BlackBerry Application Developer Guide
PIM T
personal information management TCP
PIN Transmission Control Protocol
personal identification number TIFF
PNG Tag Image File Format
Portable Network Graphics TLS
Transport Layer Security
R
RRC U
Radio Resource Control UDP
RTC User Datagram Protocol
real-time clock URI
Uniform Resource Identifier
S
URL
SDK
Uniform Resource Locator
software development kit
UTC
SIM
Universal Time Coordinate
Subscriber Identity Module
SMS W
Short Message Service WAP
SRAM Wireless Application Protocol
static random access memory WBMP
SRP wireless bitmap
Service Relay Protocol WML
SSL Wireless Markup Language
Secure Sockets Layer WMLC
Wireless Markup Language Compiled
WTLS
Wireless Transport Layer Security
132
Index
A overriding constructor, 80
addCall(), PhoneLogs class, 76 toString(), 80
addElement(), Vector class, 91 ApplicationMenuItemRepository class
addGlobalEventListener(), Application class, 124 about, 80
addMenuItem(), ApplicationMenuItemRepository class, addMenuItem(), 81
81 getInstance(), 81
addPhoneListener(), Phone class, 74 applications
addRecordStore(), RecordStore class, 83 auto-run on startup, 99
address book different arguments, 124
about, 25 event source, 110
converting to serial formats, 28 inter-process communication, 124
creating contacts, 25 managing, 123
importing contacts, 28 retrieving information, 123
invoking, 79 scheduling, 125
opening ContactList, 25 system modules, 99
removing contacts, 29 See also code modules
retrieving contact information, 27 appointments, See calendar
saving contacts, 27 attachments
administrative control about, 19
about, 85 registering a handler, 20
APIs retrieving contents, 21
invocation, 79 retrieving information, 21
messaging, 11 sending, 21
notifications, 109 auto-run, applications, 99
persistence, 83
PIM, 23 B
service book, 107
backup
synchronization, 97 about, 85
Application class, addGlobalEventListener(), 124 implementing, 97
application descriptor, different arguments, 124 supporting, 98
application manager, virtual machine, 123
Backup and Restore
ApplicationDescriptor class
about, 97
about, 124
currentApplicationDescriptor(), 124 BlackBerry applications
adding menu items, 80
ApplicationManager class
about, 123 starting, 79
Boolean data type, persistence, 85
getVisibleApplications(), 123
browser
isSystemLocked(), 124
about, 47
lockSystem(), 124
API overview, 47
postGlobalEvent(), 124
Browser class
runApplication(), 125 getDefaultSession(), 47
scheduleApplication(), 125 getSession(), 47
unlockSystem(), 124 browser content
ApplicationMenuItem class filtered, 67
about, 80 retrieving, 51
extending, 80 browser fields, about, 48
BlackBerry Application Developer Guide
134
Index
D UserInfo.java, 87
data
persistent storage, 86 F
data integrity, 85 file extensions
data types .cod files, 9
persistence, 85 .csl files, 9
databases, creating persistent, 86 .cso files, 9
deferred events filtering URLs, 67
cancelling, 112 finishLoading(), BrowserField class, 52
cancelling all, 112 FolderEvent class, about, 13
code example, 112 folders
triggering, 111 listing, 18
deferredEventWasSuperseded(), managing, 18
NotificationsEngineListener interface, 115 saving messages, 19
deleteCall(), PhoneLogs class, 76 searching, 19
deleteModule(), CodeModuleManager class, 127
deleting, persistent databases, 87 G
display characteristics, specifying, 63
displayBrowserField(), RenderingApplication class, 48 get(), RuntimeStore class, 130
displayPage(), BrowserSession class, 48 getAccept(), BrowserContentProvider class, 63
DTMF tones, queueing, 74 getActiveCall(), Phone class, 73
getApplicationDescriptor(), CodeModuleManager class,
E 126
getBrowserContent(), BrowserContentProvider
email, See messages interface, 63
enableSynchronization(), SerialSyncManager class, 98 getBrowserField(), RenderingApplication interface, 51
entry points, alternate, 99 getContents(), PersistentObject class, 87
enumerateRecords(), RecordStore class, 84 getDefaultSession(), Browser class, 47
eventOcurred(), GlobalEvent interface, 124 getDisplayPhoneNumber(), PhoneCall class, 73
events getElapsedTime(), PhoneCall class, 73
adding, 109 getInstance()
calendar, 37 ApplicationMenuItem class, 81
cancelling, 112 OptionsProvider interface, 43
global, 124 SerialSyncManager class, 98
messaging, 13 getModuleHandle(), CodeModuleManager class, 126
phone, 74 getModuleHandles(), CodeModuleManager class, 126
service book, 108 getModuleManagerForObject(), CodeModuleManager
triggering deferred, 111 class, 126
examples getParticipantAt(), ConferencePhoneCallLog class, 76
BasicMail.java, 17 getParticipants(), PhoneCallLog class, 76
BrowserFieldSampleApp.java, 52 getRecord(), RecordStore class, 83
BrowserPlugin.java, 64 getRenderingOptions(), RenderingApplication
ConsequenceDemo.java, 119 interface, 49
getRuntimeStore(), RuntimeStore class, 129
ContactsDemo.java, 29
getSession(), Browser class, 47
DemoAppMenuItem.java, 81 getStatus(), PhoneCall class, 73
DemoOptionsProvider.java, 44 getSupportedMIMETypes(), BrowserContentProvider
EventDemo.java, 40 class, 63
NotificationsDemo.java, 112 getVisibleApplications(), ApplicationManager class, 123
PhoneLogsDemo.java, 76 global events, posting, 124
Protocol.java, 68 GlobalEventListener interface, about, 124
Restaurants.java, 92
RestaurantsSync.java, 99 H
TaskDemo.java, 35 handheld options
135
BlackBerry Application Developer Guide
about, 43 about, 11
adding, 43 attachments, 19
code example, 44 creating, 11
registering, 43 managing events, 13
storing data persistently, 44 managing folders, 18
using public methods, 44 multipart, 12
handhelds reading, 14
locking, 124 receiving, 13
unlocking, 124 replying, 16
Hashtable data type, persistence, 85 storing, 12
HTTP filters, about, 67 MIME types
HTTPFilterRegistry class, registerFilter(), 68 listing accepted, 63
supporting additional, 62
I
immediate events N
cancelling, 112 negotiateDeferredEvent(), Notifications manager class,
code example, 112 111
triggering, 111 newConfiguration(), Consequence class, 118
initialization projects, creating, 99 notifications
Integer data type, persistence, 85 about, 109
integrity, data, 85 adding events, 109
Intellisync, about, 97 canceling events, 112
intercepting, URLs, 67 custom, 115
inter-process communication, global events, 124
custom system, 116
Invoke class, invokeApplication(), 79
invokeApplication(), Invoke class, 79 custom system notifications, 116
isLibrary(), CodeModuleManager class, 126 deferred events, 111
isOutgoing(), PhoneCall class, 73 defining custom, 115
isSystemLocked(), ApplicationManager class, 124 holstering, 115
immediate events, 111
L listener, 115
lastElement(), Vector class, 92 registering listener, 116
library projects, creating, 110 superseded, 115
locking, handhelds, 124 triggering deferred events, 111
lockSystem(), ApplicationManager class, 124 tunes, 117
Long data type, persistence, 85 NotificationsEngineListener interface, 115
about, 115
M deferredEventWasSuperseded(), 115
managing, applications, 123 notificationsEngineStateChanged(), 115
memo pad, invoking, 79 registerNotificationsEngineListener(), 116
MemoArguments class, about, 79 notificationsEngineStateChanged(),
menu items NotificationsEngineListener interface, 115
adding, 80 NotificationsManager class
adding to BlackBerry applications, 80 cancelDeferredEvent(), 112
registering, 81 cancelImmediateEvent(), 112
specifying behavior, 80 code example, 112
specifying position, 80 negotiateDeferredEvent(), 111
specifying text, 80 registerNotificationsObject(), 119
MessageArguments class, about, 79 registerSource(), 110
MessageEvent class, about, 13 triggerImmediateEvent(), 111
messages numberOfCalls(), PhoneLogs class, 75
136
Index
O getStatus(), 73
Object data type, persistence, 85 isOutgoing(), 73
openRecordStore(), RecordStore class, 83 PhoneCallLog class
options constructor, 76
See handheld options getParticipants(), 76
OptionsProvider interface PhoneCallLogID class
about, 43 about, 76
getInstance(), 43 PhoneListener interface, about, 74
registerOptionsProvider(), 43 PhoneLogs class
addCall(), 76
P callAt(), 75
deleteCall(), 76
persistence
getInstance(), 75
BlackBerry APIs, 84
swapCall(), 76
code examples, 92
PIM
creating databases, 86
fields, 23
custom objects, 90
items, 23
limited memory, 84
lists, 23
MIDP API, 83
See also address book, calendar, tasks
retrieving data, 87
postGlobalEvent(), ApplicationManager class, 124
retrieving objects, 92 proceedWithDeferredEvent(),
saving data, 86 NotificationsEngineListener interface, 115
saving objects, 91 put(), RuntimeStore class, 129
persistent data, managing, 85
persistent databases, deleting, 87 R
PersistentObject class
about, 86 receiving, messages, 13
record stores
commit(), 86
about, 83
getContents(), 87
adding, 83
setContents(), 86
opening, 83
PersistentStore class, about, 84
phone application, invoking, 79 retrieving, 83
phone calls retrieving all, 84
about, 73 RecordStore class
adding DTMF tones, 74 addRecordStore(), 83
duration, 73 enumerateRecords(), 84
retrieving, 73 getRecord(), 83
status, 73 openRecordStore(), 83
Phone class registerFilter(), HTTPFilterRegistry class, 68
addPhoneListener(), 74 registering
getActiveCall(), 73 attachment handler, 20
notification event source, 109
removePhoneListener(), 74
options items, 43
phone listener, registering, 74
phone logs startup, 110
about, 75 synchronization collections, 98
missed calls folder, 75 registerNotificationsEngineListener(),
normal calls folder, 75 NotificationsEngineListener class, 116
retrieving, 75 registerNotificationsObjects(), NotificationsManager
class, 119
PhoneArguments class, about, 79 registerOptionsProvider(), OptionsProvider interface, 43
PhoneCall class
registerSource(), NotificationsManager class, 110
about, 73
removePhoneListener(), Phone class, 74
getDisplayPhoneNumber(), 73 rendering
getElapsedTime(), 73
137
BlackBerry Application Developer Guide
138
Index
139
BlackBerry Application Developer Guide
140
©2005 Research In Motion Limited
Published in Canada.