• Articles about computing
• Articles about software development
My adventures with developing a Qt application for the BlackBerry PlayBook
The recent fall in price of BlackBerry PlayBook tablets potentially
makes these devices much
more attractive to buyers — even if only as media players. Right now in the UK
you can pick up a 64Gb unit for just over £100: a price that compares
favourably with media players from Archos and Samsung. Of course, with the
you're getting a full tablet PC, with Web browser, camera,
personal information manager, and support for 3rd-party applications.
The delative dearth of applications (compared to the number
available for Android) is seen by many as the
weak point in the BlackBerry tablet's ability to develop a decent market
However, the reduction in price has roughly coincided with a number
of particular interest to potential application vendors.
Most significantly, perhaps, is the recent introduction of Android
emulation in the PlayBook OS. Some porting is still necessary but,
potentially, vendors with existing Android applications might be
encouraged to try their luck in the BlackBerry market.
However, for my purposes, of more interest is the fact that
BlackBerry has released
tools for compiling and deploying native-code applications (the Native
Development Kit, NDK) for the PlayBook. We have to
be a bit careful about the word 'native' in this context; many writers
use the term 'native' to mean
'written specifically for the PlayBook', rather than ported from Android.
I'm using the word native in that sense and the traditional sense
of an application deployed as machine code. This new development
is of interest because it offers something that Android does not
offer — the ability to develop fully-featured, desktop-style applications,
free of the limitations posed by the tightly controlled virtual machine
and user interface of Android.
This freedom and flexibility come at a price, however.
The BlackBerry NDK provides only raw, low-level platform services.
What I mean by that is that the application sees a video framebuffer
and a source of input events (keystrokes from the virtual keyboard, for
example). Notably, there is no user interface library beyond very
rudimentary window control. No widgets, no window manager, no kinetic
Whatever user interface features you want, you get to code
yourself, down to the pixel level. It's a bit like developing for X on
a Unix platform, without even a rudimentary toolkit.
This situation is less painful than it
might be, because
soon after the release of the NDK, substantial work was
done on porting the Qt user interface platform to the PlayBook. Qt provides
a very rich, inclusive library of user interface widgets and related
services — I/O, text formatting, and networking, for example.
In this article, I will outline my efforts to develop a desktop-style
file manager for the BlackBerry PlayBook, using Qt and the BlackBerry
NDK. My reasons for doing this are partly for self-education, and partly
because the PlayBook lacks such a thing itself. There is a rudimentary
file browser, but it has no concept of a folder or directory. The browser,
and all the built-in applications, flatten any directory structure that
the user might create. In a small computer with 64Gb of storage, the
inability even to create and browse folders, or to move files from one
folder to another, is — it seems to me — a shocking omission.
I will also make some comparisons between developing for the
PlayBook and developing for the Android platform.
Developing the file manager application hasn't been an
entirely satisfactory experience, although I'm
moderately happy with the results. My hope is that my experiences will
be of some help to other people considering developing for the
Blackberry platform, or even just interested in this kind of technology.
I'm not going to be able to go into a whole lot of detail — the best
I can do is point out particular areas where I had difficulty, and
what I had to do to overcome those difficulties (where I could).
BlackBerry supplies versions of the NDK for Linux and Windows platforms.
For either platform, the NDK is a huge download. A large part of that
download is the Mometics integrated development environment (IDE).
I'm not a big fan of IDE tools in general, and I'm unsure whether the
IDE can be used for development with Qt. If it can, the process does
not seem to be well documented. What's more, it seems that most
work in this area has been done on the Linux platform — presumably it
is possible to use BlackBerry's Windows tools to produce Qt-based
applications but, again, there's little documentation to support this.
Consequently, I'm working entirely with command-line tools and Makefiles on
a Linux platform. That suits me fine — it's exactly what I'm used to, but
I don't think it's the way BlackBerry intended their tools to be used,
and there's little information from BlackBerry about working this way.
The NDK is available from the
BlackBerry Native SDK Web site. There's a lot of information on the BlackBerry site about
code signing, and the keys that you will need to get from BlackBerry to
make applications available to other users. In fact, for most of the
development process you don't need these keys. Instead, you can install a
'debug token' on the PlayBook, and package applications in debug mode.
Information on doing this is provided on the
Setting up the Native SDK page at the Qt Project Web site and, as it's a bit of a bear, I'll have more
to say about it later.
To use Qt you're going to need the Qt libraries and header files. These are,
or should be, independent of the development platform and, by now, perhaps
they are available somewhere as precompiled binaries. However, provided
the NDK is set up correctly, it's actually quite straightforward to
build Qt from source. This process is also documented at the Qt project
building Qt for BlackBerry.
The result of following all these instructions should be a BlackBerry-specific
version of the GCC compiler tools, an IDE (which I haven't used, except for
generating code signing certificates, as explained below),
and a set of Qt libraries ready
to be linked against your application.
Provided that the environment is set up correctly, you should be able
to build applications specified by a standard Qt
.pro file is processed by the
qmake utility to produce
Makefiles, which can then be processed using GNU
the usual way. Of course, you can write the Makefiles manaually,
but the QMake approach automates the very ugly step of running the
Qt Meta-Object Compiled (
moc) in the various C++ classes.
.pro file won't do the packaging of the
application into a deployable
bundle, but (Blackberry-specific) instructions can be added to it to do
Things to watch out for
There isn't space to describe all the detailed steps needed
to write an application
for the PlayBook; I'm assuming that the reader as some knowledge
of Qt, C++, and mobile application development in general.
The Playbook deployment format is a BAR (Blackberry ARchive?) file,
conventionally with a name ending
The BAR file is simply a ZIP archive containing a manifest
file, the executable code,
descriptor (previously called
preferred name now is
bar-descriptor.xml), and any other
resources the application needs. In a Qt application, those resources
will include the Qt libraries themselves. The format of the BAR file
looks superficially similar to that of a signed Java Archive,
but I don't think
it's similar enough that you could use common Java tools to create it.
BAR files can be signed or unsigned. An unsigned BAR can only be deployed
on an emulator, or on a real tablet with a debug token installed. Because
the debug token is identified in the BAR file, it is impossible
(I believe) to distribute unsigned BAR files in a way that is useful
to anybody except other developers with access to the NDK tools. They
are of no use to end users. More on the knotty issue of code
Packaging the Qt libraries with the application presents the obvious
disadvantage that they are likely to be larger than the application.
The minimum additional size seems to be about 6Mb (compressed). The
advantage is that you can, if necessary, modify and build Qt to suit
your application. Discussions on the various developer forums suggests
that such modifications are sometimes necessary — the Qt port
to BlackBerry is not perfect, and does not suit every application.
However, I did not find it necessary to make changes to the
Qt libraries for my purposes.
In practice, the BAR file gets generated using the
blackberry-nativepackager utility, part of the NDK.
This utility has a whole bunch of obscure, poorly-documented
command-line arguments. The only way to figure out what they all do
seems to be to look at other peoples' projects, coupled with a fair
amount of trial and error.
Everything the application needs has to be packaged into the BAR
file. The structure of the BAR file maps onto the structure of the
directories created when the application is installed, but in a non-obvious
way. The example of making, say, an icon available as a PNG file
To pack the icon (or, indeed, anything) into the BAR file, you need
to use a command-line argument of the form:
-e path/to/icon.png res/icon.png
res/icon.png is where the PNG file will end up in the BAR
archive. But if you look in the archive, you'll see that the location
native directory is implicit. On deployment, the
whole of the
native directory gets unpacked into a folder
app/native, which is a subdirectory of the application's
private installation directory. That installation directory will be the
working directory of the application at run time. What this means is that,
to load the icon file in you application, you need to do:
QIcon *icon = new QIcon ("app/native/res/icon.png");
And, most importantly, you need to avoid changing the application's working
directory, otherwise it won't be able to find its resources. If you
have to change the working directory, then it's possible to work out
where the resources are installed by working upwards from $HOME and
the down again, but it's a bit ugly. You can't specify the absolute path
of any resource on the BlackBerry filesystem, because your application
has no control over where it is installed.
What applies to icons and resources also applies to libraries. To
pack the Qt library
libQtCore.so.4, you need to use
the command-line switch
-e /path/to/libQtCore.so.4 lib/libQtCore.so.4
and this will put the library into the BAR file in the location
and expand it into the PlayBook into the subdirectory
of the current working directory.
Note the implicit directory
native again. Then you need
to set LD_LIBRARY_PATH so that the application can find the
library and you need to tell Qt where to load libraries that it
loads dynamically. For the first task you can set LD_LIBRARY_PATH
using the <env-var> element in
needs to be:
<env var="LD_LIBRARY_PATH" value="app/native/lib"/>
For the second task, in your application you can do:
Notice the non-obvious mapping between the directory names you use as
blackberry-nativepackager, and the directory
names you application needs to use; note again the essential use of
relative pathnames for all these resources.
Working directory and $HOME
Just as on the Android platform, each application on the PlayBook has
seperate user identity. This separate identity is used to segregate
applications so that they cannot interfere with one another.
Applications can share files in the shared media area
/accounts/1000/shared), which is the same directory
that you see when mounting the PlayBook as a USB device. Even to use
that directory requires a specific setting in the
and the user will get warned about
it when installing the application.
Because each application has separate user identity, the environment variable
$HOME is constant only within the application. Each application will
see a different version of $HOME. At startup, $HOME
points to a directory that is readable and writable by the application,
and is a reasonable place to store configuration files and the like.
BlackBerry's impoverished platform
In many areas, the BlackBerry PlayBook is a stable, mature platform.
However, attempting to implement a file manager made me very aware,
very quickly, how much is missing in the platform, compared even
to Android, let alone to a desktop computer.
Most significantly for my purposes, applications cannot invoke one
another, except to the very limited extent provided by the
Navigator API (see below). There is no way to decide which application
will handle a particular type of file, even if the file is of a type
that the Navigator API recognizes (essentially media files, PDFs, and Docs2Go
docuemnts). Even media files are limited to the types that the built-in
media player can play. You can, for example, install an application that
can play FLAC files, but you can't launch it from a file manager, or even
the built-in file browser, because it's not something the media player
can handle. Android supports a method of inter-process communication
called 'intents'. This is very restrictive compared to what a desktop
application would expect to be able to do, but even that meagre
level of integration is missing in the
The PlayBook platform has very limited support for customization,
either programatic or by end-user configuration. On Android, for example,
it is possible to implement an alternative keyboard handler, or an alternative
lock screen, or screensaver. None of this is possible on the PlayBook.
The keyboard layout is particularly problematic for some applications — the built-in keyboard — which cannot be modified — has no arrow keys, no
tab key, no 'end' or 'home'. Any application that requires these keys
simply can't be implemented in an elegant way.
Consequently, in some areas, the PlayBook OS has the look of a beta product, or
a work in progress. Some of its limitations can be worked around; many
can't. I'm told that the BlackBerry 10 OS will address some of the limitations,
but that's not much help for PlayBook developers, since we have no idea
when, if any, this OS will be available for the PlayBook.
The Navigator is the name that BlackBerry uses for the application
launcher. I like the fact that the BlackBerry OS actually sees applications
as processes, which the user can explicitly start and stop. The Android,
OS makes it very inconvenient for a user to stop an application, either
because it's misbehaving or just because the memory could be better
used elsewhere. The application lifecycle is expected to be managed
entirely by the platform. On my Android tablet, when I click the
button to select between running applications, I see a huge list, some of
which I haven't used for months. The BlackBerry approach is more
The BlackBerry launcher provides an 'X' button to close an application. However,
with a Qt application, I've noticed that the application does not shut
down cleanly when the X is tapped. In particular, the
application's main event loop never
ends. The means that a lot of the cleanup code that is normally executed
when an application finishes will never get executed on the PlayBook.
If an application needs to save its state, in order to restore it
when it is next used, it will need to do it judiciously, during the life
of the application, and not rely on getting informed when the it is
being shut down. In effect, you have to code your application as if
the user could do 'Ctrl-C' on it at any time, without warning.
Deploying to the PlayBook
The NDK supplies a command-line deployment utility,
blackberry-deploy, which takes a
.bar file as
an argument. Both signed and unsigned applications can be deployed, but
to deploy an unsigned application requires building the application in
debug mode, and installing a debug token on the device, as explained
blackberry-deploy works, in principle, over a wireless network
or USB connection. However, I found that I was unable to get the USB
method to work in Linux. My Linux workstation recognized that the tablet
was plugged in, but was unable to find any driver for it. Wireless mode
worked fine, but only so long as the PlayBook was prepared to listen for
incoming network traffic. I suspect that the tablet tries aggressively to
conserve power and, even when it is docked and powered, it shuts down the
networking components when they are not in use. Therefore, sometimes it was
necessary to wake up the networking system by, for example, running the
tablet Web browser, before applications could be installed.
Deployment of an application with a minimum size of 6Mb is pretty slow — perhaps half a minute. This does make the process of making minor, iterative
tweaks to the user interface pretty painful. Such tweaks are necessary,
because it's rather hard to predict how the user interface will look and
feel on the tablet, based only on experience
with desktop programming for Qt.
By default, a Qt application running on the PlayBook looks like a
desktop application in a very small screen. To be useable, as a minimum
you'll need to increase the size of user interface elements like
scrollbars, buttons, and menu items. This
can be done declaratively using Qt stylesheets, which at
least means that you don't have to do a lot of coding to control the appearance of the application.
Judicious styling will give
you a desktop-style user interface with fat-looking controls. It's
workable, but not very sightly.
On the positive side, everything that you can do in a Qt user interface
in a desktop application
will work (after a fashion) on a Qt PlayBook application. You can create
a progress dialog box, for example, and use it to show the progress of
long-running operations. You don't need to do anything special to deal
with long-running operations that you wouldn't have to do in a desktop
application — so long as you continue to respond to user interface events,
things will tick along nicely. Anybody who has had to deal with the nightmare
of handling long-running operations in Android applications will surely
appreciate how much less painful it is the Qt way.
On the negative side, a desktop-style interface doesn't necessarily
suit finger-tapping tablet operation. If you create a
that is too long to fit on the screen then, by default, it will get a
scrollbar. But tablet users aren't really used to working with scrollbars — they expect to be able to drag lists around by swiping a finger.
There is no built in support for this kind of operation in the standard
Qt widgets. To be tablet-like, you'll need to define your own user interface
elements with the necessary additional logic, either by subclassing the
basic Qt widgets, or by applying custom event filters to them. For example,
it's relatively easy to implement kinetic scrolling by implementing an
event filter that will turn click and drag gestures into the necessary
scroller movements; examples of doing this can be found with a bit of
Qt implementation issues
Slightly separate from the issue of Qt look-and-feel is the issue of
how coding practice is inluenced by the
way the Qt port to BlackBerry was implemented. Most significantly,
the PlayBook has no window manager, and the Qt implementation has to
work around this lack. This has two obvious consequences
and, probably, some non-obvious ones that I have no yet discovered.
1. Windows and dialog boxes have no frames or captions, and cannot
be moved or sized by the user. All instances of
appear centered above their parent windows, and will stay there, since
there's no way to move them. If you need a window or dialog that is
user-moveable or user-sizeable, you'll need to implement the logic and
the associated user interface elements yourself. Dialog boxes don't get
a default 'close' button in the caption bar, since there is no a caption bar,
so will always need to be supplied with a specific 'close' or 'cancel' button.
2. Only a maximized widget or window will be resized when the screen
changes size or shape. If you set a fixed size, then that's what you'll
get. Since there is no window manager, there is no way for a user to
resize the window after creation. The screen will change shape when the
tablet is rotated between portrait and landscape orientation; it will change
size when the virtual keyboard rolls out. If you set a fixed-size
main window, then the virtual keyboard will roll out over the top of
it, obscuring any contents of the window. The solution is to show
the application's main window using the
function, rather than
show(). This caught me out, because
I can't think of a good reason ever to do this in a desktop application;
but in the PlayBook it's more-or-less essential, as only maximized
windows adjust to screen size.
Code signing and debug tokens
Only signed applications can be installed on real PlayBook tablets, and
submitted to the BlackBerry AppWorld site for end users to download.
Developers have to register with BlackBerry to get code signing keys,
although I found that process quick and painless. Signing can be done
by specifying particular arguments to the
utility, or applied to a built BAR file using the
blackberry-signer. However, the arguments you
have to use to
blackberry-nativepackager are different if
you plan to sign the application, than if you don't; so providing a
separate signing utility is not as helpful as it ought to be.
If you don't want to sign, you'll need to create a debug token, and
install it on the PlayBook and build it into your applications.
I confess that I was unable to figure out how to generate the certificates
that the signing utility needs, or the debug tokens,
using command-line tools. The
code signer looks for certificates in the directory
but the process for getting them there is not entirely clear.
In the end, I used the
IDE to generate the certificates for signing, and to create and install a
debug token, because this process, at least,
is well documented. This process only needs to be followed once; after that
you can use the same certificates to sign all applications.
I was somewhat surprised to find that a particular release of an application
can be signed only once. BlackBerry, presumably, keeps a record
of very signing request it responds to. I presume that the intention is
that you only sign the version that you plan to release to customers; for
all other purposes you make do with debug tokens. The problem with this
approach is that you can't distribute unsigned
BAR files in
such a way that anybody can use them — locking them to a specific debug
token means that unsigned BARs are for personal use only. So you can't
distribute early versions of your work to, say, friends and colleagues
for pre-release testing, unless you sign the BAR.
You can get around the signing limitation by incrementing the version
number of your application in the deployment descriptor every time you
sign but, to be honest, it's a bit of a pain.
I imagine that BlackBerry has taken steps to limit the distribution of
applications outside of the official AppWorld market to reduce software
piracy. Looking at the experience of Android developers, it's hardly
surprising that such a measure is necessary. However, their approach
creates a deal of inconvenience for developers.
Comparison with Android
I was rather surprised — gobsmacked, as we say round my way — that
you can't develop for the PlayBook in Java, except by targetting the
Android emulator. The emulator works — in fact, it works surprisingly well;
but it's slow to start up, and all emulated Android applications share
one window in the launcher. There's no doubt that you're using a foreign
application system. Moreover, the standard Android 'Home', 'Back', etc., buttons
are emulated in rather peculiar ways, using particular finger swipes.
This makes Android applications rather fiddly to use, until you get used
to these oddities.
This lack of Java support is peculiar because earlier
BlackBerry devices supported
Java — J2ME, at least. Arguably, the typical J2ME implementation
(usually the highly restrictive CLDC/MIDP variety) is not very suitable
for a tablet computer. Still, the lack even of this level of Java support
strikes me as rather peculiar.
It's never been very clear to me how BlackBerry sees applications being
developed for the PlayBook. Until the NDK was released, the only
(non-Android) way to develop applications was to use Adobe AIR — a technology really intended for embedding interactive content in
Web pages. I can see the appeal of AIR to developers — it supports
many different platforms with minimal code changes — but the idea of
developing a really substantial application with AIR seems to me about
as agreeable as walking on broken glass.
The fact that BlackBerry felt the need to release the NDK suggests that
it isn't just me who feels this way. However, I rather suspect that
the NDK is really intended for developers who want to port existing
OpenGL games; for such developers, the lack of any user interface
library is no problem, since the game will invariably include its own,
based presumably on libraries implemented with OpenGL primitives.
All this means that for developers of applications other than games,
there is no real equivalent of the Android Java-based development platform
Blackberry, except the Android emulator itself. If I wanted to implement,
say, a media player, an IRC client, a contact manager, an RSS feed
browser, or any one of the thousands of other non-game applications
available for Android, Qt is the only game in town. Unless, that is,
I wanted to dive into the murky pool of AIR.
Since Qt on the PlayBook is my platform of choice (or, perhaps, of
necessity), then a comparison with Java development on Android because
necessary, however different these development approaches might seem.
The most obvious difference in development is the difference between C++
and Java. For my part, I find these two languages more-or-less equivalent
in use. In fact, you can code in C++ for Android, but only in the form
of libraries with specific interfaces to the Java code. You can't
code a new user interface in C++ for Android, even should you want to.
Working with C++ on the PlayBook means more than just a different
programming language, it means a wholly different programming
In my experience, the biggest difference between BlackBerry (Qt) development
and Android development is that Android has a specific user interface
model, and applications have to use it. That user interface model is
pretty well-suited to tablet operation, and all the built-in user
interface widgets support pinch, flick, and swipe gestures. If you want
these things in your BlackBerry QT application, you have to code them
youself. The Android interface elements by default have sizes appropriate
for finger-poking, while Qt development requires a lot of tweaking to
get an effective look-and-feel. You could, in principle, use the
Qt-Quick progamming model with a Qt application. Qt-Quick is more
interface model is far more tablet-like than raw Qt. But if you're going
to go that way, I don't really see any advantage over Adobe AIR, and
there are none of the advantages (cross-platform support, for example).
The finished result
Here are some more screenshots of the finished file manager in action.
I won't be making my file manager available on the BlackBerry AppWorld site,
because the administrators require far more personal information than I'm
prepared to supply, just to give away my software for free. Anybody who
is interested can download the application (click here). And side-load it using the DDPB utilities. A link to
DDPB, and instructions for using it, are available
The main file browser screen. Note that the scrollbar width and minimum
height have had to be increased substantially from their defaults to make
them useable. However, this list supports kinetic ('flick') scrolling, via
a custom event filter, so there's no real need to use the scrollbar.
The toolbar buttons and menu items are also substantially increased in
size from their defaults. The white-on-black colour scheme looks more
tablet-like, and perhaps uses slightly less battery capacity.
Search results page. The user interface uses separate tabs, as a desktop
application might. However, the tab label height as a proportion of the
screen size needs to be larger.
The text editor. Astonishingly, the PlayBook has no built-in support even
for viewing text files. Fortunately, most of the editor logic already
exists within the Qt libraries, so adding this feature to an application
is relatively straightforward.