post

Q10 too fast ? why you need UNDO functionality

If you’re NOT developing for BlackBerry 10 platform perhaps your users are complaining apps running too slow.

Speedy Q10

On BlackBerry 10 you have to think ahead because apps are running so incredible fast – esp. using Keyboard devices like Q10 – that you run into situations not thinking about on a ‘normal’ smartphone.

You speed up users workflow using shortcuts:

E → 12 → enter

and you’re done with:

  • tip on E to edit the quantity of an order position
  • new page opens
  • curser already in quantity field
  • keyboard switched to numeric mode
  • type 12 as new quantity
  • tip on ENTER key
  • new quantity saved
  • page closed
  • list summary recalculated

this is an intuitive and fast way to work with business apps on a smartphone.

And sometimes it can be too fast ;-)

DeleteAction on Z10 (Touch)

As a good citizen of Cascades UI design guidelines you’re using a special ActionItem to delete a row in a list or so:

DeleteActionItem {
    id: deletePositionAction
    title: qsTr("Delete Position") + Retranslate.onLanguageChanged
    ActionBar.placement: ActionBarPlacement.InOverflow
    onTriggered: {
        // delete the position
    }
}

Delete actions are always placed at the bottom of your menu. Here’s how it looks like on a Touch Device:

menu

To get something deleted you have to do a first tap to get the menu:

overflow-menu-on-Z10

then you have to tap on the delete action:

delete-on-Z10

there’s enough time to decide what to do and you have to tap directly on the delete action, so normaly you don’t ask the user “do you really want to delete this item ?”

DeleteAction on Q10 (Keyboard)

Now on Q10 the situation is different using shortcuts. You must know that Cascades automatically maps some actions to keys – and this will work in all applications without the need for you to code this by yourself. If a user on the Q10 taps on the menu, then the keyboard shortcuts become visible:

menu_marked_keys

the DEL – key is mapped to the Delete Action. automatically.

the E – key is mapped to the Edit Quantity Action by me as a SystemShortcut:

SystemShortcut {
    type: SystemShortcuts.Edit
}

Because I want to edit something, I’m using one of the SystemShortcuts instead of my own custom ShortCuts.

Now we enter the dangerous area ;-)

detail_on_device

If the user tips on the DEL key here, the delete action will be triggered. without any warning. perhaps it was the wrong key and the user wanted to type P or ENTER.

You have to find a way to avoid this.

Undo – the user-friendly solution

Normaly converting apps from Touch (Z10) to Keyboard (Q10) is easy and soon done – but you should carefully test your app on Q10 to find hidden traps.

What can you do to avoid deleting a record by accident ? the easiest way would be to insert a yes/no SystemDialog and always ask if the record should be deleted. But now you’re breaking the users workflow. not so good.

here’s one solution:

  • on Z10 use it as before
  • on Q10 add an Undo function

Undo must be implemented a way not breaking users flow. There is a UI control you can use for this: Cascades SystemToast: a small popup window going away after a short time. And here’s my solution:

If DeleteAction is triggered, test if you’re on a keyboard device and if so, don’t execute the delete logic. Instead of this I’m changing the Icon of the list row and bring up a Toast with the same icon and some text to inform the user.

SystemToast {
    id: deleteToast
    body: qsTr("Position will be deleted") + Retranslate.onLanguageChanged
    icon: "asset:///images/position_to_be_deleted_small.png"
    position: SystemUiPosition.BottomCenter
    button.label: qsTr("Undo")
    onFinished: {
        if(deleteToast.orderId > 0){
            if (value == SystemUiResult.ButtonSelection) { 
                // UNDO clicked - revert to normal Icon in this case
            } else {
                // do your DELETE stuff
            }
        }
    }
}

undo_on_device

Now it’s up to the user:

  • if DEL was done by accident click on the Undo button an all will change back to normal
  • if DEL is what user wants to do simply follow the workflow – ther Toast will disappear automatically

From my POV this is an elegant way to solve this situation: user has full control and workflow not broken :)

The Video

here’s a short video where you can see how it works before and after:

Some tips for developers implementing such a solution

Toasts will go away after a short time, but you cannot set this delay. Toasts with a button will remain on screen until user does some work on UI, which will start the countdown until Toast disappears. In some situations this is too long for me, so I want to dismiss the Toast per ex. if user triggers another action, clicks the back button or something else.

cancel() on a Toast will stop and hide the toast immediately. cool. or not ? If Toast is canceled means, user has NOT clicked the Undo Button, so the data can be deleted.

But cancel() doesn’t trigger the onFinshed() at Toast. with a little trick this will work:

add a boolean property ‘killed’ to the Toast, fire this if you cancel() the Toast and now onKilled() at the Toast can execute the same delete- businesslogic as onFinished() from TimeOut.

I will publish some code on this later and will also add this pattern to my workshops on Cascades, because you’ll need this all the time in business apps.

Have fun with Q10

If you need an App: I’m developing quality BlackBerry10 APPS for customers around the world ;-)
If you want to write such kind of apps by yourself: You can book a training (in german or english)

ekke

post

OpenDataSpace on Q10

OpenDataSpace just got some updates: most important one is the support of BlackBerry Q10 with physical keyboard.

We also added an Action to ApplicationMenu: FAQ, where you find answers for your questions or can add new questions.

Here are some screenshots, so you can imagine how it looks on the Q10.

Screenshots on the device are made using Heiko Behrens ShapeItApp

Login into OpenDataSpace:

ods-login-q10

Some DataRooms and Content listed on Q10:

ods-datarooms-q10

ods-dataroom-content-q10

All the functionality from Touch devices like Peek-back are also available on Q10 of course:

ods-peek-q10

As you can see, on Q10 OpenDataSpace is using a dark theme, where on the Z10 we’re using the bright one. It’s recommended to use a dark theme because of the OLED and will give you more battery power.

OpenDataSpace now also has specific Images as Scene Cover if minimized (running in background):

ods-minimized

OpenDataSpace is available from BlackBerry World

the app is FREE and there’s also a FREE account from ods for up to 5 users and 2 GB Data Space.

Sources are available at Github (Open Source)

OpenDataSpace is Built For BlackBerry

BuiltForBlackBerry

post

Conference2Go EclipseCon is BuiltForBlackBerry certified

great news:

my Conference2GoEclipseCon Application now is Built For BlackBerry certified :)

Z10-on-appworld

BuiltForBlackBerry

Conference2Go EclipseCon is available from BlackBerry World

post

Conference2Go JAX

Conference2Go JAX is the new Conference APP for attendees of JAX conferences.

jaxcon-app-minimized

You can download this app from BlackBerry World

c2g jax in bb world

BlackBerry 10 FLOW

This article will demonstrate how Conference2Go will be used by Conference attendees. Perhaps you already heard about BlackBerry 10 Flow – but what does this FLOW of seamless integrated workflows mean ? Will this have an impact on the way how to develop mobile Applications ?

