The Power of Ant Build

There's several official ways for WebWorks developers to package their apps: Ripple (which I have personally never actually used) and the command line (my former favorite) being the big two. However, Tim Windsor from the BlackBerry Dev Relations team created what is, in my opinion, the best and easiest way to package and sign your WebWorks apps: the Ant Build Script.

If you want to skip the rest of this post and read Tim's excellent documentation on getting it all set up, just head over to But if you're not convinced yet, read on.

First, why is the Ant Build Script awesome? 

It's awesome because it lets you quickly and easily compile your apps via the command line in a variety of ways. Before I had the Ant Build Script, I'd write my app, add it to a zip, move it to a folder I set up for signing/packaging, open the command line, and type "bbwp c:/apps/ -g mypassword -buildId 0"; if I wanted to say add web inspector, I'd have to add -d, and there were a few other operators that I've forgoten. Then I'd drag it to a sideloading bat to sideload it onto my BlackBerry.

With the Ant Build Script, all I have to do is open the command line tool in the app folder (shift+right click) and type "ant build" and my bar is compiled and sideloaded to my BlackBerry. That simple.

If that convinced you that the Ant Build Script is awesome (if it didn't, read it again), then here's how to get it set up:

Set Up

1Download the Ant Build Script from and extract it to somewhere you don't mind keeping it.

2Open the buildTasks.xml (it's in the tools folder) with a program like Notepad++ and edit the variables you need, such as the location of your SDKs and your signing key password.

3Download Apache Ant from (you want the binary zip)

4Unzip Apache ant anywhere you want (I put it into the root of my C drive)

5Add Ant_Home to your System Variables

The easiest way to do this is to type "System Variables" into the Windows Search bar. You can also get to it by right clicking on the computer icon.Click the "New" Button.
For Variable Name, type ANT_BUILD For Variable Value, enter the directory of the Ant build folder. For me, that was C:/ApacheAnt

6Now, whenever you want to package a new app, copy the build.xml file from the Ant Build Script folder, edit it to suit your needs, and run "ant build"

That should be it! If you have any problems with my instructions, check out Tim's to see if he explained something better than I did, or email us here at OSBB to let us know.


getUserMedia: stream video to your BB10 WebWorks App

If you ever wanted to stream into your BlackBerry 10 WebWorks app, it's pretty simple to do. This tutorial will include a brief example showing how to do it (and include all the necessary code).

1. Prepare all the basic elements for your app; the config.xml, any custom scripts and styling, and get everything set up.

2. Add the needed features and elements to your config.xml:


I also recommend you use the following to lock the orientation: 

<feature id="">
<param name="orientation" value="portrait" />

3. Create the following video and canvas elements on the page you want to stream video to:

<canvas id="canvas"></canvas>
<video id="video" style="display: none;" autoplay></video>

You'll probably want to include the height/width of your canvas in that element.

4. Add the code!If you're using bbUI, you can add it to the onDomReady event. If you're not, the easiest way to use it is to use a DOMContentLoaded event listener: document.addEventListener('DOMContentLoaded', function() {})

var video = document.getElementById("video");
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d')
navigator.webkitGetUserMedia({video: true}, function(stream) {
     video.src = window.URL.createObjectURL(stream);
     setInterval(function () {ctx.drawImage(video, 0, 0, 300, 500);}, 20);

That's it! 

And if you're on your BlackBerry 10 device, or using Google Chrome, here's the above code in action:

Click here to see the code in action


WebWorks File API Framework

One of the things I love about developing for BlackBerry 10 is that BlackBerry has really done well at implementing HTML5 standards (and a quick visit to confirms it). While this is awesome as far as creating robust HTML5 apps is concerned, it means that developers have to learn new technologies that might not be fully implemented in your web browser. As an example, webkitGetUserMedia only recently showed up in Chrome.

The File API isn't all that new (it's been around a while now), but it's something that I couldn't find a whole lot of documentation for it. There is a very, very good article at, but it's (in my opinion) a fairly involved API.

The great folks over at BlackBerry have implemented the File API, but that doesn't necessarily mean it's easy for developers to start using. And since the web is all about frameworks these days (JQuery, Sencha, etc), I figured I'd do a mini framework of BlackBerry specific File API functions to make things easy for other WebWorks Devs to implement saving and loading (including backup and restore) to their apps!

This framework is Open Source (so you can browse my typos without even downloading it), and you can check it out at My Github.

You can check out the readme in the github link to see how it works, but here's the quick how-to:

1. Include the javascript in your index.html

Example: <script type="text/javascript" src="/cssjs/bbfiles.js"></script>

2. Add the required feature IDs to your config.xml:

<feature id="blackberry.invoke.card" />
<feature id="" />
<feature id="blackberry.ui.toast" />

3. Create a function for whatever you want to do. Functions that are available: 

Save text to a specified file:
saveText(Text to save, save location and file name)
Example: saveText('Hello World!', '/accounts/1000/shared/misc/helloWorld.txt')

Save text to a file of the user's choice:
saveText(Text to save, location to open the file picker, 'picker')
Example: saveText('Hello World', '/accounts/1000/shared/misc/', 'picker')

Load text from a file:
loadData(location of document)
Example: loadData('/accounts/1000/shared/misc/helloWorld.txt')

Load text from a file of the user's choice:
loadData(location to open the file picker, 'picker')
Example: loadData('/accounts/1000/shared/misc/', 'picker')

Delete a specified file:
deleteFile(file location and name)
Example: deleteFile('/accounts/1000/shared/misc/helloWorld.txt')

Delete a file of the user's choice:
deleteFile(location to open the file picker, 'picker')
Example: deleteFile('/accounts/1000/shared/misc/', 'picker')

Create a folder:
createFolder(folder to create)
Example: createFolder('/accounts/1000/shared/misc/New')

Delete a folder:
deleteFolder(folder to delete)
Example: deleteFolder('/accounts/1000/shared/misc/New')

Move a file:
moveFile(location to move the file to, current file location and name)
Example: moveFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/helloWorld.txt')

Move a file of the user's choice:
moveFile(location to move the file to, location to open the file picker, 'picker')
Example: moveFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/', 'picker')

Move and Rename a file:
moveRenameFile(location to move the file to, current file location and current file name, new name)
Example: moveRenameFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/helloWorld.txt', 'newFile.txt')

Move and Rename a file of the user's choice:
moveRenameFile(location to move the file to, location to open the file picker, new name, 'picker')
Example: moveRenameFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/', 'newFile.txt', 'picker')

Copy a file:
copyFile(location to move the file to, current file location and file namee)
Example: copyFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/helloWorld.txt')

Copy a file of the user's choice:
copyFile(location to move the file to, location to open the file picker, 'picker')
Example: copyFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/', 'picker')

Copy and Rename a file:
copyRenameFile(location to copy the file to, current file location and current file name, new name)
Example: copyRenameFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/helloWorld.txt', 'newFile.txt')

Copy and Rename a file of the user's choice:
copyRenameFile(location to copy the file to, location to open the file picker, new name, 'picker')
Example: copyRenameFile('/accounts/1000/shared/misc/downloads/', '/accounts/1000/shared/misc/', 'newFile.txt', 'picker')

Rename a file:
renameFile(file location and current name, new name)
Example: renameFile('/accounts/1000/shared/misc/helloWorld.txt', 'yay.txt')

Rename a file of the user's choice:
renameFile(file location, new name, 'picker')
Example: renameFile('/accounts/1000/shared/misc/', 'yay.txt', 'picker')

Save Canvas to an image:
saveCanvas(canvas element, location and name you want to save canvas to)
Example: saveCanvas(document.getElementById('canvas'), '/accounts/1000/shared/misc/image.png')

Save Canvas to an image of the user's choice:
saveCanvas(canvas element, location to open the file picker, 'picker')
Example: saveCanvas(document.getElementById('canvas'), '/accounts/1000/shared/misc/', 'picker')

Load image to Canvas:
loadCanvas(canvas element, image to load', 'nopicker', width you want image to load, height you want image to load)
loadCanvas(document.getElementById('canvas'), '/accounts/1000/shared/misc/image.png', 'nopicker', 500, 300)
Note: 'nopicker' can be any text except 'picker'. It is optional, unless you specify a height and width (which are also optional).

Save image of the user's choice to Canvas:
loadCanvas(canvas element, location to open the file picker, 'picker', width you want image to load, height you want image to load)
loadCanvas(document.getElementById('canvas'), '/accounts/1000/shared/misc/', 'picker', 500, 300)

That's it! Maybe not as simple as simple can get, but a lot better than writing the function out yourself :)


Getting Started with BBUI.js



In this tutorial, we will get to know the basic structure of BBUI.js. Recently, I developed an app, Crochet Buddy HD, for PlayBook using BBUI.js for UI elements. to developp the app, I essentially only used the actionbarlist,&nbspbuttons, andscreen;elements when creating the UI.  Below, we will create a sample BBUI.js app using some of these elements

Before diving in, it is important to become familiar with some of the main features of BBUI.js. First, the action bar...

UI Elements: The ‘Action Bar’

The Action Bar in BBUI.js

The action bar is the primary navigation "dock" for the typical BBUI.js based app.  Buttons, tabs, and other elements can be placed on the action bar and various actions can be assigned to the action bar elements.

In Crochet Buddy HD, I created four action bar buttons. Each panel/page in my app resides in it's own .htm file.  To keep everything contained within the BBUI framework, each button does not simply link to the .htm file of the corresponding page. Each item on the action bar is defined as a data-bb-type="action", so look at the code below:


<div data-bb-type="screen" data-bb-scroll-effect="on"> [Page HTML code goes here] <div data-bb-type="action-bar"> <div data-bb-type="action" data-bb-style="button" data-bb-img="images/actionBar/cog_dark_theme.png" onclick="bb.pushScreen('HTML_File.htm');" data-bb-title="Action Title">Text Under Button</div> </div>


In the code sample above, you have one panel of an app. just before closing the div, you can see we inserted an action bar and defined one button, that when activated  will load 'HTML_file.htm'.

The code in 'HTML_file.htm' will look very similar to the code above, but I will change the action bar.  See code sample below:


<div data-bb-type="screen" data-bb-scroll-effect="on"> [Page HTML code goes here] <div data-bb-type="action-bar"> <div data-bb-type="action-bar" data-bb-back-caption="Back"></div> </div>


When you define data-bb-back-caption="Back" in the action bar as we did in the above sample, the result is a blank action bar with a functioning back button (see image below)

Action bar with 'back' button

So, as you would expect, when the 'back' button is tapped, you will return to the previous panel.

UI Elements: Lists

There are 2 lists types that can be called within BBUI,js:

  • Arrow Lists
  • Image Lists
  • Grid Lists

Each lists has it's own look and feel (see image below).

To use the various list type in your app, you simply create a div define the list type using the attribute bb-data-type="list type goes here" and create the items in the list. Check out the code sample below:

<div data-bb-type="text-arrow-list">  <div data-bb-type="item" onclick="alert('click')">Sleepy</div>  <div data-bb-type="item" onclick="alert('click')">Sneezy</div>  <div data-bb-type="item" onclick="alert('click')">Dopey</div>  <div data-bb-type="item" onclick="alert('click')">Grumpy</div>  <div data-bb-type="item" onclick="alert('click')">Doc</div>  <div data-bb-type="item" onclick="alert('click')">Bashful</div> <div data-bb-type="item" onclick="alert('click')">Happy</div> </div>

 In the above sample code, we created an arrow-list and the individual items contained within that list. With BBUI.js it really is simple to create UI elements.

Building a sample application

Now that the basics have been discussed, we can build a simple sample BBUI.js application.

Before getting started, there are a couple of things you will need:

  • Download BBUI.js from GitHub here
  • A good IDE or Editor. I prefer Notepad++ which can be downloaded here

Once you have BBUI.js downloaded, unzip the contents. Locate the 'samples' directory and copy and paste it into it's own directory outside of the BBUI.js directory (I copied the samples directory to MyDocuments\bbuiapp1).

Once you have the samples directory in the desired location open up the folder and locate the index.htm file with your favorite text editor.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"> <!-- * Copyright 2010-2011 Research In Motion Limited. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. --> <html>  <head> <meta name="x-blackberry-defaultHoverEffect" content="false" /> <meta name="viewport" content="initial-scale=1.0,width=device-width,user-scalable=no,target-densitydpi=device-dpi" /> <link  rel="stylesheet" type="text/css" href="/bbui-0.9.2.css"><link /> <script type="text/javascript" src="/bbui-0.9.2.js"></script> <script type="text/javascript"> // For some fun I did some random color scheme generation :o) var bb10HighlightColor, randomNumber; randomNumber=Math.floor(Math.random()*100); if (randomNumber > 60) {   bb10HighlightColor = '#BA55D3'; } else if (randomNumber > 30) {   bb10HighlightColor = '#00BC9F'; } else {   bb10HighlightColor = '#00A8DF'; } // You must call init on bbUI before any other code loads.   // If you want default functionality simply don't pass any parameters.. bb.init(); bb.init({bb10HighlightColor: bb10HighlightColor, bb10ActionBarDark: true, bb10ControlsDark: true, bb10ListsDark: false, bb10ForPlayBook: true, // Fires "before" styling is applied and "before" the screen is inserted in the DOM onscreenready: function(element, id) { if (id == 'dataOnLoad') { dataOnLoad_initialLoad(element); } // Remove all titles "except" input and pill buttons screen if running on BB10 if (bb.device.isBB10 && id != 'input' && id != 'pillButtons') { var titles = element.querySelectorAll('[data-bb-type=title]'); if (titles.length > 0) { titles[0].parentNode.removeChild(titles[0]); } } }, // Fires "after" styling is applied and "after" the screen is inserted in the DOM ondomready: function(element, id) { if (id == 'dataOnTheFly') { dataOnTheFly_initialLoad(element); } } }); </script> </head> <body onload="bb.pushScreen('menu.htm', 'menu');"> </body> </html>


You will notice that the index.htm file contains the standard <head> with stylesheets and javascript.

In the <body> of the document bb.pushScreen() is used to load the intital landing page for your app.

Now let's build a page.

Browse back to the 'samples' directory containing the index.htm and delete all other .htm files except for index.htm (don't worry these files are still on your HDD in the BBUI.js directory you extracted earlier) IMPORTANT: Only delete the .htm files, leaving the directories, CSS, and JS files untouched.

Open your favorite text editor and create a new .htm file in the samples directory with the name: home.htm (this will be the very first screen visible when your application is launched)

The structure of each page will be similar, for home.htm use the following:


<div data-bb-type="screen" data-bb-effect="fade"> <div style="height:175px; width:550px;margin: 0px auto 0px auto;"> <h1 style="height:12%; text-align:center; padding-top:3%;">App Title or Image</h1> </div> <h2>Please choose an item below</h2> <div data-bb-type="image-list" data-bb-image-effect="fade"> <div data-bb-type="item" onclick="bb.pushScreen('calculator.htm', 'calculator');"data-bb-img="images/icons/icon4.png" data-bb-title="Calculator">A simple function calculator</div> <div data-bb-type="item" onclick="bb.pushScreen('slider.htm', 'slider');" data-bb-img="images/icons/icon3.png" data-bb-title="Slider">Example of a Slider</div>  <div data-bb-type="item" onclick="bb.pushScreen('table.htm', 'table');"data-bb-img="images/icons/icon2.png" data-bb-title="Table Example">An example of a formatted table</div> </div> <div data-bb-type="action-bar"> <div data-bb-type="action" data-bb-style="button" data-bb-img="images/actionBar/cog_dark_theme.png" onclick="bb.pushScreen('action1.htm', 'action1');">Action 1</div> <div data-bb-type="action" data-bb-style="button" data-bb-img="images/actionBar/cog_dark_theme.png" onclick="alert('You clicked Action 2. This could trigger an alert or load a page, or any other action you wish');">Action 2</div> </div> </div>


Save this file in the root directory (same directory as index.htm).

Now that we have a landing/home page for our app, we need to open index.htm and have it point to the home page.

In index.htm change


<body onload="bb.pushScreen('menu.htm', 'menu');"> </body>




<body onload="bb.pushScreen('home.htm', 'home');"> </body>


Now, save and close index.htm

Once the app is packaged, the steps above will result in the following (click image for larger view):


Adding Content

Within the code in home.htm, you will notice that some of the buttons and list items point to .htm files we have not yet created. Each of those pages can contain any HTML code you wish, but should follow the structure below:


<div data-bb-type="screen" data-bb-effect="fade"> {your html code here} <div data-bb-type="action-bar" data-bb-back-caption="Back"></div> </div>


 The content should be wrapped in <div data-bb-type="screen"> </div>. Essentially,  each .htm page will be treated as a <div> within index.htm.  So, when you use onclick="bb.pushScreen();" the content of that page is loaded within the BBUI.js wrapper.

Other than the index.htm and home.htm files we have already discussed, the following pages need to be created:

In the above bullet list, click any of the pages to see the associated code.

Prior to being able to package your app, you will need to creat a config.xml file.

More information about the config.xml file can be found here.

The config.xml should be formatted as follows:


<?xml version="1.0" encoding="utf-8"?> <!-- * Copyright 2010-2011 Research In Motion Limited. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. --> <widget xmlns=""         xmlns:rim=""         version="" id="bbuijssample">   <name>Sample BBUI app</name>   <description>App description</description>   <author>Your Name</author>   <icon src="/images/icon.png" />     <rim:permissions> <rim:permit>access_shared</rim:permit> </rim:permissions>   <rim:orientation mode="portrait" />   <content src="/index.htm" />            <feature id="" required="true" version="1.0.0" />    <feature id="blackberry.invoke" required="true" version="1.0.0"/>    <feature id="blackberry.identity" required="true" version="1.0.0"/>    <feature id="blackberry.ui.dialog" required="true" version="1.0.0"/>    <feature id="blackberry.ui.dialog"/>    <feature id="" required="true" version=""/>    <access subdomains="true" uri="*"/>   </widget>


 Included in the assests archive (available for download at the end of this post) are all the files that we create in this tutorial--including and icon. However, if you wish you can create and 86 x 86 PNG icon and save it as "icon.png" in the "images" directory for the app.

Important: For the purposes of this tutorial, many images and other files were not removed from the original BBUI.js files downloaded earlier in the tutorial. Many of these files are not needed, but for the purposes of this tutorial there really is no harm in leaving those files in place.  

With all the files in place you can now package this app. Since we are targeting PlayBook with this app, the Tablet OS Webworks packager should be used.

Note: Included in the assets archive (available for download below) is a presigned .bar file that can be sideloaded onto your PlayBook. I included this to provide a reference for how the app created in this tutorial should look and function.

For help compiling and installing this application on your PlayBook, please see the following information from RIM: HERE

To download all the files used in this tutorial click the button below:


Subscribe to this RSS feed
Subscribe to the official OSBB BBM Channel!



Back to top