Saturday, February 28, 2009

What Is - The file size limit for wireless downloads

0 comments

The maximum size of a COD file, which can be downloaded wirelessly, varies based on a number of factors. These factors include the BlackBerry Device Software version, the BlackBerry Enterprise Server™ version, the BlackBerry JDE version, and the type of browser used to install the application (for example, BlackBerry Browser connected to a BlackBerry MDS or BlackBerry Mobile Data Service, or Internet Browser using the BlackBerry Internet Service™).

Using BlackBerry JDE 3.6 and 3.7

When using BlackBerry JDE 3.6 and 3.7, the maximum COD file size that can be downloaded wirelessly, using a browser, is 128 KB. This number includes a maximum limit of 64 KB for application data (code) and 64 KB for resource data (images or files).

Note: Each section must also be under the 64 KB limit; therefore, you cannot complete a wireless installation of a COD file that contains 20 KB of application data and 100 KB of resource data. There are no exceptions to this limit for applications built with BlackBerry JDE 3.6 and 3.7.

To work around this, build your application so that it consists of several smaller COD files. Place some of your object code or resources into a Library project. When built, this will produce multiple COD files that must be smaller than the limit.

To build a Library project, complete the following steps:

  1. In the BlackBerry JDE, create a second project.
  2. Right-click the project and select Properties.
  3. On the Application tab, select Library as the Project Type.
  4. Move some of your classes or resources from the main application into this library project to reduce the size of your main application.

The library project becomes part of the runtime classes on the BlackBerry device.

  1. In the main application, import this package to be able to use the classes.
  2. Compile both applications.

You now see two distinct COD files (one for your application, and one for the library).

  1. Change your JAD file to allow the user to download the two COD files, as shown below:

....
RIM-COD-URL: myLibrary.cod
RIM-COD-URL-1: myApp.cod
RIM-COD-SHA1: 65 39 3f 54 d8 ef 6e 43 72 37 db 5e 7a 27 89 84 f8 e0 30 9b
RIM-COD-SHA1-1: 88 02 c3 1c 00 19 e8 bb e5 1a 3f f8 28 8e b5 57 5b dd 48 14
RIM-COD-Size: 33128
RIM-COD-Size-1: 46996
...

Note: Always place the libraries at the top of the JAD list so they are downloaded first.

Using BlackBerry JDE 4.0 and Later

BlackBerry JDE 4.0 introduced the concept of sibling COD files. If an application is too large to fit within the 128 KB limit (64 KB of application data and 64 KB of resource data), sibling COD files are created and packaged into a single main COD file. Sibling COD files are a series of COD files that are suffixed with -#, where # is incremented for each sibling COD file. These sibling COD files are then packaged into a main COD file that has a basic ZIP structure. The sibling COD files adhere to the 128 KB (64 KB + 64 KB) size limit. To determine if your application contains sibling COD files, you can attempt to open the COD file with WinZip®. If the COD file contains sibling COD files, you can open it and View or Extract the sibling COD files in the same way as a ZIP file.

Using the BlackBerry Browser to Install

When using a BlackBerry Device Software or a BlackBerry Enterprise Server earlier than 4.0, the maximum COD file size that can be downloaded wirelessly, using a browser, is 128 KB (64 KB of application data and 64 KB of resource data).

BlackBerry MDS or BlackBerry Mobile Data Service 4.0 and later paired with a device running BlackBerry Device Software 3.8 or later is able to download a COD file greater than 128 KB that contains sibling COD files.

Note: If the COD file does not contain sibling COD files, the limit is still 128 KB. BlackBerry MDS or BlackBerry Mobile Data Service can extract the sibling COD files from the main COD file, and send them individually to the BlackBerry Browser.

Using the Internet Browser to Install

When using the Internet Browser through the BlackBerry Internet Service, the maximum COD file size that can be installed wirelessly is 128 KB (64 KB of application data and 64 KB of resource data). The Internet Browser does not have the ability to install a COD file that contains sibling COD files, regardless of their size.

To support this browser, the sibling COD files should be extracted from the main COD file and placed individually on a web server. To extract them, use WinZip. Make sure you extract the sibling COD files to a different directory other than the location of the main COD file as the first sibling COD file will have the same name as the main COD file.

After the COD files have been extracted, reference each of them in the JAD file. Use the example above to update the JAD file.

Note: BlackBerry JDE 4.1 and later will automatically create a JAD file that references all sibling COD files, thus, no editing of the JAD file is needed.

Optimized installation

It is recommended that sibling COD files be extracted from the main COD file and placed individually on a web server instead of packaged in the main COD file. This allows both the BlackBerry Browser and Internet Browser to install the application. It is also more efficient for the web server. The BlackBerry Enterprise Server does not store COD files, so every time a sibling COD file that is packaged in a main COD file is requested by a device, the BlackBerry MDS or BlackBerry Mobile Data Service must download the entire main COD file to extract the single requested sibling COD file. As a result, the BlackBerry MDS or BlackBerry Mobile Data Service will download a main COD file multiple times (one time for every sibling COD file it contains).

Friday, February 27, 2009

News : BlackBerry Bold 9000 OS 4.6.0.241 Found Online

0 comments

This is for the BlackBerry Bold 9000 only. Please only upgrade if you are comfortable with the process.

You can get the OS file here.

You can check out discussions on this OS at BlackBerryForums.com

News : Sprint officially releases 4.5.0.135 for 8830 model

0 comments

Sprint has officially released OS 4.5.0.135 for the BlackBerry 8830. This OS may be installed to any 8830 model by following the instructions in the link.

* File name: 8830uAMEA_PBr4.5.0_rel201_PL3.4.0.28_A4.5.0.135_Sp rint.ex

Instructions to download and discussion of the OS here.

Wednesday, February 25, 2009

News : BlackBerry Bold 9000 OS 4.6.0.237 found online

0 comments

This is for the BlackBerry Bold 9000 only. Please only upgrade if you are comfortable with the process.

You can get the OS file here.

You can check out discussions on this OS at BlackBerryForums.com

News : Plazmic CDK 4.7 beta 4.1.0.16 found online

0 comments

Plazmic 4.7 CDK has been discovered online. Supposedly this version gets less crashes during an export. This is build Version 4.1.0.16, from Feb 13th 2009.
You can get it from here

News : BlackBerry 9530 Storm 4.7.0.109 OS Found Online

0 comments

This is 4.7.0.109 for the BlackBerry Storm 9530 only. Please only upgrade if you are comfortable with the process.

You can get the OS file here.

You can check out discussions on this OS at BlackBerryForums.com

Tuesday, February 24, 2009

Code : Log Phone Calls

1 comments

BlackBerry JDE 4.0 introduces a phone logs API (net.rim.blackberry.api.phone). The phone logs API allows developers to:

  • manipulate phone data and phone features to further enhance business processes.
  • extract information regarding all phone call activities on a BlackBerry device and organize it accordingly.

Note: The phone logs API is very useful for companies that use time billing.

The functions that are used to navigate through a phone log are as follows:

  • callAt() returns a CallLog object which allows a user to extract data and/or set data.
  • getInstance() returns the current values stored in a Phone Log.

PhoneCallLog (extends CallLog) and PhoneCallLogID classes return data structures from a call record. PhoneCallLogID deals with data regarding a phone number. This class contains getNumber(), getName() and setName().