Conference2Go APPs are an example and I will explain it. I attended uncount developer conferences in germany and worldwide so I know the requirements and tried to solve as much as possible.

Before you go to the conference

Download the Application

First step of course is to download the application from BlackBerry World.

If you’re wondering about the size of 9 MB – there are some high qualitiy images inside to enable you to zoom into floorplans. Also a first version of data will be delivered with the app, so you don’t have to wait for first initializing the app throught the web. Conferences always have international speaker and attendees, so I want to avoid to transfer a huge amount of data where some attendees are in roaming or expensive hotel wifi or slow conference wifi. Conference2Go later only needs a small amount of traffic to get some updates.

Settings (Calendar, Remember, Foursquare)

If starting the application the very first time, you’ll get a Tip-of-the-day telling you about some settings you should do:

first-start

Settings are placed in the Application Menu you reach if swiping down from top bezel:

c2g-jax settings

Conference2Go is integrated with the native BlackBerry Calendar: your private schedule can be synced with Calendar Entries and you get the comfort of collision detection if sessions are overlapping. If you would like to use these features, you have to enable the sync: check the box and select your Calendar:

c2g-sync-with-calendar

Conference2Go stores the selection and now uses your selected Calendar to add / remove Sessions and to test against for Collisions.

Conference2Go is also integrated with native BlackBerry 10 Notebooks (Remember App) where you can store all your notes about sessions and more. If you’re using a Notebook from Evernote, then all your notes are synchronized with Evernote, so you have access from other devices and your desktop.

I’m always creating a special Notebook for each conference – so perhaps it’s a good idea at first go to your Remember APP and create a new notebook (Folder) for JAX 2013:

my notebooks

Now from Settings select your Notebook:

c2g-set-notebook

Last step is the Connection to Foursquare. Conference2Go is connected App and if you always have running Foursquare on your BlackBerry10 device, you can use Foursquare without a new login. Connecting your Foursquare Acoount with Conference2Go is easy: In Settings there’s a button to do this: Conference2Go then goes to your Account and asks you if you want to allow Conference2Go to use it:

foursquare-connected

Conference2Go only uses Foursquare to do CheckIns or to search for some criteria near the Conference venue.

Now your settings are configured :)

Navigate through the Conference days

It’s a good idea to create your personal schedule before going to the conference. JAX 2013 is a huge conference:

  • 180+ speaker
  • 220+ sessions
  • 30+ tracks
  • 24 special days
  • 14 rooms
  • 3 main conference days (tuesday -thursday)
  • 2 extra days (workshops, special days on monday / friday)

here’s an overview from the website of the conference:

uebersicht-from-web

HowTo manage this on a small device ? a real challenge !

Here’s my solution on BlackBerry 10 developed as native app with cascades.

The most important part of the conference – the main conference – is reached directly from Conference2Go Home screen.

At the bottom there are the most important Tabs:

c2g-tabs-on-home

tapping on Sessions will give you the sessions from Tuesday to Wednesday. Tap on a day and you’ll see all sessions of this day ordered by starting time.

c2g-main-conference

Also available directly from Home are the workshops:

c2g-tabs-on-home

Tapping on Workshops gives you the workshops and also some sessions of special days happening on Monday or Friday:

c2g-monday-friday

If Sessions or Workshops are opened the Tab Bar shrinks and only displays the selected one at bottom left.From there you can navigate through all main components of Conference2Go and here you’ll find more ways to find your sessions and get an overview.

Besides the Sessions and Workshops there are also Tracks and Special Days and infos about Speaker:

c2g-sidebar

Tapping on the Tracks you get a list with all tracks of the conference:

c2g-tracks

Each session can be connected to one or more tracks. For each Track you see how many sessions will happen on which days.

Tap on the List Item of the Track you’re interested in and you’ll see a list of the sessions available for this track.

The list is ordered by starting time and from top you can select the day.

c2g-track-sessions-by-day

Same is for the Special Days. Tapping on Special Days from Tab- Sidebar you’ll get the list of all Special Days:

c2g-special-days

Then it’s the same as for the tracks: tap on a line to see the sessions – also sorted by starting time and by day.

Now you know where to find the sessions for

  • Main Conference (Tuesday – Thrursday)
  • Extra Days (Monday and Friday)
  • Tracks
  • Special Days

If you’re interested into the speakers at JAX – there’s a special listing of all Speakers:

c2g-speakerlist

For a conference like JAX 2013 this is a long list, so I added a Search.

Tap on Search from ActionBar at Bottom and type your search criteria:

c2g-speaker-search

Now it’s up to you to find your favorites:

Configure your schedule

You have seen there are different ways to navigate to a specific session from main conference, workshop, tracks or special days.

If you want to get more informations on a session simple tap on the list row and you’ll get a Session Detail page:

c2g-session-detail

From this details page you see all the categories belonging to this session, the type (Session, Workshop, keynote), the room and you can read the session abstract.

At the bottom of the page you’ll find the list of Speakers for this Session.

You want to add this session to your Favorites to get it into your personal schedule ?

There’s a toggle Button in the ActionBar: “set as favorite” (or remove as favorite if you change your selections.

Sessions marked as Favorite will get a small flag to visualize the status.

Your Session Lists also have a toggle to see all sessions of the selected day or only the favorites.

Here you see a list of sessions only for favorites:

c2g-show-favorites

From ActionBar you can toggle to see all sessions again – so you can switch easy.

The Overflow Menu (bottom right) gives you an option to see sessions from your list in a special Overview Page.

Here you see the Sessions you flagged as Favorite. As you can easy see both will be in room “Goldsaal C” and from timeline you see the start and duration of the sessions.

c2g-overview-flagged

The size of the Overview Page depends on your selections and you can pinch and zoom with your fingers and move the content around.

BTW: the complete page will always be created on demand dynamically and Cascades does a great job: rendering is very smooth and fast.

Here are some more samples what you can get from the Overview:

c2g-overview-01

c2g-overview-02

c2g-overview-03

c2g-overview-04

Using this Overview Page it’s easy…

  • to locate your sessions (which rooms)
  • to see what happens at the same time (Timeline)
  • where are free slots
  • to recognize your Favorites (flagged)
  • to look at special days or tracks.

From the Overview page you can also tap on a session and get the details and directly from there to set / remove as Favorite.

If you have enabled synchronization with Calendar, Conference2Go automaticalle adds your Favorites to the selected Calendar:

c2g-calendar-entries

It comes even better: there’s another cool feature helping you doing your schedule. Jumping back and force between days and tracks and special days and marking sessions as your favorite, it may happen that you’re loosing the overview and you run into collisions if marking more then one slot as Favorite .

As soon as you tap on “Select as Favorite” you’ll get a warning:

c2g-calendar-warning

Now you can decide:

  • Cancel ? From the title of the overlapping Session you know that you want to give this session priority
  • Manage the Collisions ? You’re not really sure and want to take a look at the overlapping session(s)
  • Set as Favorite ? Perhaps you’re only collecting Sessions and want to decide later, then Tap on this and go on

You decided to manage the collsions ? Then you’ll get a special Overlay Page:

c2g-overview-overlapping

Now you can tap on the Sessions, study the details and set/remove as Favorite :)

