02-05-2013 12:18 PM
Hi all,
I recently added a background thread into an application that is launched from an alternate entry point. This background thread will constantly (every X seconds) do RMS checks and compare timestamps. When necesarry, it will send a notification to the user that launches the application when clicked. The problem is..
When the user clicks the notification, it will open the application normally (with the icon and everything), but it also opens a second instance that does not have an icon. I have determined that the code that actually launches the application is not the culprit (because if I take it out, it still opens the second instance). This is making me think it has something to do with the ApplicationDescriptor.
My notification manager has this line:
ApplicationDescriptor appDescriptor = new ApplicationDescriptor(ApplicationDescriptor.curren
If I change this to only return the currentApplicationDescriptor() or add any arguments in the string array, the notifications do not function at all.
Can anyone think of a reason why this might be happening?
Solved! Go to Solution.
02-05-2013 06:13 PM
The thing you need to be aware of is that an alternate entry can be another instance of your application. So if you start an alternate entry, and this runs in the background, you can have a second instance of your application. it all depends on what you code in your Main.
So unless we see your main method we can not really comment on this. but what you are seeing is possible.
02-06-2013 10:10 AM
Hi Peter,
This is our main method. (Removed some preprocs and such to simplify).
private static void processMainArgs(String[] args) {
if (args != null && args.length != 0 && args[0].equals("rollover")) {
ApplicationManager appMan = ApplicationManager.getApplicationManager();
boolean keepGoing = true;
Bitmap regularIcon = Bitmap.getBitmapResource("icon.png");
Bitmap icon = Bitmap.getBitmapResource("icon_roll_over.png");
while (keepGoing) {
if (appMan.inStartup()) {
// BlackBerry is still starting up
try {
Thread.sleep(1000);
} catch (Exception e) {}
} else {
try {
HomeScreen.updateIcon(regularIcon, 0);
HomeScreen.setRolloverIcon(icon, 0);
keepGoing = false;
} catch (Exception e) {}
}
}
System.exit(0);
} else if (args != null && args.length != 0 && args[0].equals("notification")) {
initFolderRegistry();
}
}
This method is called when the alternate entry point sends "notification" through the main args. It will then call init() on our notification manager.
private static void initFolderRegistry() {
final NotificationManager notificationManager = new NotificationManager();
final EncodedImage indicatorIcon = EncodedImage.getEncodedImageResource(RESOURCE_COD_
final ApplicationIcon applicationIcon = new ApplicationIcon(EncodedImage.getEncodedImageResour
final ApplicationIndicatorRegistry indicatorReg = ApplicationIndicatorRegistry.getInstance();
indicatorReg.register(applicationIcon, true, false);
final ApplicationMessageFolderRegistry reg = ApplicationMessageFolderRegistry.getInstance();
if (reg.getApplicationFolder(NotificationManager.INBO
notificationManager.init();
}
notificationManager.enterEventDispatcher();
}
Lastly, this is the init() call that happens in the NotificationManager itself:
public void init() {
final ApplicationMessageFolderRegistry folderReg = ApplicationMessageFolderRegistry.getInstance();
final ApplicationDescriptor mainDescription = ApplicationDescriptor.currentApplicationDescriptor
final ApplicationDescriptor appDescriptor = new ApplicationDescriptor(mainDescription, APPLICATION_NAME, new String[] {});
//#if BB_OS_VERSION >= 7.0
final ApplicationFolderIntegrationConfig inboxIntegration = new ApplicationFolderIntegrationConfig(true, true, mainDescription);
final ApplicationFolderIntegrationConfig deletedIntegration = new ApplicationFolderIntegrationConfig(false);
//#endif
final MessageListStore messages = MessageListStore.getInstance();
//#if BB_OS_VERSION >= 7.0
final ApplicationMessageFolder inbox = folderReg.registerFolder(NotificationManager.INBOX
final ApplicationMessageFolder deleted = folderReg.registerFolder(NotificationManager.DELET
//#else
final ApplicationMessageFolder inbox = folderReg.registerFolder(NotificationManager.INBOX
final ApplicationMessageFolder deleted = folderReg.registerFolder(NotificationManager.DELET
//#endif
//#if BB_OS_VERSION >= 7.0
inbox.addListener(this, ApplicationMessageFolderListener.MESSAGE_DELETED | ApplicationMessageFolderListener.MESSAGE_MARKED_OP
deleted.addListener(this, ApplicationMessageFolderListener.MESSAGE_DELETED, appDescriptor);
//#else
inbox.addListener(this, ApplicationMessageFolderListener.MESSAGE_DELETED | ApplicationMessageFolderListener.MESSAGE_MARKED_OP
deleted.addListener(this, ApplicationMessageFolderListener.MESSAGE_DELETED, appDescriptor);
//#endif
messages.setFolders(inbox, deleted);
folderReg.setRootFolderName(APPLICATION_NAME);
final ApplicationIcon icon = new ApplicationIcon(EncodedImage.getEncodedImageResour
folderReg.registerMessageIcon(MagmicMessage.MAGMIC
folderReg.registerMessageIcon(MagmicMessage.MAGMIC
folderReg.registerMessageIcon(MagmicMessage.MAGMIC
final ApplicationMenuItem openMenuItem = new OpenContextMenu(0x230010);
final ApplicationMenuItem markOpenedMenuItem = new MarkOpenedContextMenu(0x230030);
final ApplicationMenuItem markUnopenedMenuItem = new MarkUnreadContextMenu(0x230040);
final ApplicationMenuItem[] newGuiMenuItems = new ApplicationMenuItem[] { openMenuItem };
final ApplicationMenuItem[] newDaemonMenuItems = new ApplicationMenuItem[] { markOpenedMenuItem };
final ApplicationMenuItem[] openedGuiMenuItems = new ApplicationMenuItem[] { openMenuItem };
final ApplicationMenuItem[] openedDaemonMenuItems = new ApplicationMenuItem[] { markUnopenedMenuItem };
final ApplicationMenuItem[] deletedGuiMenuItems = new ApplicationMenuItem[] { openMenuItem };
folderReg.registerMessageMenuItems(MagmicMessage.M
folderReg.registerMessageMenuItems(MagmicMessage.M
folderReg.registerMessageMenuItems(MagmicMessage.M
folderReg.registerMessageMenuItems(MagmicMessage.M
folderReg.registerMessageMenuItems(MagmicMessage.M
folderReg.setBulkMarkOperationsSupport(MagmicMessa
folderReg.setBulkMarkOperationsSupport(MagmicMessa
//#if QA_BUILD
int timerCheckInterval = 5000; // Five seconds for QA builds
//#else
int timerCheckInterval = 60000; // One minute for production builds
//#endif
UpdateThread updateThread = new UpdateThread(timerCheckInterval, messages, new ApplicationIcon(EncodedImage.getEncodedImageResour
updateThread.run();
(new NotificationManager()).enterEventDispatcher();
}
The thread that is opened at the bottom of init() is what we use to do our RMS checks. It will continuously run and notify the user when our daily lottery goes off.
Is there a better way to do this besides using a background thread? Would I be able to make all of this work in a single application? That would ultimately be much better.
Thanks a lot for the response.
02-06-2013 10:12 AM
Actual main() if that is important too:
public static void main(String[] args) {
processMainArgs(args);
BlackBerry controller = new BlackBerry();
//#if USES_BB_MESSENGER && BB_OS_VERSION >= 5.0
controller.checkBBMIntegration(args);
//#endif
controller.setAcceptableScreenDirections();
controller.enableKeyUpEvents(true);
Core core = Core.create(controller);
core.setCanvas(controller.canvas);
controller.pushScreen(controller.canvas);
core.start();
controller.enterEventDispatcher();
}
02-06-2013 03:55 PM
I have resolved the problem I was having.
In the end, I ended up changing this code:
final ApplicationDescriptor mainDescription = ApplicationDescriptor.currentApplicationDescriptor();
final ApplicationDescriptor appDescriptor = new ApplicationDescriptor(mainDescription, APPLICATION_NAME, new String[] {});
to:
int moduleHandle = CodeModuleManager.getModuleHandle(APPLICATION_NAME
ApplicationDescriptor mainDescriptor;
if (moduleHandle != 0)
{
ApplicationDescriptor[] apDes = CodeModuleManager.getApplicationDescriptors(module
mainDescriptor = apDes[0];
ApplicationMessageFolderRegistry folderReg = ApplicationMessageFolderRegistry.getInstance();
if (folderReg.getApplicationFolder(NotificationManage
notificationManager.init(folderReg, mainDescriptor);
}
}
Instead of using the currentApplicationDescriptor(), I had to reference the application module itself using the CoreModuleManager. My init method takes in the ApplicationDescriptor and uses it for everything.
Thanks to everyone who took any time to read through my post!