/**
* MessageListDemo.java
*
* Copyright � 1998-2011 Research In Motion Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Note: For the sake of simplicity, this sample application may not leverage
* resource bundles and resource strings. However, it is STRONGLY recommended
* that application developers make use of the localization features available
* within the BlackBerry development platform to ensure a seamless application
* experience across a variety of languages and geographies. For more information
* on localizing your application, please refer to the BlackBerry Java Development
* Environment Development Guide associated with this release.
*/
package com.rim.samples.device.messagelistdemo;
import net.rim.blackberry.api.invoke.Invoke;
import net.rim.blackberry.api.invoke.MessageArguments;
import net.rim.blackberry.api.messagelist.ApplicationIcon;
import net.rim.blackberry.api.messagelist.ApplicationIndicatorRegistry;
import net.rim.blackberry.api.messagelist.ApplicationMessage;
import net.rim.blackberry.api.messagelist.ApplicationMessageFolder;
import net.rim.blackberry.api.messagelist.ApplicationMessageFolderRegistry;
import net.rim.device.api.command.Command;
import net.rim.device.api.command.CommandHandler;
import net.rim.device.api.command.ReadOnlyCommandMetadata;
import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.image.Image;
import net.rim.device.api.ui.image.ImageFactory;
import net.rim.device.api.util.StringProvider;
/**
* Sample to demonstrate the Message List API. On device startup, two
* ApplicationMessageFolders are registered, one for inbox messages, and one for
* deleted messages. An ApplicationIndicator is also registered and will be
* visible on the home screen when the inbox folder contains demo messages.
* ApplicationMenuItems are registered which allow for the display and
* manipulation of demo messages while in the Messages application. When this
* sample application is invoked from the home screen, a user can invoke menu
* items to add messages to the inbox or start a thread to add, delete and and
* change properties of messages.
*/
public final class MessageListDemo extends UiApplication {
/* com.rim.samples.device.messagelistdemo */
static final long KEY = 0x39d90c5bc6899541L; // Base folder key
/* com.rim.samples.device.messagelistdemo.INBOX_FOLDER_ID */
static final long INBOX_FOLDER_ID = 0x2fb5115c0e4a6c33L;
/* com.rim.samples.device.messagelistdemo.DELETED_FOLDER_ID */
static final long DELETED_FOLDER_ID = 0x78d50a91eff39e5bL;
/**
* Flag for replied messages. The lower 16 bits are RIM-reserved, so we have
* to use higher 16 bits.
*/
static final int FLAG_REPLIED = 1 << 16;
/**
* Flag for deleted messages. The lower 16 bits are RIM-reserved, so we have
* to use higher 16 bits.
*/
static final int FLAG_DELETED = 1 << 17;
// All our messages are received, we don't show sent messages
static final int BASE_STATUS = ApplicationMessage.Status.INCOMING;
static final int STATUS_NEW = BASE_STATUS
| ApplicationMessage.Status.UNOPENED;
static final int STATUS_OPENED = BASE_STATUS
| ApplicationMessage.Status.OPENED;
static final int STATUS_REPLIED = BASE_STATUS
| ApplicationMessage.Status.OPENED | FLAG_REPLIED;
static final int STATUS_DELETED = BASE_STATUS | FLAG_DELETED;
// Constant to define number of bulk messages
static final int MAX_MSGS = 50;
private CommunicationSimulatorThread _commThread;
/**
* Entry point for application.
*
* @param args
* Command line arguments
*/
public static void main(final String[] args) {
if (args != null && args.length > 0) {
// Perform initialization on device startup
if (args.length == 1 && args[0].equals("startup")) {
final MessageListDemoDaemon daemon =
new MessageListDemoDaemon();
// Register application indicator
final EncodedImage indicatorIcon =
EncodedImage
.getEncodedImageResource("img/indicator.png");
final ApplicationIcon applicationIcon =
new ApplicationIcon(indicatorIcon);
ApplicationIndicatorRegistry.getInstance().register(
applicationIcon, false, false);
// Check if this application registered folders already
final ApplicationMessageFolderRegistry reg =
ApplicationMessageFolderRegistry.getInstance();
if (reg.getApplicationFolder(INBOX_FOLDER_ID) == null) {
// Register folders & message types and initialize folders
// with data. Normally the data would come from from a mail
// server or persistent store.
daemon.init();
}
// This daemon application will be responsible for
// listening for notifications and menu actions, it runs until
// the device shuts down or the application is uninstalled.
daemon.enterEventDispatcher();
} else if (args.length == 1 && args[0].equals("gui")) {
// Create a GUI instance for displaying a DemoMessageScreen.
// This will occur when this application is invoked by the
// View Demo Message menu item.
final MessageListDemo messageScreenApp =
new MessageListDemo(false);
messageScreenApp.enterEventDispatcher();
}
} else {
// Create an instance of the main GUI application. This occurs
// when the application is launched from home screen.
final MessageListDemo mainGuiApp = new MessageListDemo(true);
mainGuiApp.enterEventDispatcher();
}
}
/**
* Creates a new MesageListDemo object
*
* @param isMainGui
* True if constructor should create GUI, false otherwise
*/
public MessageListDemo(final boolean isMainGui) {
if (isMainGui) {
final MainScreen mainScreen = new MainScreen();
mainScreen.setTitle("Message List Demo");
mainScreen
.add(new RichTextField(
"Please choose one of the menu options, then open the Messages application from the home "
+ "screen to manipulate Message List Demo messages. You can open, reply to, mark opened and unopened, delete and search "
+ "for messages in the list."));
addMenuItems(mainScreen);
pushScreen(mainScreen);
}
}
/**
* Adds a menu which allows a user to perform various message store actions
*
* @param mainScreen
* The screen to add the menu to
*/
void addMenuItems(final MainScreen mainScreen) {
final MenuItemWithIcon appendUnreadMessage =
new MenuItemWithIcon("Append Unread Message", 0,
"img/sm_add_message.png");
appendUnreadMessage.setCommand(new Command(new CommandHandler() {
/**
* @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
* Object)
*/
public void execute(final ReadOnlyCommandMetadata metadata,
final Object context) {
// Create a new message
final DemoMessage message = new DemoMessage();
message.setSender("John Smith");
message.setSubject("Hello from John");
message.setMessage("Hello Chris. Do you know that you can get a BlackBerry Smartphone cheaper through the Message List Demo Store?");
message.setReceivedTime(System.currentTimeMillis());
message.setPreviewPicture(CommunicationSimulatorThread
.getRandomPhotoImage());
// Store message
final MessageListDemoStore messageStore =
MessageListDemoStore.getInstance();
synchronized (messageStore) {
messageStore.addInboxMessage(message);
}
Dialog.alert("Unread message was added to inbox");
// Notify folder
final ApplicationMessageFolder inboxFolder =
messageStore.getInboxFolder();
inboxFolder.fireElementAdded(message, true);
}
}));
mainScreen.addMenuItem(appendUnreadMessage);
final MenuItemWithIcon appendOpenedMessage =
new MenuItemWithIcon("Append Opened Message", 1,
"img/sm_add_message.png");
appendOpenedMessage.setCommand(new Command(new CommandHandler() {
/**
* @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
* Object)
*/
public void execute(final ReadOnlyCommandMetadata metadata,
final Object context) {
// Create a new message
final DemoMessage message = new DemoMessage();
message.setSender("Maria Rosevelt");
message.setSubject("How have you been?");
message.setMessage("Hi Chris. I haven't seen you in ages. Let's do lunch!");
message.setReceivedTime(System.currentTimeMillis() - 2 * 24
* 60 * 60 * 1000L);
message.setPreviewPicture(CommunicationSimulatorThread
.getRandomPhotoImage());
message.markRead();
// Store message
final MessageListDemoStore messageStore =
MessageListDemoStore.getInstance();
synchronized (messageStore) {
messageStore.addInboxMessage(message);
}
Dialog.alert("Opened message was added to inbox");
// Notify folder
messageStore.getInboxFolder().fireElementAdded(message);
}
}));
mainScreen.addMenuItem(appendOpenedMessage);
final MenuItemWithIcon appendMessagesInBulk =
new MenuItemWithIcon("Append Messages in Bulk", 2,
"sm_add_messages_bulk");
appendMessagesInBulk.setCommand(new Command(new CommandHandler() {
/**
* @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
* Object)
*/
public void execute(final ReadOnlyCommandMetadata metadata,
final Object context) {
final MessageListDemoStore messageStore =
MessageListDemoStore.getInstance();
synchronized (messageStore) {
for (int i = 1; i <= MAX_MSGS; i++) {
// Create a new message
final DemoMessage message = new DemoMessage();
message.setSender("Mark Duval");
message.setSubject(i + " of " + MAX_MSGS);
message.setMessage("Please pick up milk and bread on the way home.");
message.setReceivedTime(System.currentTimeMillis());
message.setPreviewPicture(CommunicationSimulatorThread
.getRandomPhotoImage());
// Store message in the runtime store
messageStore.addInboxMessage(message);
}
// Notify folder
final ApplicationMessageFolder inboxFolder =
messageStore.getInboxFolder();
inboxFolder.fireReset(true);
}
Dialog.alert("Bulk messages were added to inbox");
}
}));
mainScreen.addMenuItem(appendMessagesInBulk);
final MenuItemWithIcon startCommunicationThread =
new MenuItemWithIcon("Start Communication Thread", 3,
"sm_start_auto");
startCommunicationThread.setCommand(new Command(new CommandHandler() {
/**
* @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
* Object)
*/
public void execute(final ReadOnlyCommandMetadata metadata,
final Object context) {
if (_commThread != null) {
Dialog.alert("Communication thread already running");
return;
}
_commThread = new CommunicationSimulatorThread();
_commThread.start();
Dialog.alert("Communication thread started successfully.\n After dismissing this dialog, press the End (red phone) key and"
+ " open the Messages application from the home screen.");
}
}));
mainScreen.addMenuItem(startCommunicationThread);
final MenuItemWithIcon stopCommunicationThread =
new MenuItemWithIcon("Stop Communication Thread", 4,
"sm_stop_auto");
stopCommunicationThread.setCommand(new Command(new CommandHandler() {
/**
* @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
* Object)
*/
public void execute(final ReadOnlyCommandMetadata metadata,
final Object context) {
if (_commThread == null) {
Dialog.alert("Communication thread is not running");
return;
}
_commThread.stopRunning();
_commThread = null;
Dialog.alert("Communication thread stopped.");
}
}));
mainScreen.addMenuItem(stopCommunicationThread);
final MenuItemWithIcon viewMessagesInMessageList =
new MenuItemWithIcon("View Messages In Message List", 5,
"sm_open_messages_app");
viewMessagesInMessageList.setCommand(new Command(new CommandHandler() {
/**
* @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
* Object)
*/
public void execute(final ReadOnlyCommandMetadata metadata,
final Object context) {
final MessageListDemoStore messageStore =
MessageListDemoStore.getInstance();
final MessageArguments mArg =
new MessageArguments(messageStore.getInboxFolder());
Invoke.invokeApplication(Invoke.APP_TYPE_MESSAGES, mArg);
}
}));
mainScreen.addMenuItem(viewMessagesInMessageList);
}
/**
* A MenuItem with an icon
*/
private static class MenuItemWithIcon extends MenuItem {
/**
* Creates a new MenuItemWithIcon object
*
* @param label
* The text to appear with the menu item
* @param priority
* The priority of the menu item
* @param iconResourcePath
* Location of icon resource
*/
public MenuItemWithIcon(final String label, final int priority,
final String iconResourcePath) {
super(new StringProvider(label), 0x230100, priority);
if (iconResourcePath != null) {
// Retrieve the icon resource and add it to the menu item
final EncodedImage encodedImage =
EncodedImage.getEncodedImageResource(iconResourcePath);
if (encodedImage != null) {
final Image iconImage =
ImageFactory.createImage(encodedImage);
this.setIcon(iconImage);
}
}
}
}
}