Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Contributor
Posts: 14
Registered: ‎10-11-2011
My Device: 9360
Accepted Solution

Email listener on all message boxes

Hi all,

 

I have been trying to implement (what I thought would be) a simple message listener. I have the code in its own class implementing FolderListener, whereby all it needs to do is retrieve messages sent to any of the message boxes that the device has. After this it will check certain properties of the message, but I'm stuck at the actual listener/detection part. 

 

Using BB code exerts I tried extracting "INBOX" of type 'Folder' and adding the listener to this, but have since gone for a more high-level approach that performs this action on the entire store:

 

class MailListener extends MainManager implements FolderListener {
  Message _newMessage;
  String _cipherText;
	
  MailListener() {
    Session.getDefaultInstance().getStore().addFolderListener(this);
  }

  public void messagesAdded(FolderEvent event) {
    _newMessage = event.getMessage();
		
    UiApplication.getUiApplication().invokeLater(new Runnable() {
        public void run() {
          Dialog.alert("Got an email");
        }
    });
  }
}

 

 

However on receiving an email, the "Got an email" message fails to display - making me think the listener isn't working correctly, as the Dialog.alert call works fine if placed in the constructor.

 

Can anyone see where I'm going wrong?

 

Thanks!

Will

Developer
Posts: 19,612
Registered: ‎07-14-2008
My Device: Not Specified

Re: Email listener on all message boxes

[ Edited ]

Are you sure trhe Message Listener is actually run in a UiApplication?

 

I'm not sure that it is, so I would look fo some other way to notify your user.

http://supportforums.blackberry.com/t5/Java-Development/Alert-a-BlackBerry-smartphone-user-from-a-Ba...

 

You might find this post of interest:

http://supportforums.blackberry.com/t5/Java-Development/ControlledAccess-exception-for-persistent-st...

 

Also you might find this is useful:

http://supportforums.blackberry.com/t5/Java-Development/Application-is-not-notified-when-new-message...

Contributor
Posts: 14
Registered: ‎10-11-2011
My Device: 9360

Re: Email listener on all message boxes

Hi Peter,

 

Thank you for your reply. Based on your suggestion, I moved the relevant code to the base (UIApplication) class of my program, implementing what should still be a simple FolderListener with the same code as above. However, when signing and loading the app onto a real device, no behaviour is observed when an email is retrieved to one of the BIS inboxes on the device.

 

By this I mean that the Dialog does not display, nor are any other commands actioned (I tried having the text contents of a label field updated). Looking at similar code online, I'm struggling to see any differences!!

 

Given the location of the code now, I can't imagine some form of Global Event is required?

 

Regards,

Will

Developer
Posts: 4,764
Registered: ‎07-21-2008
My Device: Not Specified

Re: Email listener on all message boxes

[ Edited ]

The folder listener does not execute in your UiAPplication context (as Peter suspected) - it runs in a messages thread.

 

Using Global Events to send the notification to your own application instance is the correct approach.

 

Contributor
Posts: 14
Registered: ‎10-11-2011
My Device: 9360

Re: Email listener on all message boxes

Thanks both, I've been testing out a simpler alternative of passing a reference of the UI object to the FolderListener class, which can in turn pass a method callback upon messagesAdded() being invoked. This didn't work :smileyhappy:

 

I've found this link which seems to be along the right lines:

http://www.blackberry.com/knowledgecenterpublic/livelink.exe/fetch/2000/348583/800332/800620/What_Is...

 

However it all seems a bit above-and-beyond what I'm looking to do - all I need is the subject of each message being received! Is the only way to do this to implement GlobalEventListener in the UiApplication class, and also the FolderListener class?

 

Thank you both again for the help, doing my best to understand this and it's critical for my dissertation :smileyhappy:

 

Regards,

Will

Developer
Posts: 19,612
Registered: ‎07-14-2008
My Device: Not Specified

Re: Email listener on all message boxes

