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
New Developer
mruthven
Posts: 20
Registered: ‎07-21-2008
My Device: Not Specified
Accepted Solution

GPS Listener issue

[ Edited ]

Hi folks,

 

Working with 4.2.1 on the 8800 simulator.  My app currently is composed of two separate applications, a UI app for getting/displaying information, and a "replication" app that communicates with our backend. I want to be able to include Location data on request from the user (in the UI app) and once it is updated, have the replication app send it off to the server. I have this working mostly to my satisfaction, but have the following problem: when I close the UI app, any incomplete GPS requests never finish. It seems like my LocationListener is unregistered, or perhaps the listener Thread is getting killed when the UI portion closes. I wouldn't expect that, as the instance is stored in the runtimestore, and the object that is registered as the listener is still valid. Here's how I have it set up:

 

From UI App, the following is run from a menu click:

 

 

GPSUpdater gps = GPSUpdaterFactory.getGPSUpdater();
gps.getGPSData(row, GPSUpdater.CHECK_IN);

 

From replication App: (lots of unrelated code cut out)

 

class ReplicationManagerImpl implements LocationListener
{
private GPSUpdater mGPSUpdater;

ReplicationManagerImpl()
{
mGPSUpdater = GPSUpdaterFactory.getGPSUpdater();
mGPSUpdater.setListener(this);
}

public void locationUpdated(LocationProvider provider, Location location)
{
mGPSUpdater.newLocationReceived(location);
}

 

public void providerStateChanged(LocationProvider provider, int newState)
{
//Not worried about this
}
}

 

 

 

GPSUpdater:

 

public class GPSUpdater
{
private Vector mUpdates;
private LocationProvider mProvider;
private Location mLocation;
private LocationListener mListener;
private Boolean isAcquiring;
private int mCounter;

private static final int MAX_RETRIES = 10;
public static final int CHECK_IN = 0;
public static final int CONFIRM = 1;

private static class UpdateData
{
private DataRow suRow;
private int updateType;
private long timeStamp;
}

GPSUpdater()
{
Criteria criteria = new Criteria();
criteria.setHorizontalAccuracy(50);
criteria.setVerticalAccuracy(50);
criteria.setCostAllowed(false);
try
{
mProvider = LocationProvider.getInstance(criteria);
if (mProvider.getState() == LocationProvider.OUT_OF_SERVICE)
{
SubsystemLog.log("GPS actions not supported", EventLogger.ALWAYS_LOG);
}
}
catch (LocationException lEx)
{
SubsystemLog.log("Error creating LocationProvider in GPSUpdater: " + lEx.getMessage(), EventLogger.ERROR);
}
mUpdates = new Vector();
mLocation = null;
isAcquiring = Boolean.FALSE;
mCounter = 0;
}

public void setListener(LocationListener listener)
{
mListener = listener;
}

public void getGPSData(DataRow row, int updateType)
{
long timestamp = System.currentTimeMillis();
if (((mLocation != null) && (mLocation.isValid()) && (mLocation.getTimestamp() > timestamp - 60000)) || (mProvider == null) || (mProvider.getState() == LocationProvider.OUT_OF_SERVICE))
{
UpdateRow(row, updateType, timestamp);
}
else
{
UpdateData update = new UpdateData();
update.row = row;
update.updateType = updateType;
update.timeStamp = timestamp;

synchronized(mUpdates)
{
mUpdates.addElement(update);
}

synchronized(isAcquiring)
{
if (!isAcquiring.booleanValue())
{
mProvider.setLocationListener(mListener, 5, 5, -1);
isAcquiring = Boolean.TRUE;
}
}
}
}

public void newLocationReceived(Location location)
{
if ((location == null) || (!location.isValid()) && (mCounter < MAX_RETRIES))
{
mCounter++;
return;
}

mCounter = 0;
mLocation = location;
SubsystemLog.log("Acquired co-ordinates: " + Double.toString(location.getQualifiedCoordinates().getLatitude()) + "," + Double.toString(location.getQualifiedCoordinates().getLongitude()), EventLogger.DEBUG_INFO);

Database db = DataSystemFactory.getDataSystem().openDatabase(DBSchema.NAME);
Object syncObject = db.getSyncObject();

synchronized(syncObject)
{
while (mUpdates.size() > 0)
{
UpdateData update = (UpdateData)mUpdates.elementAt(0);
UpdateRow(update.row, update.updateType, update.timeStamp);
mUpdates.removeElement(update);
}
}
db.commitAndNotify();

synchronized(isAcquiring)
{
provider.setLocationListener(null, -1, -1, -1);
isAcquiring = Boolean.FALSE;
}
}

private void UpdateRow(DataRow suRow, int updateType, long timeStamp)
{
//wrapper class to allow persisting double values
DBDouble latitude = new DBDouble();
DBDouble longitude = new DBDouble();

if (mLocation != null && mLocation.isValid())
{
latitude.setDouble(mLocation.getQualifiedCoordinates().getLatitude());
longitude.setDouble(mLocation.getQualifiedCoordinates().getLongitude());
}
else
{
latitude.setDouble(0.0);
longitude.setDouble(0.0);
}

//store data here
}

}

 

