Rollover Icon Creation

Once the backend and UI of the application are complete and have been thoroughly tested you'll eventually want to design a unique application icon for provisioning onto the device. If you do not assign an icon to your app, the device assigns a cookie-cutter application icon which does a pretty poor job of distinguishing your app. If you intend on programming your app for all the various OS versions beyond 4.5 you'll need to design the icon for both the Precision and Dimension themes. Regardless of what icon you come up with you'll need to have one regular version and one that displays the "rollover" effect.

In order to programmatically instantiate the rollover effect for OS's prior to 4.7 you must first set your app to startup with the Blackberry OS and then you have to create an alternate entry point for the application such that the OS can access your app on startup and acquire the appropriate icon images to use in creating the effect. Although I've never tried this, apparently for 4.7 you can just set the Icon and Focus Icon files straight in the Project properties by right-clicking on the project then "Properties->Blackberry Project Properties-> Resources". Then just add the icon files to the appropriate slots. Even though 4.7 has this capability, I still find that since most developers are working across multiple OS's it makes much more sense to programatically work this functionality into your application.


I'll show the required steps for Eclipse with the Blackberry plugin since this is my environment of choice. Some of the code is located in the Blackberry knowledge base articles found here

Configure the Eclipse Project Properties


First you need to configure your project to run when the Blackberry device is started. Right click the project file and go to Properties->Blackberry Project Properties. Check the 'System Module' and 'Auto-run on startup' checkboxes and make sure the'Startup Tier' is set to '7(Last;3rd party apps only'. The config for your main project should look like the one below:



Next you'll need to create a new Blackberry project in the same workspace as the current project. The purpose is to act as a surrogate that passes the appropriate command line information to our main app when it's compiled. Once this is complete, right-click the project file as before and go to "Properties->Blackberry Project properties'. Set the Project type as 'Alternate CLDC Application Entry Point', the 'Argument passed to "static public void main(String args[])" as "gui" and "Home screen position" as 0. The "Alternate entry point for:" option should be set to your main project name. Refer to the screenshot below:



[Update]In order to set a custom application icon after installation of your app simply right-click this new Project and browse to Project properties->Blackberry Project Properties->Resources(tab) then under the "Icon Files" option click "Add" and point to the proper .png file you want as your base application icon. Make sure that .png file is in your main project's directory otherwise it won't be included in your .cod file and the phone won't have the image to load after install.

After you complete the coding below and recompile your project, open your .jad configuration file you'll see the following line in it indicating the icon file to use:

RIM-MIDlet-Icon-2-1: ../{MAIN_PROJECT_DIRECTORY}/src/{PNG_FILE_NAME}.png,

I haven't tried directly modifying this path to the image in the main project's .jad file but I imagine that it would work and would be quicker. Note that the rollover effect will not work until the phone is reset however without making this modification you'll get the default Blackberry icon for your app which could be a bit confusing to the end user.[END UPDATE]


Coding the Alternate Entry Point


The final step is to code the alternate entry point into your main function. The idea here is that you've set the Launcher project settings to pass the "gui" string on the command line which will tell our application to run when the user selects our app normally. If our application doesn't receive the "gui" string - in this case when the Blackberry is started up - it will instead provide the OS with the appropriate icon files to perform the rollover effect. Here's the code for main:


public static void main(String[] args){

if ( args != null && args.length > 0 && args[0].equals("gui") ){
//main entry point
MainScreenUI theApp = new MainScreenUI(false);
theApp.enterEventDispatcher();
} else {
//Pass the icons
MainScreenUI theApp = new MainScreenUI(true);
theApp.enterEventDispatcher();
}

}


To reinforce the point here we are passing our MainScreenUI constructor a boolean that will tell it if it's received the "gui" string from the command line - true for normal user startup and false if the phone rebooted/turned on. Below is the code in MainScreenUI for the class constructor - note that the boolean autoStart tells the constructor what to do during runtime. Also, we're using the HomeScreen class to see what the preferred icon size is and then based on that will identify the correct icon to use. The BitMaps that are used to pass to HomeScreen.UpdateIcon() and HomeScreen.setRolloverIcon() must be final since we're calling final functions. Refer to the code below :

