MTN App of the Year

How I built the best-selling BlackBerry app of all-time, BBSmart Email Viewer

Written by Neil Sainsbury

Many years ago, I built what I believe was the best-selling BlackBerry app of all-time,

It feels strange to write that, and it’s not something I’d say I’m really known for outside of the small niche community of BlackBerry app developers that used to exist. But of course this had a huge impact on my life and while there’s a lot I could say on the subject, there’s one aspect in particular that I’ve always wanted to write about – specifically, a technical trick that made the app work that very few other developers at the time could figure out.

I’m now 35 and enough years have passed that it’s finally time to talk about it! All my commercial interests in BBSmart are long expired, so I’ve put up the source code for BBSmart Email Viewer on GitHub, along with all the other apps I built as an independent BlackBerry app developer at my company, BBSmart (many of which were also very successful – just not as much as BBSmart Email Viewer). If you do take a look, try not to judge the code too harshly – this was the work of a 23yr old developer just getting started ­čÖé

What was BBSmart Email Viewer?

BBSmart Email Viewer was an alternative email-client for the BlackBerry. While the BlackBerry was renowned for being an email-centric device, the native email app left a lot to be desired – particularly when it came to the rendering of HTML emails: it simply couldn’t handle them and would choke, spitting up a mess of HTML tag soup. BBSmart Email Viewer had a lot of cool additional functionality (reply templates, notes, task/calendar integration, etc.) but its pi├Ęce de r├ęsistance was that it could render HTML email.

And while BBSmart Email Viewer was an alternative email-client, it also seamlessly in-situ replaced the native email client, losing none of the native functionality. This shouldn’t have been possible – not only where there no APIs available to even implement most of the core functionality needed for an email client, there were also no APIs to allow developers to swap out/substitute core apps like there exist today for Android, etc.

How did it work?

Hold up! Best-selling of all-time?

Yes! At least, I think so. At the time the mobile space was very different from today. Android didn’t exist and neither did the iPhone. There was no native “app store” on the BlackBerry and instead the places people went to buy apps were sites like MobiHand, Handango, and CrackBerry, or to preloaded carrier webstore bookmarks (eg. AT&T, T-Mobile, etc.). Because of the fragmented nature of sales, it’s hard to be definitively sure.

However, I have good reason to believe it was the best-selling BlackBerry app ever made.

BBSmart Email Viewer released in 2007 and immediately upon release jumped to the top of the best seller-lists everywhere. The app received a ton of press, glowing reviewsI was interviewed, etc. What was unique about the app however was it then stayed at the top of the best-seller lists (literally #1) on the major sites for 1 – 2 years (I didn’t keep track, exactly). For over a year BBSmart Email Viewer was, day-in, day-out, the best-selling BlackBerry app. The app also generated an enormous number of sales in to enterprise, including several 10K+ license purchases, and one mass deployment with a US carrier.

Because of the sales, I got to know the small industry of BlackBerry developers very well, and all the key players. Later after things wound down at BBSmart, I joined BlackBerry as part of the Developer Relations team and later still became the Director of Developer Relations at BlackBerry. Everything I learned and saw suggests BBSmart Email Viewer outsold everything.

The magic trick that made it all work – #1

So how did BBSmart Email Viewer replace the native email client seemingly on-the-fly? One interesting BlackBerry API I found when wandering around one day in the docs was that it was possible to register a listener for when the user opened an email in the native email client. BBSmart Email Viewer would do this on startup [1].

Session.addViewListener(this);

When a user then opens an email, the listener would fire its open event handler. Critically, from that handler, it was then possible to get a reference to the current UI stack via the call to UiApplication.getUiApplication() – Once you had that reference, you could do whatever you want with any screens in the current display stack. You could pop screens from the stack, push new screens on the stack, and grab any screen in the stack and dig in and modify any of the UI components on any screen (deleting them, replacing them, etc.).

This is a very dangerous and powerful. Because you could do this from pretty much any global event handlers, it was possible on the BlackBerry to truly build an app that could replace/update/modify any part of any application running on the device at any time. For example, theoretically, it would have been possible to create a global event handler that triggered regularly and woke up to check if the “HSBC Bank” app was running…and update the value in the “destination bank account” field if the user was on the transfer screen).