Istn’t this comfortable ?

At the JAX 2013 Conference

CheckIn with Foursquare

Conference2Go is integrated with Foursquare – so it’s a good idea to checkIn at JAX 2013. Using Conference2Go this is a one-tap-action from Home Menus or Venue Tab to get this:

foursquare-checkin

Explore the Conference Center (Venue)

From Home Menus or Venue Tab you can explore the Conference Venue.

venue-tab

You need the Loaction of the Conference ? Locate the Convention Center (Orte das Convention Center) opens the location in BlackBerry Maps. From there you can also easy search what’s nearby: Restaurants, Hotels, …

c2g-location-map

Where are all the rooms ? There’s a List with Floorplans and Images for each Room:

c2g-list-of-rooms

The list is grouped by Floorplans and sorted by Rooms inside Floorplans.

You can tap on a Floorplan to get the image:

c2g-floorplan

If you tapped on a Room, you get this Room marked with a red arrow:

c2g-room-of-floorplan

In all these images you can zoom-in and zoom-out with your fingers. (In fact the image was viewed using BlackBerry 10 ImageViewer, but thanks to Invocation Framework it feels like inside the app.)

Twitter is also integrated and if you’re interested into Tweets using the conference Hashtag #eclipsecon, you can do so from venue Tab and you’ll get the list from the native Twitter APP:

c2g-tweets

Attending Sessions

From the Session Detail Page you can do more then only setting as Favorite.

c2g-session-detail-options

Because Twitter is integrated, you can easy tweet about the session you’re attending. As you see it’s also easy to add an image to the tweet. All of this INSIDE the Conference2Go APP :)

c2g-tweet-from-session

At the Bottom of the Session Detail Page you’ll find the Presenters. Tapping on a Presenter you’ll get the Speaker Bio:

c2g-speaker-bio

If the Speaker has provided a Twitter Account, a Tweet@Speaker Action becomes visible and you can directly mention the Speaker:

c2g-tweet-from-speaker

From Session Detail you can also take a look at the Room Location:

c2g-room-from-session

it’s easy to zoom into the details with your fingers:

c2g-room-from-session-zoomed

For me at conferences there was always aproblem: HowTo write my notes, where to store images and more for a specific Session and HowTo remember at home and HowTo get it on my desktop. Using my MacBook isn’t always comfortable in crowded rooms without tables, so I would prefer to do it all only from my mobile.

Conference2Go makes this easy :)

BlackBerry 10 has a native app to manage notebooks on your BlackBerry 10 device. These Notebooks can besynchronized with Evernote and Evernote is available for all platforms.

Thanks to Cascades Invocation Framework I can integrate Remember (Evernote) into my application. Now from a Session Detail page with a simple Tap I can create an Entry in my Conference Notebook. The Title is the name of the Session and I can type my notes. I can even add or capture Audio, Images, Video or add attachments.

c2g-notebook-entry

From venue Tab there’s also a special list of all my Notes I added for this conference, so it’s easy to edit them and perhaps add a audio.

c2g-session-notes

At Home

When you’re back from the conference at home, all your Notes from the conference are already waiting for you.

Don’t delete the app – you’ll get updates for the next JAX conference.

You like this app ?

jaxcon-app-minimized

If you like this app, there are some options to help spread the word on this:

home-options

  • You can invite others to BBM (BlackBerry Messenger is integrated)
  • You can leave a Review (BlackBerry World is integrated)

Need feedback

If you find bugs or have some ideas HowTo make the app better, from ApplicationMenu you can send feedback to me as eMail:

c2g-feedback

Have Fun with Conference2Go

If you need an App: I’m developing quality BlackBerry10 APPS for customers around the world ;-)

If you want to write such kind of apps by yourself: You can book a training (in german or english)

ekke

——————-

hint: BlackBerry Push Services will be added soon and be integrated for next JAX / W-JAX conference

post

Conference2Go EclipseCon

Now my first Conferecne2Go APP for BlackBerry 10 is available at BlackBerry World:

Conference2Go EclipseCon

Z10-on-appworld

Search for ‘EclipseCon’ at BlackBerry World and download this app for FREE.

Thanks to Cascades Invocation Framework seamless integrated with

  • BBM
  • BlackBerry World
  • Foursquare
  • Twitter
  • Remember (Evernote)
  • MediaPlayer
  • ImageViewer

… to provide BlackBerry 10 FLOW

Read more about this app from my blogs, where you’ll also find many scereenshots:

EclipseCon and BlackBerry 10

Conference2Go APP at BlackBerry World

there’s also a first Video available:

http://vimeo.com/ekkescorner/c2g-eclipsecon

Download and have fun !(runs on Z10, DevALpha, Q10)

it’s FREE and there will follow more Conference Apps for BlackBerry 10: JAX, W-JAX, MTC, …

stay tuned…

post

TeaTimer and Q10

Please read at first my story ‘Behind the scenes‘.

TeaTimer should run on Touch and Keyboard devices, so I just did a first implementation and here are my experiences.

Redesign Layout Homescreen for Q10

Q10 has less space available: 720×720 instead of 768×1280. It’s worth rethinking the layout. Some screens worked out-of-the-box, but the startscreen got a redesign for Q10.

first decisions:

  • Moving the DropDown on top over the images
  • Making the ActionBar as Overlay to avoid distortion of images.

q10-layout-01

You have to reserve 96 Pixel for the DropDown UI Control.

If you expand the DropDown, it doesn’t use the complete space of the screen – only 50% were used from my experiences. Setting  the height to a higher value doesn’t work. My first idea to make the Images invisible if DropDown is expanded, doesn’t look good with only half screen occupied by the DrowDown.

My solution: move the Image 360 px down (TranslateY) and all is perfect. I also hide the ActionBar to only display the DropDown where the user has make his/her choice.

q10-layout-02

To avoid flickering I’m reusing the DropDown area to show the progress while brewing the tea and placed a ‘Stop’ button to cancel the process:

q10-layout-03

Here are the Screenshots how it looks now on BlackBerry Q10:

Homescreen with Tip-of-the-day:

tip-of-the-day

Selecting Tea (DropDown expanded):

select_tea

Animated progress of brewing:

progress

Tea is ready:

tea_thanks

That’s it !

Most Screens working out-of-the-box

All other screens are working without any changes. the secret to get this: use of

  • ScrollView
  • ListView
  • DockLayout

Here some examples:

tea_list

tea_details

Minimized Views (ActiveFrame / SceneCover)

As you know, the TeaTimer is running in the background and minimized Screens have three states: stopped, brewing, ready.

Thanks to the tips from Staffan Lincoln I already have changed the minimized views for Z10 using the ‘Header’ template, so minimized is also working out-of-the-box for me:

all_minis

Text is readable inside Header and it’s ok only to see 50% of the Images compared with Z10.

More work ?

As soon as I’m getting the DevAlpha C I will add some more comfort for the keyboard using shortcuts. But for now I’m having an App supporting both devices.

As soon as the update is approved in BlackBerry World you can update on Z10 or install on Q10 if you’re one of the lucky owners.

Have Fun !

Cascades Trainings

BTW: there will be some Cascades trainings by me in April 2013. Come and learn HowTo develop cool apps for Z10 and Q10.

post

SerCar10 – a new way to manage ServiceCars

the product website is online:

http:// sercar10.com

post

OpenDataSpace is Built for BlackBerry certified

great news:

my OpenDataSpace Application now is Built For BlackBerry certified :)

ODS APP

BuiltForBlackBerry

OpenDataSpace is available from BlackBerry World

and all Sources are OpenSource at Github.

post

AllAboutMy B-101

AllAboutMy B-101 is a simple WebViewer Application:

You get direct access to the blog of a canadian BlackBerry Fan:

screenshot-all-about-my-b

post

ekkes TeaTimer – behind the scenes

even the smallest utility app should follow the BlackBerry 10 Design Guides

… to provide the cool UX of this platform.
as you probably know, I just switched my main device from i to z and I’m searching to find all the apps I need for my Z10 to be satisfied.

one of these (for me important and) useful apps is a Tea Timer and I looked around at BlackBerry World, but didn’t found a TeaTimer providing BlackBerry 10 UX.

so I decided to develop my own ;-)

here’s a short video to get first impressions:

edited: 2013-03-07 (begin)

I got really valuable feedback from Staffan Lincoln (Designer at TAT/Cascades) and changed the minimized views (ActiveFrame / SceneCover) and also replaced the animated Slider by an own custom animation – of course all using Cascades. (see below some more infos)

here’s the new Video demonstrating minimized Views and new animations:

http://vimeo.com/ekkescorner/teatimer-anmimations

edited: 2013-03-07(end)

You like it ?

ekkes TeaTimer for Z10 + DevAlpha at BlackBerry World

ekkes TeaTimer is available at BlackBerry World:

teatimer-qrcode

I started this app small (only counting a timer) but after some days of work I realized that even in this small app I’m using all concepts and frameworks of BlackBerry10 Cascades Apps.

So I got the idea to use this app as a case study to demonstrate to other users and developers what’s important to develop a BlackBerry 10 Quality App and to provide the unique BlackBerry 10 UX.

While thinking about this the next idea was born: I will use the TeaTimer as a template to develop another app, which can be used in my Cascades Trainings and also an upcoming BlackBerry Cascades book. The TeaTimer is a .99 $ app, but be prepared that next months there will be an OSS (Apache 2 licensed) sister project (egg-cooking-timer) helping you to understand how it works and to follow my trainings and the book.

The documentation of Cascades is really good and you’ll find many sample apps and cascades-projects and cascades-community-projects at Github. But you know: if you’re working on real-world-apps then all the samples are only samples and you always miss some more infos or the glue code between different parts / samples. The goal of my trainings is to fill this gap and to help you to create cool and outstanding apps with Cascades.

OK  – let’s take a look …

… behind the scenes of ekkes TeaTimer:

teatimer-behind the scenes

UI Design Guide

most important if developing BlackBerry 10 applications: follow the design guidelines. perhaps it’s some more work for you but your apps will be seamless integrated into the BlackBerry 10 UX.

for me it doesn’t matter if developing a small utility like this one or a complex business application for customers: they all are following the UI Design guidelines.

following the guidelines is also a first step to get your APP as certified ‘Built for BlackBerry‘. I got this certification for my OpenDataSpace App.

Now let’s go through some parts of the TeaTimer APP and see what I did there to follow the BlackBerry 10 UI Design Guides and to develop a TeaTimer different to others.

BTW: all my previous apps are using the light theme – TeaTimer will use a dark theme.

Portrait / Landscape

In all my applications I’m always trying to have all (or most) screens available in Landscape and Portrait because from my POV an APP should not dictate the users HowTo hold the device ;-)

Sometimes it’s easy and you have to do nothing – sometimes it’s more difficult or even impossible. here are some samples from ekkes TeaTimer:

screen_02

screen_08

I decided to use an image of 720×720 which will fit perfect for Z10 from width in portrait, height in landscape and also Q10. In Portrait the DropDown is placed below the image and in Landscape besides. I’m using a DockLayout and put all the fields without the images into a Container.

Container {
    id: descriptionContainer
    layout: DockLayout {
    }
    verticalAlignment: VerticalAlignment.Fill
    horizontalAlignment: HorizontalAlignment.Fill
    translationY: 720
    translationX: 20
    // which tea ?
    DropDown {
        id: brewSelected
        objectName: "brewSelected"
        title: qsTr("selected Tea:") + Retranslate.onLanguageChanged
        visible: true
        verticalAlignment: VerticalAlignment.Top
        horizontalAlignment: HorizontalAlignment.Center
        translationX: -20
        translationY: 0
        preferredWidth: 720
        onSelectedValueChanged: {
            teaPage.teatime = selectedValue
        }
        onExpandedChanged: {
            if (expanded) {
                teaPage.actionBarVisibility = ChromeVisibility.Hidden
                stoppedLabel.visible = false
            } else {
                teaPage.actionBarVisibility = ChromeVisibility.Visible
                stoppedLabel.visible = true
            }
        }
    }
	// some more fields .....
} // end descriptionContainer

Now it’s easy to move the Container around, to re-align the DropDown and even have some more space for DropDown-Title in Portrait:

function reLayout(orientation) {
    if (orientation == UIOrientation.Landscape) {
        descriptionContainer.translationY = 0
        descriptionContainer.translationX = 720
        brewSelected.horizontalAlignment = HorizontalAlignment.Left
        brewSelected.translationX = 0
        brewSelected.title = qsTr("selected:") + Retranslate.onLanguageChanged
        brewSelected.preferredWidth = 720 - 160
		// more stuff
    } else {
        descriptionContainer.translationY = 720
        descriptionContainer.translationX = 20
        brewSelected.horizontalAlignment = HorizontalAlignment.Center
        brewSelected.translationX = -20
        brewSelected.title = qsTr("selected Tea:") + Retranslate.onLanguageChanged
        brewSelected.preferredWidth = 720
		// more stuff
    }
}

Hint: in Portrait I noticed if the DropDown was placed on the bottom of the Page even inside a ScrollView the expanded DropDown was partially invisible under the ActionBar, so I hide the ActionBar if DropDown is exanded. positive side-effecrt: the user only sees the important thing: the options of available Teas.

Another hint: if you’re using long-running animations as I’m doing with the images (see below) be aware: if orientation changes the animation is stopped, so you have to freeze the orientation while animation is running or to save and restore the values.

To be a good citizen in Portrait and Landscape isn’t always an easy job for your app – I will go into the details at my trainings.