public MainScreenUI(boolean autoStart){

if(autoStart){
//The application started using the auto start entry point.
//Setup the rollover icons.

Bitmap tRegIcon;
Bitmap tIcon;
//73 Storm, 80 Bold,
if(HomeScreen.getPreferredIconHeight() > 70){
tRegIcon = Bitmap.getBitmapResource("iconpng.png");
tIcon = Bitmap.getBitmapResource("iconglowpng.png");
}
else{
tRegIcon = Bitmap.getBitmapResource("curve.png");
tIcon = Bitmap.getBitmapResource("curveglow.png");
}

final Bitmap regIcon = tRegIcon;
final Bitmap icon = tIcon;

invokeLater(new Runnable()
{
public void run()
{
ApplicationManager myApp =
ApplicationManager.getApplicationManager();

boolean keepGoing = true;

while (keepGoing)
{
//Check if the BlackBerry has completed its startup process.

if (myApp.inStartup())
{
//The BlackBerry is still starting up, sleep for 1 second.

try
{
Thread.sleep(1000);
}
catch (Exception ex)
{
//Couldn't sleep, handle exception.
}
}
else
{
//The BlackBerry has finished its startup process.

//Set the rollover icons.
try{
HomeScreen.updateIcon(regIcon, 1);
HomeScreen.setRolloverIcon(icon, 1);

}
catch(Exception e){}

keepGoing = false;
}
}
//Exit the application.
System.exit(0);
}
});
}

else{
TitleScreen ts = new TitleScreen();
pushScreen(ts);
Thread t = new Thread(this);
t.start();
int width = Display.getWidth();

............



Note that the try{}catch{} block is required around the HomeScreen.updateIcon() and HomeScreen.setRolloverIcon() since for reasons unknown to me(a bug in the OS code perhaps?) an IllegalArgumentException is thrown there. Despite this, the functions still work and your icons will appear.

Now you'll be able to compile your application as normal and test on the Blackberry device. Upon startup, the correct icon files will be inserted by the OS and when the user scrolls onto it the rollover will place the appropriate icon in place.

4 comments:

Anonymous said...

Thanks for the invaluable post. I've spent a day trying to properly set the icon and rollover icon - this is by far the most coherent and useful instructions I've come across (knowledgebase articles are flawed). It works on the simulator and device (usb and OTA). The only problem is that it requires a reboot of the phone for the icon and rollover icon to actually take effect. After installation, I just get the default icon. Any idea how to make the icon/rollover automatically automatically show before reboot?

John Banks said...

Thanks for your comments bigmasc, really appreciate it. To the best of my knowledge there is no way of forcing the blackberry to use the icons you've updated without rebooting. You're literally telling the OS to use your designated icons and the OS won't know about them until it runs through the registered apps - at startup. I believe that this is one of the many reasons most apps require a reboot on install.

Anonymous said...

John, thanks for the response. Here's what I've noticed from testing currently available apps. Some apps don't use a rollover icon at all, but the regular icon appears immediately after install (Bank of America, QuickPull). Other apps show a regular icon immediately after install, but show a rollover icon following reboot (eBay, WeatherEye). Apps released by RIM show regular and rollover icons immediately after install - I assume they have access to some private APIs (MySpace, AppWorld).

My problem is that, following your directions, I only get the default icon immediately after install; the regular and rollover icons don't appear until after reboot. But clearly it's possible to have the regular icon appear without reboot. Am I missing something?

John Banks said...

After a bit of investigation I think I know the solution to your problem and I'll update the tutorial with better instruction. If you are not doing a rollover icon but you want an icon that's different than the default you simply set your icon file in the project properties: Right-click the project->Project properties->Blackberry Project Properties->Resources(tab) then under the "Icon Files" option click add and point to the proper .png file you want as your base icon.

In our case we're making the rollover icon work by creating a second Blackberry project in the same workspace as the main project that acts as the surrogate to pass the "gui" parameter (in my case above it was the "Launcher" project). It's this project's config that's also included in the main project's .jad Blackberry configuration file and is screwing up the default icon selection.

What we have to do is set the second project's icon file the same way I just explained. When you rebuild your main project you'll see an entry in the .jad file, similar to the one below (where MAIN_PROJECT_DIRECTORY is your project's directory name, etc):

RIM-MIDlet-Icon-2-1: ../{MAIN_PROJECT_DIRECTORY}/src/{ICON_IMG_NAME}.png,

You'll notice that it goes up a directory then to your main project's directory, then the path to file. I imagine that you can simply edit the .jad file with the right path to the icon image you want and it will accomplish the same thing although I didn't try that. However, I did ensure that doing it the way I described does give you your custom icon after install without reboot.

Let me know if that works for you.

Post a Comment

top