PhoneCallLog produces the rest of the data such as getDate(), getNotes(), getStatus() and setNotes(). Thus, it is crucial to use all the classes in this API to build an appropriate phone log application.

The following sample illustrates a custom application, which logs all answered calls and their details.

Phone Log Java Source Code

import net.rim.blackberry.api.phone.phonelogs.*;
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 java.util.*;
import net.rim.device.api.i18n.*;
/**
* This sample illustrates logging phone calls or keeping a record of them
* using the phonelogs api. This sample logs all calls except missed calls.
*/
class Phone_Log extends UiApplication{
/**
*an instance of MainScreen, to add display content
*and set display options on the device
*/
MainScreen _screen = new MainScreen();
/**
* instance of Phonethread(used in the background to retrieve data)
*/
Phonethread _phone;
Date _date;
/**
* instance of PhoneLogs API, used for filtering through the log
*/
PhoneLogs _logs;
/**
* will define the total talk time
*/
int _total = 0;
/**
* will hold the string value of the date variable
*/
SimpleDateFormat _formatedDate=
new SimpleDateFormat(DateFormat.DATE_DEFAULT);
/**
* main function that starts the event thread
*/
public static void main(String arg[])
{
Phone_Log application = new Phone_Log();
//create a new instance of the application
//and start the application on the event thread
application.enterEventDispatcher();
}
/**
* Class constructor
* Sets the application title, starts a separate phone thread,
* and pushes the screen on the device
*/
public Phone_Log(){
_screen.setTitle("Phone Log");
_screen.add(new RichTextField("Activities on your Phone"));
_screen.add(new SeparatorField());
pushScreen(_screen);
_phone = new Phonethread();
_phone.start();
}
/**
* Private class that extends thread.
* It will run in the background, and not affect the
* performance of the device.
*/
private class Phonethread extends Thread{
/**
* Class constructor, invokes super
*/
public Phonethread(){
super();
}
/**
* Run method that will receive a copy of the phone log
* and work through it to collect data.
* It will then display the log in chronological order.
* The items that will be displayed are: the date of a call;
* the number of the call; the duration of the call in seconds
* and if there were any notes.
* Uses the screen variable to display items on the device.
* The log will only be taken from the normal folder
* which contains all calls except the missed.
* For a log of missed calls please use missed folder.
*/
public void run(){
_date=new Date();
_logs=PhoneLogs.getInstance();
for(int i=0;
i<(_logs.numberOfCalls(_logs.FOLDER_NORMAL_CALLS));
i++){
//extracting the date from the log
_date=_logs.callAt(i, _logs.FOLDER_NORMAL_CALLS).getDate();
//referencing a call log to a PhoneCallLog so the caller ID,
//the number and notes can be extracted
PhoneCallLog callLog=(PhoneCallLog)_logs.callAt
(i, _logs.FOLDER_NORMAL_CALLS);
String number=callLog.getParticipant().getNumber();
String data=_formatedDate.formatLocal(_date.getTime());
//seeing if a call is received or dialed
//and outputting the correct information
if(callLog.getType() == callLog.TYPE_RECEIVED_CALL){
_screen.add(new RichTextField(
"You received a call from: "+number));
_screen.add(new RichTextField(
"it was received on: "+data));
}
if(callLog.getType() == callLog.TYPE_PLACED_CALL){
_screen.add(new RichTextField(
"The number you dialed was: "+number));
_screen.add(new RichTextField(
"it was made on: "+data));
}
_total+=callLog.getDuration();
//adding the duration of the call
//and any notes that were made
_screen.add(new RichTextField(
"It lasted for: "+ callLog.getDuration() + " secs"));
_screen.add(new RichTextField(""));
_screen.add(new RichTextField(
"These are your notes: " +callLog.getNotes()));
_screen.add(new SeparatorField());
}
//end for
_screen.add(new RichTextField(
"Total time spent on the phone: "+_total+" secs"));
}
}
}

Code : Backup and restore data using SyncItem

0 comments

SyncItem (net.rim.device.api.synchronization.SyncItem) provides an easy method of backing up and restoring small amounts of data such as application configuration information. Allowing data to be backed up and restored ensures that the same information will be reloaded onto a user’s BlackBerry device when they upgrade the OS on their device. It can also allow configuration information to be transferred from one device to another.

It is not recommended to use this method to backup and restore a large amount of data. For more information on backing up and restoring a large amount of data see Chapter 6, Backing up and restoring persistent data in the BlackBerry Developer's Guide, Volume 2, Advanced Topics.

Procedure

In order for the SyncItem to register when the device starts, a separate project will have to be created that acts as an alternate entry point to your main application. This passes an argument to your application the first time that the device starts so that your application registers only once.

  1. In the BlackBerry JDE, create a project.
  2. Right-click the project and click Properties. The Properties window appears.
  3. Click the Application tab.
  4. From the Project type drop-down list, select Alternate CLDC Application Entry Point.
  5. From the Alternate entry point for drop-down list, select the main project that implements synchronization.
  6. In the Arguments passed to field, type init.
  7. Select the Auto-run on startup option.
  8. Select the System module option.
  9. Click OK.