(Sidenote: I later used this ability to wake up regularly to build BBSmart Alarms Pro – a multi-alarm application. You could wake up via with one-minute resolution by registering a RealtimeClockListener [2])

Anyway, in my case, what I would do is get the underlying email being opened (sent with the original open event), format it, and then push an entirely new screen on to the display stack, essentially sitting on top/hiding the native email display screen which was still open in the background [3]

UiApplication.getUiApplication().pushScreen(

    new EmailViewScreen(m, formatter));

And of course, for my email display, I did a bunch of work to clean up the email contents to ahem un-fuck it [4], and then finally displayed the email contents in a HTMLField [5]

And when the user did finally close the email, I would pop both my screen and the old native email screen, so from the user’s perspective it was seamless and appeared like the native email screen was never launched:

private void exitToMessageList() {
// Close this and the previously opened
// email view screen
    UiApplication.getUiApplication().popScreen(
UiApplication.getUiApplication().getActiveScreen())   
    UiApplication.getUiApplication().popScreen(  
           UiApplication.getUiApplication().getActiveScreen());  
public boolean onClose() {
}    
    if (this.getScreenBelow() == mailScreen) {
        exitToMessageList();
    } else {
        close();
    }
    return true;
}

The magic trick that made it all work – #2

So at the end of this process, I now had my email display screen showing instead of the native email display screen. But that still left the problem of how to implement all of the native email functionality that no APIs existed for – like opening attachments to the email, replying, jumping to the next/prev unopened email, etc.

The key to enabling all this functionality from my own app was the BlackBerry menu. For those unfamiliar with the BlackBerry, there used to be a dedicated physical menu key you could press to bring up an “in-app menu” with all the global and contextual (depending on what was in-focus) menu options.

And of course, all these native email menu options existed in the native email application. So once again, leveraging the reference I had already obtained to the native screen, when a user in BBSmart Email Viewer selected “Reply”, I would get the reference to the native screen, from that get the reference to the native screen’s menu, and finally “invoke” the corresponding menu item. For example, here’s the definition of the “Reply” menu item from BBSmart Email Viewer [6]:

private MenuItem replyMenuItem = new MenuItem(replyMenuItemText, 0, 0) {
    public void run() {
        findDefaultMenuItem(“Reply”).run();
        if (UiApplication.getUiApplication().getActiveScreen()
                .getScreenBelow() != mailScreen) {
            close();
        }
    }
};
with findDefaultMenuItem [7] and mailScreenMenu [8] defined as:
private MenuItem findDefaultMenuItem(String name) {
    final int M_SIZE = mailScreenMenu.getSize();
    MenuItem item;
    for (int i = 0; i < M_SIZE; i++) {
        item = mailScreenMenu.getItem(i);
            return item;
        }
    }
    return null;
}
mailScreen = UiApplication.getUiApplication().getActiveScreen();
mailScreenMenu = mailScreen.getMenu(0);

And voila! With careful management of the native email menu, BBSmart Email Viewer was able to offer all the functionality available in the native email app.

And so it goes…

Many developers could not figure out how BBSmart Email Viewer worked – I used to get an email every few weeks or so from people asking how the app worked, but of course, I never told anyone. Having said that, some other developers also did work it out and my app was eventually copied (almost verbatim in look, feel, and functionality) by another developer. To make the app a real success then still relied on a lot of grit, late nights, regular updates, marketing, great customer communication, business relationships, and all the usual things you have to do to be successful in business.

Nonetheless, I still think back and laugh every now and then at this silly little technical trick that changed my life.

HAVE YOU READ: Top 3 mobile app development trends to watch out for in 2021

Source: www.neilwithdata.com

Share:

Share on facebook
Facebook
Share on twitter
Twitter
Share on pinterest
Pinterest
Share on linkedin
LinkedIn
Get The Latest Updates

Subscribe To Our Monthly Newsletter

Sign up today for the latest news in one weekly email, plus occasional event updates, direct to your inbox