BBM Step by Step

advertisement
Integrating with the BBM Social
Platform, One Step at a Time
Brian Zubert
Team Lead, Developer Relations
bzubert@rim.com
July 19, 20111
BlackBerry Messenger Community
Experiencing explosive growth
•45+ million global BBM subscribers
•
>70% of BBM users use it daily
•
>2 million new users per month
•
>2 thousand new users per hour
•
>100 billion BBM messages sent per month!
•BBM community is there when it counts
•
300% lift in traffic after winning goal at World Cup finals
2
BBM Social Platform
What is it?
• Gives apps access to the enormous user base of BBM
• 3 Major API Areas:
•
•
Access BBM contact list
Access and update user profiles
• Including app-specific area, where anything goes
•
•
Enable in-app chat
(and a 4th):
•
Share files such as pictures, voice notes, videos and music.
3
BBM Social Platform
Supported Platforms
•Backwards compatible: Supports OS 5.0 and above
•Support for BlackBerry Java Applications
•Support for BlackBerry WebWorks Applications
http://us.blackberry.com/developers/choosingtargetos.jsp
4
BBM Social Platform
Where do I get it?
•Releases
• Java release is gold!
• WebWorks release is in beta!
•Get updates:
• BlackBerry Developer’s Blog - http://devblog.blackberry.com/
• @BlackBerryDev on Twitter
• BBM Dev Page - http://www.blackberry.com/developers/bbm/
5
BBM Registration
BBM Registration
• Registration is the first step!
•
•
Requires user’s permission
Requires a new class that extends
BBMPlatformApplication
• (does not replace UIApplication)
7
BBM Registration - Java
• Create your BBMPlatformApplication class
public class MyBBMAppPlugin extends BBMPlatformApplication
{
public MyBBMAppPlugin()
{
//UUID is a unique identifier used for the test environment
super( "Insert your UUID here" );
}
}
8
BBM Registration - Java
• Create your BBMPlatformContextListener class
public class MyBBMPlatformContextListener extends BBMPlatformContextListener
{
public void accessChanged(boolean isAccessAllowed, int accessErrorCode)
{
if (!isAccessAllowed)
{
// You cannot access the BBM platform, handle this situation here, disable features, etc.
}
}
public void appInvoked(int reason, Object param)
{
// Code for handling different contexts for invocation such as user invite, profile click, etc.
}
}
9
BBM Registration - Java
• Register your app
MyBBMAppPlugin myPlugin = new MyBBMAppPlugin();
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
//The platformContext variable will need to be saved and used
//throughout your application. It should be an instance or static variable.
BBMPlatformContext platformContext =
BBMPlatformManager.register(myPlugin);
MyBBMPlatformContextListener platformContextListener;
platformContextListener = new MyBBMPlatformContextListener();
platformContext.setListener(platformContextListener);
}
}
);
10
BBM Registration - WebWorks
document.onload = function()
{
//onAccessChanged *must* be defined *before* a call is made to register.
// Invoked when application access status changes (such as a successfully registered app):
blackberry.bbm.platform.onAccessChanged = function(accessible, status)
{
if (status === "allowed")
{
//Access is allowed: complete any steps that make use of the BBM APIs which
// would normally occur during a pageLoad event which:
blackberry.bbm.platform.io.onConnectionCreated = function(event, connectionType, connection,
param)
{
// ...
}; } };
//The onAccessChanged method will be called after a registration request.
// If successfully registered, the status will be "allowed“.
blackberry.bbm.platform.register( { uuid: “0cee5bbb-cee9-3bd4-8e3a-4d3247301e38" } );
//Don't make any further calls to BBM APIs in the onload event after a call to register.
// The BBM SDK will call the onAccessChanged method if this app is successfully registered.
}
11
BBM Registration
• If the user clicks Decide Later
•
•
You can not ask the user again
The user must grant permissions via the
BBM Options screen
12
Working with Contacts
Viral Distribution
Viral Distribution
• What is Viral Distribution
Use of a social network to increase brand awareness or other
marketing objectives
• The natural spread of a product, service or marketing material
through peer to peer interaction
•
• Key Components:
A compelling product
• Empowered users
• A strong medium
•
• Leverage the already familiar BBM chat interface for app recommendations to friends
14
The BBM Advantage
• Millions of users
• 45+ million users
• Tightly connected with friends, family and coworkers
• Instant communication
• Push-based communication system
• Delivery and Read notices
• Carrier agnostic
• Free to use
• Free to implement
15
Invite to Download
• What
•
Allow users to invite their friends to
download your app
• Why
•
Leverage the social graph exposed by BBM
to grow your user base
• How
•
Very simple!
• Just one method call to initiate the whole process!
16
Invite to Download
• A single API call that performs the
following:
• Contact Picker is displayed
• User selects a contact
• User confirms contact
• The invitee receives a message on
BBM inviting them to download the
app.
17
Invite to Download
What the inviter sees
What the invitee sees
18
Invite to Download (Java)
MessagingService messagingService =
platformContext.getMessagingService();
messagingService.sendDownloadInvitation();
Reminder: the object ‘platformContext’ was provided upon registering with the service.
19
Invite to Download (WebWorks)
var result =
blackberry.bbm.platform.io.inviteToDownload(onComplete);
20
Working with Contacts
Sharing with BBM Contacts
Sharing with BBM Contacts
• What
•
Sending a message or file to BBM contacts
• Why
•
•
Share the application experience with BBM contacts
who do not have the app.
Get them interested in the content, and maybe they
will download the app!
• How
•
Simple API calls for each messages and files.
22
Sharing with BBM Contacts
• Sending a message
• User can select a contact to message
• App can pre-populate text
• User must confirm / complete the sending
of the pre-populated text
– Prevents spamming of users friends
• App is hyperlinked in the conversation for
identification and easy access
Java
platformContext.getUIService().startBBMChat("Hello!");
WebWorks
blackberry.bbm.platform.users.startBBMChat(onComplete, "Hello");
23
Sharing with BBM Contacts
• Sending a file
•
•
•
App or user can select a contact
App or user can select a file
User must confirm file transfer
Java
platformContext.getMessagingService().sendFile(
contact, filePath, “See my file sent from BBM SDK
Demo!");
WebWorks
blackberry.bbm.platform.io.sendFile(filePath, “See my
file sent from BBM SDK Demo!”, onFailure, contact);
24
Working with Contacts
Listening for Contact List Changes
Listening for Contact List Changes
• What
•
Receive notification when a user’s contacts change
status, picture, name, etc.
• Why
•
Integrating these values into your app will allow it to
truly behave as if it’s part of the BBM network.
• How
•
Implement the PresenceListener (Java)
• or onUpdate listener (WebWorks)
26
Listening for Contact List Changes
• The listener notifies on updates to:
•
•
•
•
•
•
Display name
Display picture
Personal messages
Status
App installation/uninstallation (Your app only)
Receipt of application invite
27
Listening for Contact List Changes
28
Listening for Contact List Changes
Java
public class MyBBMContactListScreen implements PresenceListener
{
public MyBBMContactListScreen(BBMPlatformContext platformContext)
{
platformContext.getContactListService().setPresenceListener(this);
}}
•
Implement the PresenceListener interface and set it as a listener
for the service:
WebWorks
blackberry.bbm.platform.users.onUpdate = onUpdate;
•
Set the onUpdate event listener to your own onUpdate method
29
Listening for Contact List Changes
Java
• Implement PresenceListener.presenceUpdated
public void presenceUpdated(BBMPlatformContact contact, int eventType)
{
final String str = "[" + getEventName(eventType) + "] was changed by " +
contact.getDisplayName();
Dialog.inform(str);
}
private String getEventName(int eventType)
{
switch(eventType)
{
case PresenceListener.EVENT_TYPE_DISPLAY_PICTURE:
return "Display picture";
break;
case PresenceListener.EVENT_TYPE_DISPLAY_NAME:
return "Display name";
break;
default:
return “Other event";
}
}
30
Listening for Contact List Changes
WebWorks
• Implement onUpdate
function onUpdate(user, event)
{
switch (event)
{
case "displaypicture":
var src = user.displayPicture;
break;
case "displayname":
var name = user.displayname;
break;
case "personalmessage":
var msg = user.personalmessage;
break;
case "status":
var status = user.status;
var statusMessage = user.statusMessage;
break;
}
}
blackberry.bbm.platform.users.onUpdate = onUpdate;
31
Working with Contacts
Inviting Users to BBM via PIN
Inviting Users to BBM via PIN
• What
•
Add to your users’ social graph when PINs are
available.
• Why
•
Allows your users to add friends via PIN if that
information is available
• How
•
Call the appropriate method and pass it the list of
PINs to invite.
33
Inviting Users to BBM via PIN
•
•
•
Users can have address book contacts that
have PIN information
Your app may already be using PINs
Create a community around your
application
• Allows anonymous users to interact and,
if a friendship is formed, add them to
each others contact list.
• Users are more likely to return to your
app to interact with their new friends
• Users will remind others of your app via
invitations
34
Invite Session Participants to BBM
Java
BBMInvitationRequest requests[] = new BBMInvitationRequest[1];
Requests[0] = new BBMInvitationRequest(“2100000A”, “Nicole”);
UIService.inviteToBBM(requests)
WebWorks
var users = blackberry.bbm.platform.users;
var invitations = [
new users.ContactInvitation("2100000A", “Nicole"),
];
blackberry.bbm.platform.users.inviteToBBM(onComplete, invitations);
35
The User Profile and Profile Box
In-App User Information
In-App User Information
• Add profile information to your app
•
•
•
•
Instant personalization
Customize your application with
profile information
Complements the Presence Listener
Add in-app awareness of user status
• The user is busy? Maybe reduce notifications, sounds,
etc.
• Apply busy status to own in-app network
37
In-App User Information
• Instant access to:
•
•
•
•
•
Display Name
Display Picture
Personal Message
Status (Available/Busy)
Status Message
38
In-App User Information
Java
UserProfile userProfile = platformContext.getUserProfile();
String displayName
Bitmap displayPicture
String personalMsg
int status
String statusMsg
=
=
=
=
=
userProfile.getDisplayName();
userProfile.getDisplayPicture();
userProfile.getPersonalMessage();
userProfile.getStatus();
userProfile.getStatusMessage();
39
In-App User Information
WebWorks
var userProfile
= blackberry.bbm.platform.self;
var
var
var
var
var
=
=
=
=
=
displayName
displayPicture
personalMsg
status
statusMsg
userProfile.displayName;
userProfile.displayPicture;
userProfile.personalMessage;
userProfile.status;
userProfile.statusMessage;
40
The User Profile and Profile Box
Update Your Users’ Status
Update Your Users’ Status
• Elements of the User Status
field
Personal Message
• Available/Busy Status
• Custom Status Message
• Display Picture
•
42
Update Your Users’ Status
• What
•
Set your users status on their behalf with
their permission
• Why
•
Raise awareness of your users activities in
your application
• How
•
Simple!
• Basic getter/setter design pattern
43
Update Your Users’ Status
• Update the user status with:
Java
UserProfile userProfile =
platformContext.getUserProfile();
userProfile.setStatus(Presence.STATUS_BUSY, “Gone
Fishing!”);
WebWorks
function onComplete(result) {
//result = true/false if user allowed the change
}
blackberry.bbm.platform.self.setStatus("busy", “Gone
Fishing!", onComplete);
44
Update Your Users’ Personal Message
• Update the user personal message
with:
Java
UserProfile userProfile =
platformContext.getUserProfile();
userProfile.setPersonalMessage(“Feeling Good!”);
WebWorks
function onComplete(result) {
//result = true/false if user allowed the change
}
blackberry.bbm.platform.self.setStatus("Feeling
Good!", onComplete);
45
Update Your Users’ Display Picture
• Update the user display Picture with:
Java
UserProfile userProfile =
platformContext.getUserProfile();
userProfile.setDisplayPicture(Bitmap OR EncodedImage);
WebWorks
function onComplete(result) {
//result = true/false if user allowed the change
}
blackberry.bbm.platform.self.setDisplayPicture(“URI",
onComplete);
46
The User Profile and Profile Box
Custom Profile Boxes
Custom Profile Boxes
• Apps can add profile boxes to the user profiles
•
Consists of an icon and text
• Benefits
•
•
•
•
Increase user engagement
Spreads awareness of your app amongst contacts
Can be fun or informative for users and their peers
Links back to your application
48
Custom Profile Boxes
• Features
• A field that appears on a users profile
•
•
•
•
•
screen.
Visible to all BBM 6.0 users
Can contain an icon and text
Clicking the box launches your app
If the app isn’t installed, takes the user to
the app page in BlackBerry App World
Maximum of 3 activities per app
49
Custom Profile Boxes
Java
UserProfile userProfile = platformContext.getUserProfile();
UserProfileBox profileBox = userProfile.getProfileBox();
if (profileBox.isAccessible()) // Ensure that we have permission to access
the box
{
// Each icon used by your application must have a unique ID
int iconId = 1;
EncodedImage icon =
EncodedImage.getEncodedImageResource("smiley.png");
profileBox.registerIcon(iconId, icon);
profileBox.addItem(iconId, "Always Happy!");
}
50
Custom Profile Boxes
WebWorks
<script type="text/javascript">
// Add an item with icon, text, and a cookie
var iconObj = { id:1, uri:"local:///profilebox/smiley.jpg"};
var options = {
text
: “Always Happy!”,
iconID : iconObj,
cookie : “Always Happy Profile Box”
};
blackberry.bbm.platform.self.profilebox.addItem(options);
</script>
51
Custom Profile Box Security
•
What’s stopping an app from filling your profile
with unwanted content?
Opt-in security
• Users must enable the functionality in the BBM
Options
• Must be specified for each application
•
•
Next release: a popup style permission box can be
launched in-app
52
Removing Profile Boxes
• Profile boxes persist indefinitely unless
•
•
•
•
•
Specifically removed by the app or user
The application is uninstalled
Permissions are changed to deny the application access to BBM
Keep content fresh
Avoid overloading the user profile with obsolete information
53
Removing Profile Boxes
Java
UserProfile userProfile = platformContext.getUserProfile();
UserProfileBox profileBox = userProfile.getProfileBox();
if (profileBox.isAccessible())
{
int[] itemIds = profileBox.getItemIds();
if(itemIds.length >= 1) {
profileBox.removeItem(itemIds[0]);
}
}
54
Removing Profile Boxes
WebWorks
var userProfile = blackberry.bbm.platform.self;
var profilebox = userProfile.profilebox;
if (profilebox.accessible)
{
profilebox.clearItems();
}
55
In-App Chat
The Plumbing: Sessions and Channels
Sessions and Channels
• What
•
Sessions and Channels are two types of data channels
between BBM Social Platform users
• Why
•
•
•
Multi user chat
Data connectivity
Games
• How
•
Let’s find out!
57
What are Sessions?
•
•
Sessions are a way to bring multiple users together
Sessions are many-to-many
•
•
•
•
•
•
Every user can see every other user in a session
Every user can invite other users
Users communicate via data channels
Users can broadcast messages to all users
Users can send messages to specific users
These capabilities can be limited by the application
•
•
IE. You don’t have to allow every user to be able to invite every other user
Sessions enable multi user activities such as
• Group chat
• Multiplayer games
58
What are Channels?
•
•
Channels allow one to one communication
Channels are one-to-many
A user is visible to only those whom this person invited or who
invited this person
• Users communicate via data channels
• Users can NOT broadcast messages to all users
• Users can send message to specific users that are visible to
them
•
•
Sessions enable private activities
• IM chat
• You may want to chat with many users but you wouldn’t want chatting with
each other
Two player games
• Location sharing
• Moderator-type scenarios
•
59
Session Class Components
•
BBMPlatformSessionListener
•
•
Receives data broadcast by other users
Receives notifications
• Contacts removed from a session
• Join request received
• Join request cancelled
•
BBMPlatformSession
•
•
•
•
•
•
Broadcasts data
Sends invitations
Add contacts
Get the list of contacts
Send data
Set host status
60
Session Class Components
•
MessagingService
•
•
Creates sessions
Sends join requests
• Send to other users who are hosting a public session in the same app
•
MessagingServiceListener
•
•
•
Receives notices about sessions created and ended
Many other notices occur here
Must register at startup if sessions or channels are used
61
Channels
•
Channels are implemented in the same way as sessions except
Uses BBMPlatformChannelListener instead of
BBMPlatformSessionListener
• Uses BBMPlatformChannel instead of BBMPlatformSession
• Cannot broadcast data to all participants
• Visibility of channel participants is limited
•
62
Session Example
Creating a Session and Inviting Participants - Java
MessagingService messagingService =
platformContext.getMessagingService();
//MySessionListener extends BBMPlatformSessionListener
//See the Dev Guide for the source code
BBMPlatformSession mySession =
messagingService.createSession(new MySessionListener());
if (mySession != null)
{
mySession.sendInvitation(“Let's play a game”, “CookieData:game6", 0);
//Invite message, cookie data, expiry time (ms)
}
63
Session Example
Creating a Session and Inviting Participants - WebWorks
var type = “session” // One of "channel" or "session"
var conn = blackberry.bbm.platform.io.createConnection(type);
setConnectionListeners(conn, type);
//setConnectionListeners() is a method that you implement to create and
//assign callbacks for the various connection events.
//See the JS Docs included with the SDK for an example
if ((conn !== undefined) && (conn !== null))
{
inviteOptions = { expiryTime : 60000 };
//Delay until the
//invitation expires (ms)
conn.inviteContacts("Let's play a game", inviteOptions);
}
64
Session Invites
•
How does a user get invited to a Session
•
If there is no session running and/or the application is not running:
• The user will receive the invite in BBM with the option to accept or decline
• If the user accepts, the app will be invoked and once the app registers its
MessagingServiceListener it will immediately get
MessagingServiceListener.sessionCreated(…) called, with the same functionality seen in
WebWorks with the event handlers.
•
If they’re in-app with a session already in progress containing the
sender:
• The user is not asked to join again
• The application will receive an alert via
MessagingServiceListener.sessionCreated(BBMPlatformSession session) for Java or
blackberry.bbm.platform.io.onConnectionCreated(…) for WebWorks
• Useful for adding additional sessions to support chat, etc.
65
Sending Message to all Session
Participants
•
BBMPlatformData is a wrapper for a byte array and represents data
sent or received over a session or a channel
•
Can identify data with an optional content type identifier
Java
String myMsg = "Test data";
BBMPlatformData data = new BBMPlatformData("Message", myMsg.getBytes());
mySession.broadcastData(data);
WebWorks
conn.broadcast(“Test data”); //connection must be a ‘session’ to broadcast
66
Sending data to a subset of
Participants
Java
String myMsg = "Test data";
BBMPlatformData data = new BBMPlatformData("Message", myMsg.getBytes(), 0);
//sendData can take BBMPlatformContact or BBMPlatformContactList depending on how many
//contacts or are transmitting to
mySession.sendData(data, contact); //BBMPlatformContact
mySession.sendData(data, contacts); //BBMPlatformContactList
WebWorks
mysession.send({message: “Test data"}, [player2, player4]);
//second parameter is an array of BBMPlatformUsers.
67
Hosted Sessions
•
Hosted sessions allow users who aren’t on each others
contact lists to come together in your application
Works like a regular session once users are in the session
• Requires application to bring together users using their own match
making techniques
• Using your own web services, you can exchange host information
amongst users
• In Java:
•
•
•
Call BBMPlatformSession.setPublic() on your session instance
In WebWorks
•
Call Connection. enableHosting(…) on your session instance
68
Joining a Hosted Sessions
•
Java
•
•
WebWorks
•
•
•
•
MessagingService.sendJoinRequest(int hostPin,
java.lang.String hostPPID, java.lang.String cookie)
static void requestToJoin(hostPIN : String, hostPPID :
String, onComplete : Function, [cookie: String])
hostPin is the device pin, ie. the device’s unique identifier
hostPPID is the user id, ie. The users’ unique identifier
Once joined, public sessions are identical to private
sessions.
69
Invite Session Participants to BBM
• What
•
Allow users to add newly made in-app friends to their
BBM contact list
• Why
•
Grow your users social graph with a common interest:
your app
• How
•
Call the appropriate method and pass it the list of
contacts to invite.
70
Invite Session Participants to BBM
•
•
Users can interact with others app users
even if they’re not on each other’s contact
list
• Realized using public sessions
Create a community around your
application
• Allows anonymous users to interact and,
if a friendship is formed, add them to
each others contact list.
• Users are more likely to return to your
app to interact with their new friends
• Users will remind others of your app via
invitations
71
Invite Session Participants to BBM
User Driven or App Driven
User driven displays a contact picker field containing all
session participants.
• The user can select any amount of contacts and invite
them all with one click.
App driven lets the application decide who to invite and then
prompts the user for permission.
• Ideal when you wish to control the UI or have an “invite
all” button.
72
Invite Session Participants to BBM
User Driven
•
User driven method requires one call:
Java
UIService.inviteToBBM(BBMPlatformConnection)
WebWorks
blackberry.bbm.platform.users.inviteToBBMFromConnections(onComplete,
BBMPlatformConnection);
BBMPlatformConnection is a reference to the session/channel
containing the users to be invited
73
Invite Session Participants to BBM
App Driven
•
•
•
Determine which users to invite using your own application logic
Put them in an array of BBMInvitationRequest objects.
Pass the array to the inviteToBBM(BBMInvitationRequest[])
method
Java
UIService.inviteToBBM(BBMInvitationRequest[])
WebWorks
blackberry.bbm.platform.users.inviteToBBM(onComplete,
BBMInvitationRequest);
74
In-App Chat
The UI
In App Chat
•
•
Sessions and channels inherently enable in app chat
Develop your own UI or use the provided components
Use the provided UI components to capture the look and feel of
BBM
• Premade components greatly reduce development time
•
•
WebWorks functionality
•
WebWorks UI fields are under development
76
In App Chat
UI Components
•
BottomUpManager
Vertical manager that gives its first field all the height that remains
after laying out the other fields.
• Used when chat is sharing screen space with your app in ‘split
screen’ configuration.
• Keeps the latest messages visible as the oldest move up
•
•
ChatField
Can be toggled to hide when the user isn’t reading/typing
• Combines numerous UI fields to provide the full BBM chat
experience
•
77
In App Chat
•
Setting up your chat screen
BottomUpManager bottomUpManager = new BottomUpManager()
_chatField = new ChatField(
MessageListManager.MESSAGE_STYLE_GROUP_MESSAGES_SAME_SENDER |
MessageListManager.MESSAGE_STYLE_SHOW_SENDER_DISPLAY_NAME,
MessageListManager.BORDER_STYLE_BUBBLE);
bottomUpManager.add (yourField); //this is the ‘first field’ that takes up all /
//remaining space
bottomUpManager.add (_chatField);
add (bottomUpManager);
78
In App Chat
•
Process the enter key in the keyChar method of the screen
if (fieldWithFocus == replyField && key == Characters.ENTER)
{
// handle the ENTER key from the embedded chat field
String msg = replyField.getText().trim();
if (msg.length() > 0)
{ // add code to send the message, for example:
try {
sendMessage(msg); //Shown on next slide
}
catch (DataOverflowException e) { // message cannot be sent
e.printStackTrace();
} catch (ContactUnreachableException e) { // contact is not reachable
e.printStackTrace(); }
}
replyField.setText(null); // clear the reply field
_chatField.toggle();
// hide the reply field
return true;
}
79
In App Chat
•
Send message code:
private void sendMessage (String msg) throws DataOverflowException, ContactUnreachableException
{
BBMPlatformContactList contactList = connection.getContactList();
/* assumes that a connection exists. To learn how to create a connection visit
www.blackberry.com/go/devguides to view the BlackBerry Messenger SDK Development Guide. */
if( connection.getContactList().size() > 0 ) {
BBMPlatformData data = new BBMPlatformData( msg );
connection.sendData( data, contactList );
}
}
}
80
Next Steps
Next Steps
• Download the BBM Social Platform Today!
•
http://www.blackberry.com/developers/bbm/
•
Get updates:
• BlackBerry Developer’s Blog - http://devblog.blackberry.com/
• @BlackBerryDev on Twitter
• Examples
•
Foursquare, ScoreMobile, RollerCoaster Rush,
Backgammon King, Wikitude
82
•
Series of Competitions and Recognition Awards
Best Adobe Flash/AIR app: April 28 – Aug 12 (now closed)
• Most Innovative BlackBerry WebWorks app on the BlackBerry PlayBook and
BlackBerry 6: May 9 – Aug 26
• Most Addictive social app using the BBM Social Platform: July 28 - Sep 23
•
•
US$3 Million Prize Pool – Submission Incentive Awards & Prize Packages
•
•
BlackBerry App World feature carousel, media press package, BlackBerry
smartphones and tablets, BlackBerry Alliance Program membership and more!
Winners will be recognized at the 2011 BlackBerry Developer
Conference!
For more information on the BlackBerry Developer Challenge 2011 visit:
www.blackberrypartnersfund.com/challenge
Submit your app today at: www.blackberrypartnersfund.com/submission
Q&A
Brian Zubert
Team Lead, Developer Relations
bzubert@rim.com
Download