/**
* SyncItemSample.java
*
* Allows a small list of names and ages that are stored in persistant
* store to be backed up and restored by the Desktop Manager.
*
*/
package com.samples.syncItemSample;
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 net.rim.device.api.synchronization.*;
import java.util.*;
public class SyncItemSample extends UiApplication
{
private String[] names
= {"Homer", "Marge", "Bart", "Lisa", "Maggie"};
private int ages[] = {36, 34, 10, 8, 3};
private static PersistentObject store;
private static UserList userList;
//This store is static so that all instances of this class
//use the same Persistent Store
static
{
//Unique identifier for the persistent store object.
//Long value = com.samples.syncItemSample.SyncItemSample
store = PersistentStore.getPersistentObject(0x677bb65afc4a6814L);
}
public static void main(String[] args)
{
boolean startup = false;
//Check parameters to see if the application was entered
//through the alternate application entry point.
for (int i=0; i<args.length; ++i)
{
if (args[i].startsWith("init"))
{
startup = true;
}
}
if (startup)
{
//Entered through the alternate application entry point.
//Enable application for synchronization on startup.
SerialSyncManager.getInstance().enableSynchronization
(new UserListSync());
} else
{
//Entered by selecting the application icon on the ribbon.
SyncItemSample app = new SyncItemSample();
app.enterEventDispatcher();
}
}
public SyncItemSample()
{
UserListScreen userListScreen;
//Check to see if the store exists on the BlackBerry.
synchronized (store)
{
if (store.getContents() == null)
{
//Store does not exist, create it with default values
userList = new UserList(names, ages);
store.setContents(userList);
store.commit();
}
else
{
//Store exists, retrieve data from store.
userList = (UserList)store.getContents();
names = userList.getNames();
ages = userList.getAges();
}
}
//Create and push the UserListScreen.
userListScreen = new UserListScreen(names, ages);
pushScreen(userListScreen);
}
/**
* UserListSync.java
*
* Handles the backup and restore of persistent data.
*
*/
package com.samples.syncItemSample;
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 net.rim.device.api.synchronization.*;
import java.util.*;
import net.rim.device.api.i18n.Locale;
public final class UserListSync extends SyncItem
{
private String[] permNames = new String[5];
private int permAges[] = new int[5];
private static UserList permUserList;
private static final int FIELDTAG_NAME = 1;
private static final int FIELDTAG_AGE = 2;
private static PersistentObject store;
//This store is static so that all instances of this class
//use the same Persistent Store
static
{
//Unique identifier for the persistent store object.
//Long value = com.samples.syncItemSample.SyncItemSample
store = PersistentStore.getPersistentObject(0x677bb65afc4a6814L);
}
public UserListSync()
{
}
//The name that will be used to reference this SyncItem.
//It is shown in the Desktop Manager under backup/restore advanced.
public String getSyncName()
{
return "Sync Item Sample";
}
//Localization is not supported in this example.
public String getSyncName(Locale locale)
{
return null;
}
//The version of this SyncItem.
public int getSyncVersion()
{
return 1;
}
//Formats the data to the specification required
//by the Desktop Manager.
public boolean getSyncData(DataBuffer db, int version)
{
int count;
boolean retVal = true;
String tempString;
synchronized (store)
{
//Check to see if the persistent store object
//exists on the BlackBerry.
if (store.getContents() != null)
{
//Store exists, retrieve data from store.
permUserList = (UserList)store.getContents();
permNames = permUserList.getNames();
permAges = permUserList.getAges();
}
}
//Format data that will be interpreted by the Desktop Manager.
//Format is Length Type Data
//Length is a short, type is a byte and data is the length
// specified by Length.
//Data must be structured in this format to be understood
// by the Desktop Manager.
try
{
for (count = 0; count < 5; ++count)
{
//Write the name.
db.writeShort(permNames[count].length() + 1);
db.writeByte(FIELDTAG_NAME);
db.write(permNames[count].getBytes());
db.writeByte(0);
//Write the age.
tempString = permAges[count] + "";
db.writeShort(tempString.length() + 1);
db.writeByte(FIELDTAG_AGE);
db.write(tempString.getBytes());
db.writeByte(0);
}
} catch (Exception e)
{
retVal = false;
}
//Return true if all data was processed.
return retVal;
}
//Interprets and stores the data sent from the Desktop Manager.
public boolean setSyncData(DataBuffer db, int version)
{
int length, nameCount = 0, ageCount = 0;
boolean retVal = true;
try
{
//Read until the end of the Databuffer.
while (db.available() > 0)
{
//Read the length of the data.
length = db.readShort();
//Set the byte array to the length of the data.
byte[] bytes = new byte[length];
//Determine the type of data to be read (name or age).
switch (db.readByte())
{
case FIELDTAG_NAME:
//Read the name from the Databuffer.
//Convert and store it in the String array.
db.readFully(bytes);
permNames[nameCount] = new String(bytes).trim();
++nameCount;
break;
case FIELDTAG_AGE:
//Read the age from the Databuffer.
//Convert and store it in the int array.
db.readFully(bytes);
permAges[ageCount]
= (int)(Integer.parseInt(new String(bytes).trim()));
++ageCount;
break;
}
}
} catch (Exception e)
{
retVal = false;
}
try
{
//Store the new data in the persistent store object.
permUserList = new UserList(permNames, permAges);
store.setContents(permUserList);
store.commit();
} catch (Exception e)
{
retVal = false;
}
//Return true if the data was successfully restored,
//or false if it was not.
return retVal;
}
}
/**
* UserList.java
*
* UserList is persistable and holds the list of names and ages.
*
*/
package com.samples.syncItemSample;
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 net.rim.device.api.synchronization.*;
import java.util.*;
import net.rim.device.api.i18n.Locale;
public final class UserList implements Persistable
{
//The persistable objects.
private String[] permNames = new String[5];
private int permAges[] = new int[5];
//Initialize the class with empty values.
public UserList()
{
}
//Initialize the class with the specified values.
public UserList(String[] names, int ages[])
{
permNames = names;
permAges = ages;
}
//Get/set methods.
public String[] getNames()
{
return permNames;
}
public void setNames(String[] names)
{
permNames = names;
}
public int[] getAges()
{
return permAges;
}
public void setAges(int[] ages)
{
permAges = ages;
}
}
/**
* UserListScreen.java
*
* This screen displays the list of names and ages.
*
*/
package com.samples.syncItemSample;
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 java.util.*;
public final class UserListScreen extends MainScreen
{
public UserListScreen(String[] names, int[] ages)
{
super();
//Create a horizontal field manager to hold the two vertical field
//managers to display the names and ages in two columns.
HorizontalFieldManager backGround = new HorizontalFieldManager();
VerticalFieldManager leftColumn = new VerticalFieldManager();
VerticalFieldManager rightColumn = new VerticalFieldManager();
//Array of fields to display the names and ages.
LabelField displayNames[] = new LabelField[5];
LabelField displayAges[] = new LabelField[5];
int count;
//Set the screen title.
LabelField title = new LabelField("User List",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
setTitle(title);
//Add the column titles and a blank field to create a space.
LabelField leftTitle = new LabelField("User ");
leftColumn.add(leftTitle);
LabelField rightTitle = new LabelField("Age");
rightColumn.add(rightTitle);
leftColumn.add(new LabelField(""));
rightColumn.add(new LabelField(""));
//Populate and add the name and age fields.
for (count = 0; count < 5; count++)
{
displayNames[count] = new LabelField(names[count]);
displayAges[count] = new LabelField(String.valueOf(ages[count]));
leftColumn.add(displayNames[count]);
rightColumn.add(displayAges[count]);
}
//Add the two vertical columns to the horizontal field manager.
backGround.add(leftColumn);
backGround.add(rightColumn);
//Add the horizontal field manager to the screen.
add(backGround);
}
public boolean onClose()
{
System.exit(0);
return true;
}
//Close the screen whenever a key is pressed.
public boolean keyChar(char key, int status, int time)
{
this.close();
return true;
}
//Close the screen if the trackwheel is clicked.
public boolean trackwheelClick(int status, int time)
{
this.close();
return true;
}
}

Saturday, February 21, 2009

Code : To Invoke applications

0 comments

One of the new APIs found in BlackBerry JDE 4.0 is the net.rim.blackberry.api.invoke, which allows developers to gain controlled access to the Phone, Messages, Calendar, MemoPad, Tasks, and Address Book.

To specify the applications to invoke, use the default arguments provided in this API. The Application Argument API provides instances to access the applications mentioned above.

The following sample illustrates simple functions to make a phone call, given a number in a custom application, and to invoke the messaging application.

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.blackberry.api.invoke.*;
class appinvo extends UiApplication {
public static void main(String arg[]){
//create a new instance of the application
//and start the application on the event thread
appinvo application = new appinvo();
application.enterEventDispatcher();
}
public appinvo () {
pushScreen(new InnovactionScreen());//creating a screen
}
}
class InnovactionScreen extends MainScreen {
//variables for the user interface
LabelField _title;
EditField _phonefield;
String _value;
public InnovactionScreen() {
super();//invoke MainScreen constructor
//define title of the app
_title = new LabelField("Sample App", LabelField.ELLIPSIS
| LabelField.USE_ALL_WIDTH);
setTitle(_title);
//add user interface field
_phonefield = new EditField("Please Enter a #","");
this.add(_phonefield);//add the field to the MainScreen
//create e-mail menuItem
MenuItem menu1 = new MenuItem("e-mail",1,1) {
public void run () {
//using invoke api to "jump" from this app
//to email app
Invoke.invokeApplication
( Invoke.APP_TYPE_ADDRESSBOOK,
new AddressBookArguments
(AddressBookArguments.ARG_COMPOSE));
}
};
//add email menu to the MainScreen
this.addMenuItem(menu1);
//create phone menuItem
MenuItem menu2 = new MenuItem("Phone Them",2,2) {
public void run () {
//getting the value user input in the
//phonefield defined above
_value = _phonefield.getText();
//using invoke api to "jump" from this app
//to phone app
//it calls the number the user types
//in the phonefield
Invoke.invokeApplication(Invoke.APP_TYPE_PHONE,
new PhoneArguments
(PhoneArguments.ARG_CALL, _value));
}
};
this.addMenuItem(menu2);//add phone menu to menuItem
}
}

How to - Capture power change events

0 comments

Your application can be notified when power change events take place on the BlackBerry device. This could be used to halt certain features when the battery power is low, and resume them when it is back to normal levels. Implementing the SystemListener interface (net.rim.device.api.system.SystemListener) can perform these operations. Events such as the BlackBerry powering on, powering off, and changes in the battery state can be captured. The following sample application shows how to implement the SystemListener interface:

import java.util.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
public class PowerChangeEvent
extends Application implements SystemListener
{
public static PowerChangeEvent theApp;
public static void main(String args[])
{
theApp = new PowerChangeEvent();
theApp.enterEventDispatcher();
}
public PowerChangeEvent()
{
//Register this instance with the system listener.
Application.getApplication().addSystemListener(this);
System.out.println("PowerChangeEvent: PowerChangeEvent has started!");
}
//Invoked when the user is putting the device into a power off state.
public void powerOff()
{
System.out.println("PowerChangeEvent: The BlackBerry is powering off.");
}
//Invoked when the device has left the power off state.
public void powerUp()
{
System.out.println("PowerChangeEvent: The BlackBerry is powering up.");
}
//Invoked when the internal battery voltage falls below a critical level.
public void batteryLow()
{
System.out.println("PowerChangeEvent: The battery is getting low!");
}
//Invoked when the internal battery voltage has returned to normal.
public void batteryGood()
{
System.out.println("PowerChangeEvent: The battery level is now good!");
}
//Invoked when the internal battery state has changed.
//Not used in this sample.
public void batteryStatusChange(int status)
{
}
}

How To - Programmatically send a PIN message

2 comments

The code sample below explains how to programmatically send a personal identification number (PIN) message from one BlackBerry device to another device that has PIN 20000000. This code sample uses the net.rim.blackberry.api.mail package.

Store store = Session.getDefaultInstance().getStore();
//retrieve the sent folder
Folder[] folders = store.list(Folder.SENT);
Folder sentfolder = folders[0];
//create a new message and store it in the sent folder
Message msg = new Message(sentfolder);
PINAddress recipients[] = new PINAddress[1];
try{
//create a pin address with destination address of 20000000
recipients[0]= new PINAddress("20000000", "Robert");
}
catch (AddressException ae)
{
System.err.println(ae);
}
try{
//add the recipient list to the message
msg.addRecipients(Message.RecipientType.TO, recipients);
//set a subject for the message
msg.setSubject("Test pin message");
//sets the body of the message
msg.setContent("This is a test pin message from my
BlackBerry Wireless Handheld");
//send the message
Transport.send(msg);
}
catch (MessagingException me)
{
System.err.println(me);
}

Works on :

  • BlackBerry wireless devices based on Java
  • BlackBerry Device Software 4.0 and higher

Note: This is not supported in BlackBerry Device Software 3.8 and earlier, and cannot be reproduced on the device simulators.

How To - Display a PopupScreen from a SendListener

0 comments

The SendListener interface can be triggered by a foreground application that displays a GUI (such as the Messages application or a third-party application) or by a background application or process that does not contain a GUI (such as a third-party application or when appointment invitations are sent from the Calendar application). Each case requires a different approach to display a PopupScreen to the BlackBerry smartphone user, resulting in the SendListener detecting what type of application is triggering it and displaying the PopupScreen appropriately. Failing to do so can result in the PopupScreen not being shown to the BlackBerry smartphone user.

The following code example demonstrates how to detect the type of application triggering the SendListener and how to display a Dialog for each case.

public class MySendListener extends Application implements SendListener
{
public boolean sendMessage(Message msg)
{
Dialog myDialog = new Dialog(Dialog.D_OK,
"This is a Message from a SendListener",
Dialog.OK,Bitmap.getPredefinedBitmap(Bitmap.EXCLAMATION),
Dialog.GLOBAL_STATUS)
{
//Override inHolster to prevent the Dialog from being dismissed
//when a user holsters their BlackBerry. This can
//cause a deadlock situation as the Messages
//application tries to save a draft of the message
//while the SendListener is waiting for the user to
//dismiss the Dialog.
public void inHolster()
{
}
};
//Obtain the application triggering the SendListener.
Application currentApp = Application.getApplication();
//Detect if the application is a UiApplication (has a GUI).
if( currentApp instanceof UiApplication )
{
//The sendMessage method is being triggered from
//within a UiApplication.
//Display the dialog using is show method.
myDialog.show();
}
else
{
//The sendMessage method is being triggered from
// within an application (background application).
Ui.getUiEngine().pushGlobalScreen( myDialog, 1,
UiEngine.GLOBAL_MODAL );
}
return true;
}
}

How To - Add an ApplicationMenuItem to BlackBerry Maps

0 comments

The BlackBerry Maps application allows the BlackBerry device user to view maps and receive directions on a BlackBerry device. BlackBerry Maps can also provide a visual route and navigational instructions to a specified destination.

BlackBerry Maps works with BlackBerry Device Software 4.1 and later. BlackBerry Maps is included with BlackBerry Device Software 4.2 and later. For use with BlackBerry Device Software 4.1, BlackBerry Maps can be downloaded from www.blackberry.com/maps.

With third-party applications, an ApplicationMenuItem can be added to the menu of BlackBerry Maps and pass a MapView object into the application.

This article focuses on adding an ApplicationMenuItem to BlackBerry Maps. Please see How To - Add a custom menu item to an existing BlackBerry application for information on the way to add a custom menu item to other BlackBerry device applications.

An ApplicationDescriptor is required for adding an ApplicationMenuItem to BlackBerry Maps. The code for registering a menu item with the BlackBerry Maps application is as follows:

ApplicationMenuItemRepository amir =
ApplicationMenuItemRepository.getInstance();
ApplicationDescriptor ad_startup =
ApplicationDescriptor.currentApplicationDescriptor();
ApplicationDescriptor ad_gui =
new ApplicationDescriptor(ad_startup, "gui", null);
amir.addMenuItem(ApplicationMenuItemRepository.MENUITEM_MAPS,new MapMenuItem(),ad_gui);

The menu item MapMenuItem() is then registered with the BlackBerry Maps application (MENUITEM_MAPS) to invoke the current application with ad_gui as the ApplicationDescriptor. The MapMenuItem()method contains the actual code for specifying the menu item as shown below. MapMenuItem implements the abstract class ApplicationMenuItem and implements the run and toString methods. The toString method specifies the text to display on the menu item.

private static class MapMenuItem extends ApplicationMenuItem {
MapMenuItem() {
super(20);
}
public String toString() {
return "My Menu Item";
}
public Object run(Object context) {
mv = (MapView)context;
if (mv != null) {
System.out.println("Latitude = " + mv.getLatitude());
System.out.println("Longitude = " + mv.getLongitude());
System.out.println("Zoom = " + mv.getZoom());
}
else {
throw new IllegalStateException("Context is null, expected a MapView instance");
}
return null;
}
}

How to - How to remove applications from Blackberry simulator

0 comments

If you want to remove only selective application from Device Simulator then

from "C:\Program Files\Research In Motion\BlackBerry JDE X.X.X\simulator"delete following files

AppName.cod, AppName.cso, AppName.debug(and AppName-X.debug ,if exists), AppName.jar, and four DMP files of related BB device like

In case of Curve 8800--> 8800-as.dmp, 8800-nv.dmp, 8800-sdcard.dmp, 8800-fs.dmp.

And if you want to remove all third party applications from Device Simulator then run "clean.bat", will reset

your simulator to its initial state with no third party applications. "clean.bat" can be found in simulator directory.

Enjoy!

Code : Support streaming audio to the media application

1 comments

The media application on the BlackBerry device is designed to read from the local file system. To stream data from a remote resource to the media application, you must buffer the resource and control the media application's data reads. The best method to accomplish this is to create a custom DataSource and SourceStream implementation that will provide data to the media application.

Buffering data

The following example opens a connection to a remote audio file and buffers an initial amount of data before starting playback. Subsequent read requests from the media application are controlled by limiting the amount of data returned and blocking the read request when the amount of available data is low. When enough data is available, the read request is resumed.

The example also includes support for saving a downloaded audio file to a microSD card and playing back a downloaded file from the microSD card.

Buffering in the SourceStream is done using SharedInputStreams. One thread reads from a connection to the resource, tracking how much data has been read into the stream. The following code shows this thread:

private class ConnectionThread extends Thread {
public void run() {
try {
byte[] data = new byte[READ_CHUNK];
int len = 0;
updateLoadStatus(_resources.getString(

BufferedPlaybackResource.LOAD_BUFFERING));
while (-1 != (len = readAhead.read(data))) {
totalRead += len;
updateLoadStatus(totalRead + _resources.getString(BufferedPlaybackResource.LOAD_UNITS));
if (!bufferingComplete && totalRead > getStartBuffer()) {
bufferingComplete = true;
System.out.println("Initial Buffering Complete");
updateLoadStatus(_resources.getString(

BufferedPlaybackResource.LOAD_BUFFER_COMPLETE));
}
if (_stop) {
return;
}
}
System.out.println("Downloading Complete");
updateLoadStatus(_resources.getString(

BufferedPlaybackResource.LOAD_DONE) + totalRead + _resources.getString(BufferedPlaybackResource.LOAD_UNITS));
System.out.println("Total Read: " + totalRead);
if (totalRead != s.getLength()) {
System.err.println("* Unable to Download entire file *");
}
downloadComplete = true;
// Write download to the local file
readAhead.setCurrentPosition(0);
while (-1 != (len = readAhead.read(data))) {
saveStream.write(data);
}
} catch (Exception e) {
System.err.println(e.toString());
}
}
}

Notice that the application waits until the whole file has been downloaded before saving it to local storage. Writing to storage while downloading the file may slow down the download process. After reading the data, the thread makes the data available to the SharedInputStream.

Reading data

Read requests from the media application are handled by the SourceStream provided by the DataSource. Internally, this SourceStream implementation uses a SharedInputStream based on the stream being read by the thread in the prior example.

The available() method of the SharedInputStream determines how far ahead the stream has been read. When the media application has caught up to the download, the application can block further read requests from the media application until the download is far enough ahead. The goal is to support playback as soon as possible and not stop unless necessary. If stopping is required, try to minimize it by stopping long enough to buffer additional data for playback.

There are four parameters used in the DataSource to define the buffering scheme:

  1. Initial buffer - the amount downloaded before playback starts
  2. Pause mark - defines when reading should be blocked because too little data is available
  3. Restart mark - defines when reading should be allowed again
  4. Limit - defines the amount of data returned at a time

The following example allows these settings to be manually adjusted, while in practice they could be set to correspond to the audio being streamed, and/or automatically adjusted to match network conditions.

The following example shows the read method of the StreamingSource implementation:

public int read(byte[] b, int off, int len) throws IOException {
System.out.println("Read Request for: " + len + " bytes");
// limit bytes read to our readLimit.
int readLength = len;
if (readLength > getReadLimit()) {
readLength = getReadLimit();
}
int available;
boolean restart_pause = false;
for (;;) {
available = _baseSharedStream.available();
if (downloadComplete) {
// Ignore all restrictions if downloading is complete
System.out.println("Complete, Reading: " + len + " - Available: " + available);
return _baseSharedStream.read(b, off, len);
} else if (bufferingComplete) {
if (restart_pause && available > getRestartBytes()) {
// start up again
System.out.println("Restarting - Available: " + available);
updatePlayStatus(_resources.getString(

BufferedPlaybackResource.PLAY_RESTART) + available + _resources.getString(BufferedPlaybackResource.LOAD_UNITS));
restart_pause = false;
return _baseSharedStream.read(b, off, readLength);
} else if (!restart_pause && (available > getPauseBytes() || available > readLength)) {
// we have what is needed
if (available < getPauseBytes()) {
// read this time, but set the pause
restart_pause = true;
updatePlayStatus(_resources.getString(

BufferedPlaybackResource.PLAY_PAUSING) + available + _resources.getString(BufferedPlaybackResource.LOAD_UNITS));
}
System.out.println("Reading: " + readLength + " - Available: " + available);
return _baseSharedStream.read(b, off, readLength);
} else if (!restart_pause) {
// Set pause until loaded enough to restart
restart_pause = true;
updatePlayStatus(_resources.getString(

BufferedPlaybackResource.PLAY_PAUSING) + available + _resources.getString(BufferedPlaybackResource.LOAD_UNITS));
}
} else {
try {
Thread.sleep(100);
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
}

The DataSource determines where the data is loaded from during the connect() method. It first opens a connection to the remote resource to get the filename and length and then opens a connection to the local file system. If a file of the same name doesn't exist, or is smaller than the remote file, it is replaced by downloading the file again. Otherwise, the local resource is passed as the resource stream to be read. The details are as follows:

public void connect() throws IOException {
System.out.println("Loading: " + getLocator());
s = (ContentConnection) Connector.open(getLocator(), Connector.READ);
System.out.println("Size: " + s.getLength());
// Open save file location
int filenameStart = getLocator().lastIndexOf('/');
int paramStart = getLocator().indexOf(';');
if (paramStart < 0) {
paramStart = getLocator().length();
}
String filename = getLocator().substring(filenameStart, paramStart);
System.out.println("Filename: " + filename);
saveFile = (FileConnection) Connector.open("file:///SDCard/blackberry/music" + filename, Connector.READ_WRITE);
if (!saveFile.exists()) {
saveFile.create();
}
saveFile.setReadable(true);
SharedInputStream fileStream = SharedInputStream.getSharedInputStream(

saveFile.openInputStream());
fileStream.setCurrentPosition(0);
if (saveFile.fileSize() < s.getLength()) {
// didn't get it all before, download again
saveFile.setWritable(true);
saveStream = saveFile.openOutputStream();
readAhead = SharedInputStream.getSharedInputStream(s.openInputStream());
} else {
downloadComplete = true;
readAhead = fileStream;
s.close();
}
if (forcedContentType != null) {
feedToPlayer = new LimitedRateSourceStream(readAhead, forcedContentType);
} else {
feedToPlayer = new LimitedRateSourceStream(readAhead, s.getType());
}
}

Works on :

  • BlackBerry Device Software 4.2
  • BlackBerry Java Development Environment (JDE) 4.2

Code : How PushRegistry works

0 comments

The PushRegistry maintains a list of inbound connections. An application can register the inbound connections with an entry in the JAD file or by dynamically calling the registerConnection method. If a notification arrives for a registered MIDlet when the application is not running, the AMS will start the MIDlet via the MIDlet.startApp() method.

/*Display the list of all inbound connections.*/

public void displayConnections() {

String[] allConnections = PushRegistry.listConnections(false);

StringBuffer sbuf = new StringBuffer();

if (allConnections != null && allConnections.length > 0) {

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

sbuf.append(allConnections[i]);

sbuf.append("\n");

}

}

String str = sbf.toString();

}

/*Register or Unregister an inbound connection*/

public void regConnection() {

try {

String url = "socket://";

String classname = "Midlet" //Midlet to be launched

if (register) {

PushRegistry.registerConnection(url, classname, "*");

} else {

PushRegistry.unregisterConnection(url);

}

} catch (IllegalArgumentException iae) {

} catch (IOException ioe) {

}

}

/*register an alarm*/

public void setAlarm() {

try {

Date d = new Date();

String classname = "Midlet"

long previousAlarmTime = PushRegistry.registerAlarm(

classname,d.getTime() + MILLISECONDS_TILL_ALARM);

} catch (Exception e) {

}

}

/*Connect to Url*/

public void connectUrl() {

try {

String[] connections = PushRegistry.listConnections(true);

if (connections != null && connections.length > 0) {

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

ServerSocketConnection serverConnection =

(ServerSocketConnection)Connector.open(connections[i]);

SocketConnection socketConnection =

(SocketConnection)serverConnection.acceptAndOpen();

socketConnection.close();

serverConnection.close();

}

}

} catch (Exception e) {

}

}

Friday, February 20, 2009

What Is - RIM Push Request Response Codes

0 comments

When performing a RIM Push to the BlackBerry Mobile Data Service or BlackBerry MDS, an application receives an HTTP response code that indicates whether or not the Push has been accepted by BlackBerry Mobile Data Service or BlackBerry MDS. The following table outlines the response codes that can be returned from BlackBerry Mobile Data Service or BlackBerry MDS and what they represent:

Response Code Its Meaning Possible causes

200

OK. The Push was accepted successfully by the Mobile Data Service.

A valid Push has occurred.

400

General Error.

Invalid Push format.

Mobile Data Service 3.7 and earlier: The email address or personal identification number (PIN) used in the Push was not recognized as a BlackBerry Enterprise Server user enabled for Mobile Data Service.

403

Access control error, or unknown email address, or BlackBerry PIN specified.

Note: This response code was added in Mobile Data Service 4.0. Previous versions would respond to this error with response code 400.

The email address or PIN used in the Push was not recognized as a BlackBerry Enterprise Server user enabled for Mobile Data Service.

Push access control has been enabled on the BlackBerry Enterprise Server and the user or computer that is performing the Push has not been granted permission to perform a Push.

404

Page not found.

The Push request was not received by the Mobile Data Service. Verify the proper URL and port are being used when submitting the Push to the Mobile Data Service.

503

Server busy.

At the present time, the server is not able to manage the request due to temporary overloading or server maintenance. By default, Mobile Data Service is configured to handle 1000 simultaneous Push requests. This figure also includes Push requests that have been accepted and are pending delivery to a BlackBerry device.

Code : to access the screen below Popup screen

3 comments

I made a transparent Popup screen. But i wasn’t able to access the screen below that Popup screen,such that Popup screen remains on the top, but focus gets on the screen below. I have accomplished that task by using following method :

public final void pushGlobalScreen(Screen screen, int priority, boolean inputRequired)

but now it work fine.

i corrected as Ui.getUiEngine().pushGlobalScreen(translucent, 4, false);

Wednesday, February 18, 2009

Code : Implement the PhoneListener interface

2 comments

BlackBerry application programming interface (API) 4.0 introduced the ability to listen to the status of incoming and outgoing phone calls. To do so, an application must implement the PhoneListener (net.rim.blackberry.api.phone.PhoneListener) or AbstractPhoneListener class (net.rim.blackberry.api.phone.AbstractPhoneListener). The following code sample illustrates the implementation of the PhoneListener interface:


import net.rim.blackberry.api.phone.*;
import net.rim.device.api.ui.container.FlowFieldManager;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.Status;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.system.*;
public final class PhoneCallListenerSample extends Application
implements PhoneListener
{
static public void main(String[] args)
{
PhoneCallListenerSample plSample = new PhoneCallListenerSample();
plSample.enterEventDispatcher();
}
private PhoneCallListenerSample()
{
System.out.println("###PhoneCallListenerSample:
Registering listener...");
Phone.addPhoneListener(this);
System.out.println("###PhoneCallListenerSample:
Listener registered.");
}
private void showPhoneEvent(String reason, int callId)
{
Status.show("Phone event: " + reason + "\n" + "CallID: " + callId,
Bitmap.getPredefinedBitmap(Bitmap.EXCLAMATION), 4000,
Status.GLOBAL_STATUS, true, false, 2);
System.out.println("###PhoneCallListenerSample: Phone event: " +
reason + " for callID: " + callId);
}
// A call has been added to a conference call
public void callAdded(int callId)
{
showPhoneEvent("Call Added", callId);
}
// User answered a call
public void callAnswered(int callId)
{
showPhoneEvent("Call Answered", callId);
}
// Conference call established
public void callConferenceCallEstablished(int callId)
{
showPhoneEvent("Conference Call Established", callId);
}
// Network indicates a connected event
public void callConnected(int callId)
{
showPhoneEvent("Call Connected", callId);
}
// Direct-connect call connected
public void callDirectConnectConnected(int callId)
{
showPhoneEvent("DirectConnect Connected", callId);
}
// Direct-connect call disconnected
public void callDirectConnectDisconnected(int callId)
{
showPhoneEvent("DirectConnect Disconnected", callId);
}
// Call disconnected
public void callDisconnected(int callId)
{
showPhoneEvent("Call Disconnected", callId);
}
// User ended call
public void callEndedByUser(int callId)
{
showPhoneEvent("Call Ended By User", callId);
}
// Call has been placed on "hold"
public void callHeld(int callId)
{
showPhoneEvent("Call Held", callId);
}
// New call has arrived
public void callIncoming(int callId)
{
showPhoneEvent("Call Incoming", callId);
}
// Outbound call initiated by the handheld
public void callInitiated(int callid)
{
showPhoneEvent("Call Initiated", callid);
}
// Call removed from a conference call
public void callRemoved(int callId)
{
showPhoneEvent("Call Removed", callId);
}
// Call taken off of "hold"
public void callResumed(int callId)
{
showPhoneEvent("Call Resumed", callId);
}
// Call is waiting
public void callWaiting(int callid)
{
showPhoneEvent("Call Waiting", callid);
}
// Conference call has been terminated
// (all members disconnected)
public void conferenceCallDisconnected(int callId)
{
showPhoneEvent("Conference Call Disconnected", callId);
}
// Call failed
public void callFailed(int callId, int reason)
{
String errMsg = "Call Failed due to ";
// determine reason
switch( reason )
{
case PhoneListener.CALL_ERROR_AUTHORIZATION_FAILURE:
showPhoneEvent(errMsg + "Authorization Error", callId);
break;
case PhoneListener.CALL_ERROR_CALL_REPLACED_BY_STK:
showPhoneEvent(errMsg + "Call Replaced By Stack", callId);
break;
case PhoneListener.CALL_ERROR_CONGESTION:
showPhoneEvent(errMsg + "Congestion", callId);
break;
case PhoneListener.CALL_ERROR_CONNECTION_DENIED_BY_NETWORK:
showPhoneEvent(errMsg + "Connection Denied", callId);
break;
case PhoneListener.CALL_ERROR_DUE_TO_FADING:
showPhoneEvent(errMsg + "Fading", callId);
break;
case PhoneListener.CALL_ERROR_EMERGENCY_CALLS_ONLY:
showPhoneEvent(errMsg + "Emergency Calls Only", callId);
break;
case PhoneListener.CALL_ERROR_FDN_MISMATCH:
showPhoneEvent(errMsg + "FDN Mismatch", callId);
break;
case PhoneListener.CALL_ERROR_GENERAL:
showPhoneEvent(errMsg + "General Error", callId);
break;
case PhoneListener.CALL_ERROR_HOLD_ERROR:
showPhoneEvent(errMsg + "Hold Error", callId);
break;
case PhoneListener.CALL_ERROR_INCOMING_CALL_BARRED:
showPhoneEvent(errMsg + "Incoming Call Barred", callId);
break;
case PhoneListener.CALL_ERROR_LOST_DUE_TO_FADING:
showPhoneEvent(errMsg + "Lost Due To Fading", callId);
break;
case PhoneListener.CALL_ERROR_MAINTENANCE_REQUIRED:
showPhoneEvent(errMsg + "Maintenance", callId);
break;
case PhoneListener.CALL_ERROR_NUMBER_NOT_IN_SERVICE:
showPhoneEvent(errMsg + "Number Not In Service", callId);
break;
case PhoneListener.CALL_ERROR_NUMBER_UNOBTAINABLE:
showPhoneEvent(errMsg + "Number Unobtainable", callId);
break;
case PhoneListener.CALL_ERROR_OUTGOING_CALLS_BARRED:
showPhoneEvent(errMsg + "Outgoing Calls Barred", callId);
break;
case PhoneListener.CALL_ERROR_PLEASE_TRY_LATER:
showPhoneEvent(errMsg + "Try Later", callId);
break;
case PhoneListener.CALL_ERROR_RADIO_PATH_UNAVAILABLE:
showPhoneEvent(errMsg + "Radio Path Unavailable", callId);
break;
case PhoneListener.CALL_ERROR_SERVICE_CONFLICT:
showPhoneEvent(errMsg + "Service Conflict", callId);
break;
case PhoneListener.CALL_ERROR_SERVICE_NOT_AVAILABLE:
showPhoneEvent(errMsg + "Service Not Available", callId);
break;
case PhoneListener.CALL_ERROR_SUBSCRIBER_BUSY:
showPhoneEvent(errMsg + "Subscriber Busy", callId);
break;
case PhoneListener.CALL_ERROR_SYSTEM_BUSY_TRY_LATER:
showPhoneEvent(errMsg + "System Busy", callId);
break;
case PhoneListener.CALL_ERROR_TRY_AGAIN:
showPhoneEvent(errMsg + "Try Again", callId);
break;
case PhoneListener.CALL_ERROR_USER_BUSY_IN_DATA:
showPhoneEvent(errMsg + "User Busy In Data", callId);
break;
case PhoneListener.CALL_ERROR_USER_BUSY_IN_PRIVATE:
showPhoneEvent(errMsg + "User Busy In Private", callId);
break;
case PhoneListener.CALL_ERROR_USER_NOT_AUTHORIZED:
showPhoneEvent(errMsg + "Not Authorized", callId);
break;
case PhoneListener.CALL_ERROR_USER_NOT_AVAILABLE:
showPhoneEvent(errMsg + "User Not Available", callId);
break;
case PhoneListener.CALL_ERROR_USER_NOT_REACHABLE:
showPhoneEvent(errMsg + "User Not Reachable", callId);
break;
}
}

How To - Use the XML Parser

16 comments

XML (Extensible Markup Language) documents allow developers to represent complex data in a simple manner. Developers can completely define their data in XML because it provides fully customized tags. In XML, there are no predefined or hard-coded tags like there are in HTML documents.

The net.rim.device.api.xml.jaxp.XMLParser API allows developers to leverage XML advantages on the BlackBerry platform. This new BlackBerry JDE 4.0 API allows developers to parse XML content and customize the point of view on BlackBerry devices. The sample provided below uses a static web-based XML document and parses through it to display the tag name with its corresponding data values.

import javax.microedition.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.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;

class XML_Parsing_Sample extends UiApplication{
//creating a member variable for the MainScreen
MainScreen _screen= new MainScreen();

//string variables to store the values of the XML document
String _node,_element;
Connection _connectionthread;

public static void main(String arg[]){
XML_Parsing_Sample application = new XML_Parsing_Sample();
//create a new instance of the application
//and start the application on the event thread
application.enterEventDispatcher();
}

public XML_Parsing_Sample() {
_screen.setTitle("XML Parsing");//setting title
_screen.add(new RichTextField("Requesting....."));
_screen.add(new SeparatorField());
pushScreen(_screen); // creating a screen

//creating a connection thread to run in the background
_connectionthread = new Connection();
_connectionthread.start();//starting the thread operation
}

public void updateField(String node, String element){
//receiving the parsed node and its value from the thread
//and updating it here
//so it can be displayed on the screen
String title="Title";
_screen.add(new RichTextField(node+" : "+element));
if(node.equals(title)){
screen.add(new SeparatorField());
}
}

private class Connection extends Thread{
public Connection(){
super();
}

public void run(){
// define variables later used for parsing
Document doc;
StreamConnection conn;
try{
//providing the location of the XML file,
//your address might be different
conn=(StreamConnection)Connector.open
("http://localhost:8000/content/test.xml;deviceside=true");

//next few lines creates variables to open a
//stream, parse it, collect XML data and
//extract the data which is required.
//In this case they are elements,
//node and the values of an element
DocumentBuilderFactory docBuilderFactory
= DocumentBuilderFactory. newInstance();
DocumentBuilder docBuilder
= docBuilderFactory.newDocumentBuilder();
docBuilder.isValidating();
doc = docBuilder.parse(conn.openInputStream());
doc.getDocumentElement ().normalize ();
NodeList list=doc.getElementsByTagName("*");
_node=new String();
_element = new String();
//get the event lock to avoid IllegelStateException while accessing the UI
Object obj = Application.getEventLock();
//this "for" loop is used to parse through the
//XML document and extract all elements and their
//value, so they can be displayed on the device
for (int i=0;i<list.getLength();i++){
synchronized(obj){
Node value=list.item(i).
getChildNodes().item(0);
_node=list.item(i).getNodeName();
_element=value.getNodeValue();
updateField(_node,_element);
}
}//end for
}//end try
//will catch any exception thrown by the XML parser
catch (Exception e){
System.out.println(e.toString());
}
}//end connection function inside run
}// end connection class
}//end XML_Parsing_Sample

Useful Links : Useful links for Blackberry Programmers

0 comments

For programmers who are not familiar with java :-

The Source for Java Developers
Thinking in Java, by Bruce Eckel
Java 2 Micro Edition

For more experienced programmers :-

Blackberry Getting Started
Blackberry Developers Zone
Blackberry Developer Knowledge Base
Blackberry Developer Guide & Other documentation
Blackberry Developer Video Library
Blackberry Memory Best Practices Book
Blackberry GPS and Maps Developer Guide

Signing keys

Tools :-

Blackberry Java Development Environment
BlackBerry JDE Plug-in for Eclipse
Blackberry Simulators
Rapid Application Development tools for Blackberry (MDS Studio)
Blackberry MDS Runtime
BlackBerry Plug-in for Microsoft Visual Studio
Netbeans
Eclipse

Additional resources :-

Java Design Patterns
Java ME code samples
Java ME learning trail
BlackBerry Java Development Environment Labs
Blackberry Browser Labs
Rapid Application Development Labs
J2ME Tutorial
Wireless Development Tutorial
Kick start J2ME Development for Blackberry

Feature Story: BlackBerry Storm Smartphone

0 comments

The BlackBerry® Storm™ smartphone is the first touch screen BlackBerry® smartphone from Research In Motion (RIM). It builds upon a variety of existing BlackBerry smartphone features and capabilities to produce a truly compelling touch experience. With the BlackBerry Storm smartphone, RIM has introduced a version of software (v4.7) that delivers a new set of APIs and capabilities for third party developers including:

  1. Enhancements to the existing RIM User Interface APIs to provide support for touch and gestures, including proper handling of multi-touch events
  2. Support for MIDP applications that leverage touch
  3. Virtual keyboard APIs
  4. Enhanced and open GPS APIs on all networks
  5. Accelerometer APIs
In addition to the new API capabilities, your Browser-based applications will build upon the browser capabilities released in v4.6.0 including:
  • Improved web page rendering including AJAX
  • XMLHttpRequest
  • JavaScript® 1.5
  • CSS 2.1
  • DOM L2 (including Core, HTML, Style, Events)
  • HTML 4.01 (including Forms, Maps, Tables, Frames, Objects)
  • Improved Native Attachment Download
  • Support for downloading files via the browser
Key Features
  • Screen Resolution: 480x360 (Landscape Mode) and 360x480 (Portrait Mode)
  • Screen Type: Capacitive Touch Screen, Multi-Touch Support
  • Virtual Keyboard: Full Keyboard (Landscape Mode) and SureType® (Portrait Mode)
  • Networking: Global 3G Network Support (HSPA/EVDO Rev A)
  • Memory: 1GB Embedded microSD™ card
  • Autonomous and Assisted GPS Support (Assisted GPS dependent on carrier network support)
  • Compatibility Mode (more info below)

For third party developers, one of the unique features of the BlackBerry Storm smartphone is its "compatibility mode" which provides an operating environment for existing 3rd party applications that are not implemented to support touch. This feature will automatically convert touch events into existing trackball events. When an application is executing in compatibility mode, a virtual keyboard will be shown at most times to mimic the physical keyboard on previous devices and will only be displayed in portrait mode. All applications that are compiled with a JDE prior to v4.7 will automatically use compatibility mode, but the user will be able to change this configuration setting at their leisure. Any applications compiled with JDE v4.7 or higher will automatically run in the standard configuration.
To get started in your development, visit the following Link to download the appropriate products.

Developer Tips and Tricks

In this segment of Developer Tips and Tricks, discover the top four items every developer should know about the BlackBerry Storm smartphone.
1. Handling Gestures and Screen Details
If your application simply leverages existing built-in BlackBerry User Interface components, your application does not need to be modified for the BlackBerry Storm smartphone to handle gestures and screen layout. The underlying UI Engine will automatically perform these operations for you. However, if your application leverages custom UI fields, you will want to enhance their implementation to handle touch events. More information on the different gestures and sample code on how to use them can be found in the BlackBerry Storm smartphone Development Guide.
2. Orientation and Re-Sizing Events
Similar to handling gestures and screen details, you only need to worry about explicitly handling these events if your application leverages custom UI fields and managers. It is important to understand that you can leverage the UI APIs on the device to explicitly indicate what types of orientation your application will support, giving you the ability to control the layout of your application. However, your application will likely need to handle re-sizing events regardless of the orientation to support the dynamic display of the virtual keyboard. It is possible to have the virtual keyboard shown at all times to minimize this work but the resulting end user experience is significantly degraded.
3. Virtual Keyboard
With the inclusion of a virtual keyboard, your application can control both the type of keyboard (Full QWERTY or SureType®) and its visibility (shown or hidden). The Virtual Keyboard API’s also allow developers to lock their keyboards into place when required. Similar to the previous sections, the virtual keyboard should be shown and hidden automatically for built-in UI fields and managers.
4. Networking Technologies
The BlackBerry Storm smartphone is an incredibly unique device with the inclusion of both HSPA radio and EVDO Rev A radio producing 3G download and upload speeds worldwide. The EVDO version of the product will leverage the EVDO network within North America and roam to HSPA when outside of North America. In contrast, the HSPA branded version will leverage HSPA in all regions and will not roam to EVDO. From a third party developer perspective, the usage of these different radio technologies is handled automatically by the underlying BlackBerry solution implementation and does not require any additional work or effort.

Monday, February 16, 2009

News : T-Mobile Launches BlackBerry Curve 8900

2 comments

T-Mobile has launched the BlackBerry Curve 8900.The device is intended to be a variant of the Bold without 3G access and features a landscape HVGA (480×320) display, quadband GSM/EDGE 3.2 megapixel camera with autofocus, speakerphone, microSDHC expansion slot, media player, Wi-Fi with UMA support for HotSpot @ Home, Bluetooth with stereo audio support, and GPS support via built-in transceiver.
The device is now availabile from T-Mobile for $299.99 after new 2 year agreement and $200 instant online discount before an additional $100 mail-in rebate, bringing the total to $199.99.

Saturday, February 14, 2009

News : The BlackBerry Curve 8900 launches in Hong Kong

0 comments

Press Release
Hong Kong - Research In Motion today announced that the new BlackBerry Curve 8900 smartphone, the thinnest and lightest full-QWERTY BlackBerry smartphone to date, is available in Hong Kong. Powered by a 512MHz next generation processor, it packs quad-band EDGE support with built-in Wi-Fi (802.11 b/g) and GPS in a refined, streamlined design weighing just 110 grams and measuring only 109mm x 60mm x 13.5mm.

“The new BlackBerry Curve 8900 smartphone packs a wealth of functionality in a compact and refined design that looks and feels great,” said Norm Lo, Vice President, Asia Pacific at Research In Motion. “Its multimedia and messaging features help users stay connected and entertained, allowing them to make the most of their busy lifestyle at work and at play.”

The BlackBerry Curve 8900 will be available from 3 Hong Kong, China Mobile Hong Kong Company Limited (PEOPLES), CSL and SmarTone-Vodafone from mid February. For more information on pricing and detailed service plans, please contact the respective carriers.