04-02-2013 04:26 AM
I am using PhoneListener for implementing a feature based on calls.
I have implemented the interface in my class called CallListener, I added listener in Background process with this
Listener works fine as expected, I am generating a pop up on call, which also works fine.
However as soon as I reinstall application, listener stops working. I dont get any callbacks untill and unless I remove application, restart device and install application again.
For finding root cause of this problem I removed pop up on calls and replaced it with logs. In this case Listener works after reinstalling application.
I dont understand how my execution post call affect behaviour of addition of call listeners.
Whenever I add a listener, I pull it from persistent storage, remove current listener and add listener again. (This is done to ensure that listeners are not added twice). To be able to have consistent listener objects I store it and retrieve it from Persistent Object.
How can I solve this issue? Any pointer would be appreciated.
Solved! Go to Solution.
04-02-2013 05:05 AM
We are just guessing here. Unfortunately we need a little more than this:
."listener stops working"
Does this mean that it doesn't get call backs or doesn't process the call backs, or fails while processing the call backs. I suspect with debugging you should be able to narrow this done to a specific statement, can you try to do this and let us know? But I have a suspicion - so read on first.
When a listener runs it can run under control of the Phone Application. So you say this:
" added listener in Background process"
But just to be clear, the Listener does NOT run under control of your background process.
That means you have to careful with things like this:
"pop up on calls"
In the popup you are blocking the phone application. It probably does not like this.
The safest way to implement listeners is to just use the listener to capture information, then pass this information to your own application for processing - global event being one method of doing this.
"Whenever I add a listener, I pull it from persistent storage"
I can't see how this will work. My understanding is Persistent store actually makes copies of the classes and restores these. This one reason why you can't have a reference to a non persistent storage object in persistent store. So in fact the object you pull from persistent store is NOT the object the listener is using - it is a copy of it. This might actually be your problem. Instead of using Persistent store, put the listener object in RuntimeStore, which does not make a copy. If you do need to persistent some stuff, do that outside your listener.
04-02-2013 05:56 AM
Thanks for reply,
When I said "listener stops working" I meant I "stop receiving callbacks"
About background process, I have two entry points to application, one that handle GUI for application, and other one is a nongui part which does background sync and other such work, I have added listener from nongui entry point.
My understanding is that these are just entry points, so I tried pushing a UIApplication screen from listener callback, again I get that screen when I run on first installation.
I run my UI in new thread so that it wont block any running call related process.
I will test it with Runtime Store to see if it works.
Can you please elaborate on this?
"pass this information to your own application for processing - global event being one method of doing this. "
I am currently picking information and passing it to new thread for processing call which in turn pushes screen.
04-02-2013 06:20 AM
"I am currently picking information and passing it to new thread for processing call which in turn pushes screen."
As you are aware, the BB is built around Applications. You have two, the background one and the foreground one. If you start a Thread in your background processing, it will run under control of that Application. If your background Application stops, then this Thread will disappear.
Now assume that your foreground (GUI) Application invokes a method that is supplied by the code in your background Application. This code starts a Thread. This Thread will be running under the foreground applications control, not the background application. So if the background Application stops, this Thread will continue to run. Even though the code that started it was supplied by the Application program.
Extend this idea to the Listener. The Listener is invoked by the Phone Application. If you start a Thread, then that Thread is running under control of the Phone Application. If you do a Application.getApplication(), you will get the Phone Application. Not your application. This is dangerous. For example, if your Listener code or your Thread called System.exit(), it will take out the Phone Application.
You need to switch processing to your own Application to do this sort of stuff. There are a number of approaches, but the easiest is to use a Global Event. You package up some information and fire an event in your Listener (running under control of the Phone Application), your Global Event Handler (in your Application) gets control and is passed in the information you give it, and it actually gets control on the Event Thread, so if you have a UiApplication acting as a GlobalEvent listener, you can do things with the screen. And they are not too difficult to use, as this KB article demonstrates:
Hope this helps.
04-02-2013 06:25 AM
I tried with RuntimeStore and same issue.
In fact I simply added a new Listener (Without checking if there was a previous listener)
There is no still no callback on reinstall.
My guess is calling UI is causing some issues with future addition of listener.
Is there any way out?
04-02-2013 06:34 AM
Is it possible that the Phone Application is disabling your listener because it does not like the UI interaction? Try the Global Event approach.
And do put your listener in RuntimeStore not PersistentStore. The other advantage of this approach is that on a reset of the Phone, RuntimeStore disappears, so you will find that your Listener is not in RuntimeStore and has been removed from the Phone Application. Using this logic, if you ever find it in RuntimeStore then it has been added and you won't add it twice, as is a common problem. And if not in RuntimeStore, then you have to add it as a Listener.