GPSUpdaterFactory:

 

public abstract class GPSUpdaterFactory {
private static final long ID = <ID here>;

public static final GPSUpdater getGPSUpdater()
{
Object o;
GPSUpdater gpsUpdater = null;
RuntimeStore runtimeStore = RuntimeStore.getRuntimeStore();
synchronized (runtimeStore)
{
o = runtimeStore.get(ID);
if (o != null)
{
if (o instanceof GPSUpdater)
{
gpsUpdater = (GPSUpdater)o;
}
}
if (gpsUpdater == null)
{
gpsUpdater = new GPSUpdater();
runtimeStore.put(ID, gpsUpdater);
}
}
return gpsUpdater;
}
}

 

Any suggestions are greatly appreciated.

 

Thanks,

 

Mike

 

 

Message Edited by mruthven on 07-21-2008 01:26 PM
Please use plain text.
Administrator
MSohm
Posts: 14,521
Registered: ‎07-09-2008
My Device: BlackBerry Z30, BlackBerry PlayBook
My Carrier: Bell

Re: GPS Listener issue

How are you closing the UiApplication?  Is the application actually exiting (System.exit call, Close menu item, etc...), or are you calling Application.requestBackground() to send the application to the background (continues to run)?
Mark Sohm
BlackBerry Development Advisor

Please refrain from posting new questions in solved threads.
Problem solved? Click the Accept As Solution button.
Found a bug? Report it using Issue Tracker
Please use plain text.
New Developer
mruthven
Posts: 20
Registered: ‎07-21-2008
My Device: Not Specified

Re: GPS Listener issue

Initially System.exit(0) from the onclose() method, but thought that might be a problem so I no longer override on close.
Please use plain text.
Administrator
MSohm
Posts: 14,521
Registered: ‎07-09-2008
My Device: BlackBerry Z30, BlackBerry PlayBook
My Carrier: Bell

Re: GPS Listener issue

Note that the Close menu item also calls System.exit. 

 

In this case the application would stop receiving updates due to the exit call.  To work around this, you can call Application.requestBackground.  This moves the application into the background, where it can continue to run.  Once you have your final fix the application could call System.exit to close itself.

Mark Sohm
BlackBerry Development Advisor

Please refrain from posting new questions in solved threads.
Problem solved? Click the Accept As Solution button.
Found a bug? Report it using Issue Tracker
Please use plain text.
New Developer
mruthven
Posts: 20
Registered: ‎07-21-2008
My Device: Not Specified

Re: GPS Listener issue

That's great, thanks Mark.
Please use plain text.