Here is a slightly more up to date version of the KB article you found:

http://supportforums.blackberry.com/t5/Java-Development/Global-Events-and-Global-Event-Listeners/ta-...

 

The approach of using a Global Event and FolderListener is the recommended approach for this sort of requirement.  Recommended because it is safe, does the appropriate context switching for you and isolates the email processing (which your folder listener is running in) from your code.

 

There are other ways, with less overhead and/or coding requirement, but there is no safer way.

 

As an example of another way, you could have a shared storage area in RuntimeStore.  You could have some processing in your Application that waits for some data to be placed in the RuntimeStore collection.  Then all the Listener has to do is pop the data into the RuntimeStore - your Application, running in its own context, will pick up this data and can process it as it likes. 

 

Passing the reference will not work, because you are still suffering from the problem of running your code in someone else's context.

 

I have attempted to explain the basics of Applications and their contexts (or process spaces, or whatever you want to call them), in this post.

http://supportforums.blackberry.com/t5/Java-Development/ControlledAccess-exception-for-persistent-st...

Developer
Posts: 4,764
Registered: ‎07-21-2008
My Device: Not Specified

Re: Email listener on all message boxes

The listener context and the UI context are actually completely different memory spaces.

 

You could possibly use the RuntimeStore to save the message, but that might be just as long a trip around the block as using global messages.

 

We actually just tak the message on to the global message when we fire it (there is an "Object" parameter for just this type of requirement).

 

I think this is your easiest path.  Posting the event is trivial, catching it (in your app context) is a simple method implementation.

 

Code snip for posting - module_name is the name of your application.

 

  /**
   * Sends a global event to the process launched from the named module.
   * 
   * @param module_name The name of the module for the process to receive the event.
   * @param guid A globally unique ID for the event.
   * @param arg1 Extra data for the event.
   * @param arg2 Extra data for the event.
   * @param obj1 Extra data for the event.
   * @param obj2 Extra data for the event.
   * @return True if sent, false on error.
   */
  public static boolean postGlobalEvent(String module_name, long guid, int arg1, int arg2, Object obj1, Object obj2)
  {
        ApplicationManager mgr = ApplicationManager.getApplicationManager();
        int processId = getProcessId(module_name);
        if (processId != -1){
            boolean postOK = mgr.postGlobalEvent(processId, guid, arg1, arg2, obj1, obj2);
            return postOK;
        } 
        else {
            return false;
        }
    }

 

 

 

Contributor
Posts: 14
Registered: ‎10-11-2011
My Device: 9360

Re: Email listener on all message boxes

[ Edited ]

EDIT: Ignore the below, it's actually working perfectly :smileyhappy: a separate piece of code was causing the crashing.

 

Thank you both for the extensive help and I apologise for the delay in my reply. The listener and GlobalEvent posting/retrieval is working very well, however as per the getDefaultInstance call on the Session, the listener only applies to the default CMIME account associated with the device.

 

While I'm still heavily researching and trialling methods to overcome this, I wonder if you have an opinion on the code I'm using below. It is currently crashing the application, but is attempting to obtain all CMIME accounts via the Service Books - and subsequently apply a listener to each of these:

 

// Return all mail accounts via the Service Book records
ServiceBook devBook = ServiceBook.getSB();
ServiceRecord[] mailRecords = devBook.findRecordsByCid("CMIME");

// Extract the service reference for each mail service
ServiceConfiguration currService;
Session[] _mailSessions = new Session[mailRecords.length];

for (int i = 0; i < mailRecords.length; i++) {
  currService = new ServiceConfiguration(mailRecords[i]);
  _mailSessions[i] = Session.getInstance(currService);
}

// Initiate a folder listener for each message box
for (int a = 0; a < _mailSessions.length; a++) {
  _mailSessions[a].getStore().addFolderListener(this);
}

 

The requirement for this is because the email being "listened for" could come to any of the available inboxes.

 

Regards,

Will