ApplicationMenu

Swipe down from the top bezel and there should be your ApplicationMenu. Place Help, Settings or seldom used functionality there.

ekkes teaTimer added to the ApplicationMenu:

  • Help
  • About
  • List of Teas
  • Settings

TeaTimer AppMenu

Don’t forget: if you open a Menu from ApplicationMenu you have to disable this Menu or the complete ApplicationMenu until the User goes back !

Implementing these Menus I used some different technologies:

  • Help gives the user access to a Video (using InvocationFramework – MediaPlayer)
  • About opens a website (using Cascades WebView)
  • List of Teas is a ListView with a JSON datasource bound to a GroupDataModel
  • Settings are stored using QSettings. AccountService was used to select default Notebook. InvocationFramework was used
    • forFourSquare OAuth
    • to give easy Access to Notifications – Settings

MediaPlayer (through InvocationFramework)

Invoking the MediaPlayer is easy done. (You already found examples on this in my Open Source Github project at BlackBerry ‘OpenDataSpace‘.

void ApplicationUI::invokeBoundMediaPlayer(const QString& uri) {
	mUsecase = Usecase::MediaPlayer;
	InvokeRequest cardRequest;
	if (uri.startsWith('/')) {
		cardRequest.setUri("file://" + uri);
	} else {
		cardRequest.setUri(uri);
	}
	cardRequest.setTarget("sys.mediaplayer.previewer");
	mInvokeManager->invoke(cardRequest);
}

Using the InvocationFramework the user doesn’t know that you’re calling another APP – it’s integrated into the TeaTimer and you can “peek back” or Go Back by a tap:
teatimer-help-mediaplayer

I created this Video to explain the APP to the user. Of course before starting the MediaPlayer rthe user gets the info that the Video will be played from Internet, so he/she can cancel to avoid traffic.

WebView (About…)

To include a site from the web you simply use a WebView. Put this WebView inside a ScrollView where scrolling in both directions is enabled, also enable PinchToZoom. There are some signals like onLoadProgressChanged(), where you easy can ad an ActivityIndicator to show the progress while the Page was loading.

The WebPage is seamless integrated into the app now – no use of a Browser:

WebView

List of Teas (JSON, GroupDataModel, ListView)

Some more infos HowTo provide data see below. Here’s how the ListView is looking:

List of Teas

In most cases I’m not using standard ListItems, because it’s easy to create custom ListItems. In this case we have an Image, Description and BrewingTime. One Tea can be marked as your favorite Tea – in this sample ‘Assam’ wher you see the Image with the CheckMark. You can now Add, Delete or Edit entries. If you tap on one Item you get this Page with the details:

List item details

There’s a TextField for the description, a switch (ToggleButton) to select you favorite Tea and a DateTime Picker to set the brewing time. If you change the value of the Switch, the Images right beside the Switch will also be changed automatically.

Let’s take a look at the DateTimePicker, because handling of dates isn’t always easy.

DateTimePicker {
    id: timePicker
    preferredWidth: 720
    topMargin: 24
    title: qsTr("Duration")
    mode: DateTimePickerMode.Timer
    minimum: timePicker.dateFromTime("00:00:30")
    maximum: timePicker.dateFromTime("00:30:00")
    onValueChanged: {
        duration = Qt.formatDateTime(value, "mm:ss");
        // .....
    }
}

TimePicker

Some important things to note:

  • DateTimePickerMode.Timer must be used to get the hh – mm – ss values
  • minimum / maximus are set to avoid that the user does enter wrong values, also we cannot suppress the hours, but we have to be sure that no hours are entered. using min/max is an easy way to solve this.
  • onValueChanged() gives us the time as value and we can use the built-in Qt.formatDateTime functions to format the value

Last thing to know: HowTo set the Value from your bound DataModel ? we have stored the brewing time as ‘mm:ss’ – the Picker needs ‘hh:mm:ss’ and we can set the value this way:

timePicker.value = timePicker.dateFromTime("00:"+data.duration)

In this case we used the dateFromTime() you can use for a Timer Picker.

Settings (QSettings)

The easiest way to store your settings is using QSettings. All values will be stored in the data directory of your app sandbox:

sandboxes/<your-app>/data/settings/<your-vendor-name>/<your-app-name>.conf

here’s the C++ code to get stored values:

QString TeaSettings::getValueFor(const QString &objectName,
		const QString &defaultValue) {
	QSettings settings;
	// If no value has been saved, return the default value.
	if (settings.value(objectName).isNull()) {
		return defaultValue;
	}
	// Otherwise, return the value stored in the settings object.
	return settings.value(objectName).toString();
}

and here’s a screenshot of the TeaTimers Settings:

settings

Settings (Remember – Notebook – Evernote)

I integrated to BlackBerry 10 Notebooks. Notebooks are part of the Remember APP and can be local Notebooks or Evernote Notebooks. Notebooks are an easy way to remember things and while preparing the Tea to be brewed perhaps you notice that you have to buy some new Tea. ekkes teaTimer makes it easy to create an entry for a Notebook. If you’re using the Remember APP with Notebooks heavy (as I’m doing) it would be nice to pre-select the Notebook where you want to store the entries and perhaps also some Tags. Tags are stored in QSettings – also the default Notebook.

To have access to a Notebook you need tqo keys: <Account-Key> and <Notebook-Key>.

There are some Services we have to use:

bb::pim::account::AccountService
bb::pim::notebook::NotebookService

Now we can ask the NotebookService for a list of all know Notebooks.

QList<Notebook> nl = mNotebookService.notebooks();

Here’s the List of Notebooks:

list of notebooks

From this list you have access to all informations you need, like:

Notebook n = (Notebook) nl.at(i);
providerDisplayName = as.account(n.id().accountKey()).displayName();

Store the AccountKey and NoteBookKey in your settings and you have all we need later to invoke this Notebook (see below)

Settings (Foursquare SSO – InvocationFramework)

Next Settings are for Foursquare. What the hell am I doing with Foursquare inside a TeaTimer you may ask ?

If I’m on-the-go and want to know where’s the next place to buy Tea or to drink a cup of Tea, Foursquare is my friend, always knowing some cool places nearby. So why not integrating Foursquare to get the places with one tap ? Thanks to Kyle Fowler (@kfow35) it’s really easy to integrate Foursquare.

There’s a Github project and using SSO (SingleSignOn) you only need to make your connection between your app and Foursquare once. Then you get an OAuth token, store this token inside your (secured in sandbox) settings – data and use it invoking the Foursqueare App. (see below)

Invoking Foursquare SSO from C++:

void ApplicationUI::onFoursquareSSO() {
	mUsecase = Usecase::FoursquareSSO;
	InvokeRequest cardRequest;
	cardRequest.setTarget("com.foursquare.blackberry.sso.card");
	cardRequest.setAction("bb.action.VIEW");
	cardRequest.setMimeType("sso/foursquare");
	cardRequest.setData(mFoursquareClientId.toUtf8());
	mInvokeManager->invoke(cardRequest);
}

Foursquare SSO

Then from CardDone Message you can extract the Token to be stored:

QString myToken = doneMessage.data().split("\"").at(1);
if (!myToken.isEmpty()) {
	mTeaSettings->saveValueFor(SETTINGS_KEY_FOURSQUARE_TOKEN, myToken);
}

To connect your App with Foursquare at first you have to go to Foursquare Developer Site and register your APP there.

Then you’re gitting two codes:

  • ClientId
  • Client secret

store these codes – there are some calls where you need them as above invoking onSSO().

Hint: while registering your app at Foursquare you’ll be asked for a redirect URL, for BlackBerry10 you have to enter:

http://localhost

Settings (Notifications)

As soon as the Tea is ready we have to notify the User. As a good citizen it should be easy to set the application-specific Notifications.

We’re using the InvocationFramework to do this. In QML we have a Button on the SettingsPage:

Button {
    id: settingsButton
    topMargin: 48
    preferredWidth: 720
    text: qsTr("Settings: Notifications") +Retranslate.onLanguageChanged
    onClicked: {
        app.invokeSettings("settings://notification")
    }
}

Clicking this Button will call this C++ code:

void ApplicationUI::invokeSettings(const QString& uri) {
	mUsecase = Usecase::Settings;
	InvokeRequest request;
	request.setAction("bb.action.OPEN");
	request.setTarget("sys.settings.target");
	request.setMimeType("settings/view");
	request.setUri(uri);
	mInvokeManager->invoke(request);
}

Animations

Most timers are only using a countdown. If you prefer such kind of a timer, it’s already built into the BlackBerry10 OS Clock:

built-in timer

I wanted to use some other kinds of animations. You probably know the Cascades Sample Lightning Crossfades where you have a slider and using this slider you can manually fade from one image to a second image.

My solution:

I shot 8 images from my Teapot showing the steps to brew tea:

empty Teapot → Tea strainer used → filling in hot water → brewing → pulling out Tea strainer → Tea ready:

states to bre tea

So I have 7 transitions between images. All images are placed ‘on top’ which is easy done in a DockLayout:

ImageView {
    id: image1
    imageSource: "asset:///images/tea-timer-01a.png"
    verticalAlignment: VerticalAlignment.Top
    horizontalAlignment: HorizontalAlignment.Center
    preferredWidth: 720
    preferredHeight: 720
    opacity: 1.0
}

the first image with  the empty Teapot has opacity of 1.0 and all the others 0.0, so they’re invisible.

I’m using a SequentialAnimation where each transition has a duration of 1/7 of brewing time.

SequentialAnimation {
    id: brewingAnimation
    repeatCount: 1
    animations: [
        FadeTransition {
            target: image2
            fromOpacity: 0.0
            toOpacity: 1.0
            duration: teaPage.teatime / 7
        },
        FadeTransition {
            target: image3
            fromOpacity: 0.0
            toOpacity: 1.0
            duration: teaPage.teatime / 7
        },
        // and so on
    ]
    onEnded: {
        // Attention: don't use onEnded !
        // won't be triggered if app minimized !
    }
}

Now it becomes difficult: normaly if an animation reaches the end, there’s an onEnded() signal where you can do your stuff. We cannot use this signal, because we want to run our App in the background and if brewing time is finished, we have to notify the user. So: don’t use onEnded() in this case !

As always with Cascades and Qt there’s a solution – in this case attach a QTimer:

QTimer {
    id: timer
    interval: teaPage.teatime
    onTimeout: {
        teaPage.teaReady()
    }
}

Start this Timer together with your animation. QTimer also runs if your app is in the background – so you’ll get the Signal that brewing time is finished.

Fading through the Images is nice, but the User should have an information about the progress. For this I’m using a Slider.

Next question was: HowTo move the Slider on ? There’s no Animation on Sliders. As you can see from the SequentialAnimation above the fading was done changing the Opacity – and that’s the key: there’s a signal from opacity-changes, so you can calculate the value of the slider:

ImageView {
    id: image2
    // more properties
    opacity: 0.0
    onOpacityChanging: {
        brewSlider.value = 12.5 + (12.5 * opacity)
    }
    onOpacityChanged: {
        brewSlider.value = 25.0
    }
}

Now we got it: Images are fading from Image 1 … 8 while the Slider is moving forward.

slider-progress

Hint: Of course the user should not be able to move the Slider manually, but on the other side if you disable the Slider it doesn’t look good. I simply placed a 9-slice-image with transparent pixels on top of the slider.

How animation works if the App is minimized and running in the background see below.

begin edited: 2013-03-05

While this works and is looking nice – it’s a mis-use of the Slider. The user normaly expexts to drag a Slider back and force, what’s not possible here because the Slider is a progress indicator and set by the application. Lesson learned after some discussions with Cascades – Designers: never use a UI element in a wrong way – even if it works, it’s a brake of the rules.

In some other applications and also while loading the WebView of the About Page I’m uising a ProgressIndicator, but in this Utility app it should look different.

So I did a custom animation: a trolley with a box of tea is moving from left to right and below a counter displays the remaining time. I solved this with Sequential and ParallelAnimations and some more work at QTimer. I will write another blog on this – here you can see how it looks like now:

custom progress

end edited: 2013-03-05

Hope you get an idea what you can do with Cascades animations and Qt Signals / Slots to create a cool UI / UX.

You need the details ? Come to one of my trainings.

Dialogs, SystemToast

Cascades provides some System dialogs – I already used many kinds of SystemDialogs, ProgressDialogs and SystemToasts in my OpenDataSpace app. Please take a look at the code in Github.

A typical SystemDialog looks like this one:

dialog

For the TeaTimer I added another usecase for a SystemToast: ‘Tip-of-the-Day

Every time the user starts the application, he/she will get another Tip-of-the-Day like this one:

Tip of the Day

This SystemToast has an Icon, Text and an OK Button. Clicking OK or doing something else will hide the SystemToast. From Settings the user can suppress these Tips. Using SystemToasts this way it’s easy to give your users some kind of help or additional informations.

Deliver and store data

It should always easy for users to start with your app. So it makes sense to deliver some data and enable the user to modify the data.

In this case I have some sorts of tea together with brewing times predefined. Cascades and JSON are working together very smooth, so my list of teas is stored as a JSON inside the assets folder of the app. This JSON datamodel looks like this:

tea data

To enable the user to change this list (add new entries, edit descriptions or brewing times) you have to copy this file from the assets folder (read-only) into the data folder of your app sandbox. so the data is hidden for the FilePicker and can only be accessed by the app and will be deleted from the phone if the app will be deleted.

Here you can see how I’m getting the data from JSON into the DataModel bound to the ListView:

void TeaTimerData::initTeaSorts() {
	QVariantList dataList;
	dataList = readDataFromJson();
	mTeaDataModel =
			Application::instance()->scene()->findChild<GroupDataModel*>(
					"teaSortsDataModel");
	if (mTeaDataModel) {
		mTeaDataModel->clear();
		if (!dataList.isEmpty()) {
			for (int i = 0; i < dataList.size(); ++i) {
				QVariantMap map = dataList.at(i).toMap();
				Tea* tea = new Tea();
				tea->setValues(map);
				mTeaDataModel->insert(tea);
			}
		}
	}
}

Because users will only change tea sorts seldom, I placed the ListView into the ApplicationMenu. the user can also mark one tea as his favorite, which will be selected after opening the app. at the main page of the app the user sees a drop down box where he/she can select the tea easy. description and brewing time are displayed as description.

Running in the background (SceneCover, Notifications)

Users shouldn’t have to wait for a task to be finished. While the Tea is brewing they should do other things and be notified when the Tea is ready.

To solve this we have to think about

  • SceneCover: what should be visible if the App is minimzed
  • Notifications: HowTo notify the User

Minimized Apps normaly display a scaled-down screenshot from your app – but it’s much better to design the minimzed View by yourself using a SceneCover.

SceneCovers can be used from QML: attach a ComponentDefinition:

ComponentDefinition {
    id: appCover
    source: "AppCover.qml"
}

The SceneCover itself is defined inside the source (in this case AppCover.qml):

SceneCover {
    property alias displayText: brewingText.text
    property alias displayColor: brewingText.textStyle
    property alias displaySource: imageBrew.imageSource
    content: Container {
        Container {
            layout: DockLayout {
            }
            background: Color.Black
            ImageView {
                id: imageBrew
                imageSource: "asset:///images/tea-timer-cover-stopped.png"
                verticalAlignment: VerticalAlignment.Center
                horizontalAlignment: HorizontalAlignment.Center
            }
            Label {
                id: brewingText
                horizontalAlignment: HorizontalAlignment.Center
                verticalAlignment: VerticalAlignment.Center
                translationX: 40
                translationY: -20
                multiline: true
                text: qsTr("Timer\nstopped")
                textStyle.color: Color.Black
                textStyle.fontSize: FontSize.Large
            }
        }
    }
}

You see we’re using an ImageView and a Label. SceneCovers are only refreshed every 30 seconds, so it doesn’t make sense to animate 8 Images as we have done running the APP in the foreground.

I’m using 3 different states only:

  • TeaTimer stopped
  • Tea brewing
  • Tea is ready

as you can see here:

scene_cover_states

using the Properties (see QML code above) it’s easy to change the Image, Text and TextColor

Application.cover.displayText = qsTr("Tea\nready !") + Retranslate.onLanguageChanged
Application.cover.displaySource = "asset:///images/tea-timer-cover-ready.png"
Application.cover.displayColor.color = Color.Red

begin edited: 2013-03-04

Thanks to Staffan Lincoln (@stlin_tat ) I got some valuable input from a designer HowTo provide better looking SceneCovers.

  • avoiding red color for text (Tea ready is a success – message and shouldn’t be in red)
  • placing text on top of images isn’t recommended
  • text as a one-liner is faster to read

There’s a Header Template described at UI Design Guidelines – I tried it and really: looks much better now:

Scene Cover v2

The good thing: now it’s also easier to use this for the Q10 – layout  (less changes needed).

Thanks Staffan ! (BTW: if you ever get a chance to attend a Designer + Developer session by Staffan Lincoln and Johan Larsby it’s really worth to go)

… submitted new version to BlackBerry World.

end edited: 2013-03-04

What about the Notification ? At first I tried to notify the user with QML-code only. Was no problem to create a Notification and notify the user.

Notification was also shown in Message HUB, but I didn’t found a way to add the InvokeRequest to the Notification from QML. InvokeRequest is needed if the User should be able to open the TeaTimer APP directly from the Notification inside the HUB – so I did it in C++:

void ApplicationUI::sendNotification() {
	Notification n;
	n.setTitle(tr("Your Tea is ready"));
	n.setBody(tr("Tap 'Open' from ActionBar to go directly to ekkes TeaTimer"));
	n.setCategory("vibrate");
	setInvokeRequestToNotification(n);
	n.notify();
}
void ApplicationUI::setInvokeRequestToNotification(
		bb::platform::Notification& notification) {
	mUsecase = Usecase::Notification;
	InvokeRequest request;
	request.setTarget("org.ekkescorner.ekkesTeaTimer");
	request.setMimeType("application/vnd.ekkescorner.teatimer");
	notification.setInvokeRequest(request);
}

don’t forget to add the required code in your bar-descriptor.xml. You should use a app-specific Mime-Type !

    <invoke-target id="org.ekkescorner.ekkesTeaTimer">
      <type>APPLICATION</type>
      <filter>
         <action>bb.action.OPEN</action>
         <mime-type>application/vnd.ekkescorner.teatimer</mime-type>
      </filter>
    </invoke-target>

Now from the Notification inside the HUB you can directly jump into your app.

notify

notification in hub

jumped-into-app

Hint: Be a good citizen of BlackBerry10 and always clear effects and notifications if your APP exits – per ex. user closes from minimized app. I’m doing a manual exit because of this.

BBM

It’s a good practice to integrate BBM into your application. Using BBM it’s easy to tell others about the APP – so you get free advertising by your satisfied users.

actions

I also included the Invite to BBM if users want to talk about your app with contacts not been connected via BBM.

And there’s another BBM – integration with ekkes TeaTimer: if Tea is ready and you want to tell this to your collegues / family / friends – it’s now so easy:

Here’s the code to tell others that the tea is ready:

Action in QML:

ActionItem {
    title: qsTr("BBM: Tea is ready") + Retranslate.onLanguageChanged
    imageSource: "asset:///images/chat.png"
    ActionBar.placement: ActionBarPlacement.InOverflow
    onTriggered: {
        app.shareTextWithBBM(qsTr("Fresh tea is waiting for you") + Retranslate.onLanguageChanged)
    }
}

Invocation from C++:

void ApplicationUI::startChat(const QString& text) {
	mUsecase = Usecase::BBM;
	InvokeRequest bbmRequest;
	bbmRequest.setTarget("sys.bbm.chathandler");
	bbmRequest.setAction("bb.action.BBMCHAT");
	bbmRequest.setData(text.toUtf8());
	mInvokeManager->invoke(bbmRequest);
}

and here’s the screenshot how it looks like:

bbm - tea ready

InvocationFramework

We have already seen some parts of the app where I’m using the InvocationFramework. The InvocationFramework is one of the coolest things of BlackBerry 10 and I recommend to use it: your users will get a seamless way to solve their workflows without switching between apps. I also recommend that you provide functionality of your APPs to others, if this makes sense for your use-cases. If you’re thinking about this: please provide Cards where possible and not only Open or Share functionality. …and if you’re providing Cards, try to use Viewer – then users can “peek-back”. I know it’s a kind of re-thinking app-development and it’s not so easy to give away functionality from your app “for-free” to other developers, but it’s really worth thinking of it. (and doing it)

Now let’s see how I intergrated Foursquare as a 3rdParty app and Remember-Notebooks as a native BlackBerry10 OS – App. We have already seen above HowTo do some settings for this.

Foursquare (3rdParty APP integrated)

You’re on-the-go and want to get easy access to places where to buy tea or to drink a cup of tea.

We’re doing this with onVenueSearch() from Foursquare:

void ApplicationUI::onVenueSearchCard() {
	mUsecase = Usecase::FoursquareVenueSearch;
    InvokeRequest cardRequest;
    cardRequest.setTarget("com.foursquare.blackberry.venuesearch.card");
    cardRequest.setAction("bb.action.VIEW");
    cardRequest.setMimeType("venuesearch/foursquare");
    QUrl uri = QUrl("foursquare://venues/search");
    QString token = mTeaSettings->getValueFor(SETTINGS_KEY_FOURSQUARE_TOKEN, "");
    if(!token.isEmpty()){
    	uri.addQueryItem("oauth_token", token);
    } else {
    	uri.addQueryItem("client_id", mFoursquareClientId);
    	    uri.addQueryItem("client_secret", mFoursquareClientSecret);
	}
    QString foursquareQuery = mTeaSettings->getValueFor(SETTINGS_KEY_FOURSQUARE_QUERY, "");
	if(!foursquareQuery.isEmpty()){
		uri.addQueryItem("query", foursquareQuery);
	} else {
		uri.addQueryItem("query", "Tea");
	}
    cardRequest.setUri(uri);
    mInvokeManager->invoke(cardRequest);
}

If you take a look at the code: we’re doing a CARD request. If the user has connected our APP with the Foursquare APP we use the token – if not we’re using the ClientID and SecretCode we got from registering the app with Foursquare. Using the token Foursquare will present a more-user-specific query result.

If the user has added keywords for the query in Settings we also use this – otherwise we simply put ‘Tea’ in as query.

This Query will give us a list of Venues nearby:

tea places
This Card comes in as a Composer – so user cannot peek back. I already requested some wishes at this Cascades-Forum-Thread.

If the User clicks on one entry, we can open directly from our APP this venue in Foursquare APP, where user can do a Check-In.

// from CardDoneMessage:
JsonDataAccess jda;
const QVariantMap venueMap =
		jda.loadFromBuffer(doneMessage.data()).toMap();
QString venueId = venueMap.value("id", "").toString();
if (!venueId.isEmpty()) {
	onOpenVenue(venueId);
}
//
void ApplicationUI::onOpenVenue(const QString &id) {
	mUsecase = Usecase::FoursquareVenueOpen;
    InvokeRequest cardRequest;
    cardRequest.setTarget("com.foursquare.blackberry.uri");
    cardRequest.setAction("bb.action.OPEN");
    cardRequest.setUri("foursquare://venues/"+id);
    mInvokeManager->invoke(cardRequest);
}

Remember APP (Notebooks / Evernote integrated)

I’m already a long-time Evernote user and so I’m really happy that Evernote is one of the BlackBerry10 Notebook providers.

Using BlackBerry10 Remember APP and Evernote I can easy transport informations from my phone to my desktop.

I’m doing this if reading Tweets on-the-go and later on my MacBookPro I want to read again.

Inside ekkes TeaTimer I can easy write a Notebook entry to be remembered to buy some Tea.

Invoking this is again easy done:

void ApplicationUI::addNotebookEntry(const QString& selectedTea) {
	mUsecase = Usecase::Notebook;
	InvokeRequest request;
	request.setAction("bb.action.ADD");
	request.setTarget("sys.pim.remember.composer");
	QString title = tr("Buy Tea");
	QString description = tr(" is empty");
	QString uri = "title=" + title + "&description=" + selectedTea + description;
	QString lastEntry = mTeaSettings->getValueFor(
			SETTINGS_KEY_NOTEBOOK_ACCOUNT_KEY, "") + ":"
			+ mTeaSettings->getValueFor(SETTINGS_KEY_NOTEBOOK_KEY, "");
	if (lastEntry.length() > 1) {
		uri += "&notebookid=";
		uri += lastEntry;
	}
	QString tags = mTeaSettings->getValueFor(SETTINGS_KEY_NOTEBOOK_TAGS, "");
	if (!tags.isEmpty()) {
		uri += "&tags=";
		uri += tags;
	}
	QString s = QUrl::toPercentEncoding(uri, "{}=&:,");
	request.setUri("remember://notebookentry?" + s);
	mInvokeManager->invoke(request);
}

most important is creation of correct URI. If user has selected a default notebook we add the AccountKey:NotebookKey, if user has added Tags, we add the Tags. Also the URI must be correct encoded !
The user gets this Page directly integrated into TeaTimer app without leaving the app:

notebook entry

Notebook (Folder) was selected, Title was set, also a description and the Tags. Wasn’t this easy ?

BlackBerry World Reviews (the easy way)

It should be easy for your users to leave a review for your APP at BlackBerry world.

HowTo integrate this:

void ApplicationUI::leaveReview() {
	mUsecase = Usecase::BlackBerryWorld;
	InvokeRequest bbWorldRequest;
	bbWorldRequest.setAction("bb.action.OPEN");
	bbWorldRequest.setMimeType("application/x-bb-appworld");
	bbWorldRequest.setUri("appworld://content/24367895");
	qDebug() << "leave review";
	mInvokeManager->invoke(bbWorldRequest);
}

Now the user will be directly sent to your AppWorld Page to leave his/her review:

IMG_00000147

Tip of the Iceberg

This is the end of my short walk through a small Utility App like a TeaTimer ;-)

This was only the Tip of the Iceberg…

iceberg

…but I hope you got some ideas for your own apps HowTo

  • make them good citizens of BlackBerry 10
  • follow the Cascades UI Design Guidelines
  • give your users a seamless FLOW
  • get satisfied users
  • differentiate your BlackBerry 10 apps from other-platform-apps

Have fun.

Get the right trainings and relax

Writing Cascades APPs for BlackBerry 10 enables you to create awesome applications.

New to BlackBerry 10 ?

New to Cascades ? C++ ? Qt ? QML ?

dont panic

I went the hard way through all the Betas from the early beginning of BlackBerry 10 and first Cascades Betas more then a year ago.

But I’m not sitting on my experiences and knowledge – you can participate: I’m writing blogs, articles like this one, speaking at conferences and there will be Cascades Workshops:

cascades-traning

If you attend both workshops (Basic: 3 days + Experts: 2 days) you’ll be able to write applications like this one !

You’ll go home with sourcecode and tips and tricks.

If you’re not tired – there are even night-coding-evenings with beer and food that week !

Register here for the next training ! attend….

relax-cool

…and relax !

edit 2013-03-10: there’s a follow-up article TeaTimer and Q 10

Follow

Get every new post delivered to your Inbox.