×

Discussion Board

Results 1 to 11 of 11
  1. #1
    Regular Contributor
    Join Date
    Mar 2009
    Posts
    80

    setLocationListener problem

    Hi,

    After having used getLocation() successfully for long time I now need to swich to setLocationListener.
    Since the the applicaiton is getting large, I decided to write new LocationDispatcher service Class for the different function classes.

    In order to try this function, I based this first code on the movementtracker example on page 16 in the JSR 173 spec, but I cannot get it to work.

    Problem 1:
    It hangs in the mobile phones I use for Test. I suspect it hangs in the setLocationDispatcher, at least the Thread suspends there when I run it in the Debugger. I have tied to use the default values for setLocationListener, same problem, it hangs.

    Problem 2:
    When looking at this code I wonder if it meant to be used at all? Should's it be better if the whole process of handling last part, ie sending the new location to other classes, were done inside the thread? Or should I write another class/thread to handle the processing of the new location?


    Problem 3:
    Is there a better way to forward the new location? When running it in NetBeans I get a warning about potential deadlock. The method I use only updates a Location variable in the receiving class and then immediately returns.

    CODE:

    import javax.microedition.location.*;
    import javax.microedition.location.LocationException;
    import javax.microedition.location.LocationListener;
    import javax.microedition.location.LocationProvider;
    import javax.microedition.lcdui.*;


    class LocationDispatcher implements LocationListener {
    private SoftAlarm midlet;
    private SafeMap safeMap;
    LocationProvider provider;
    Location lastValidLocation;
    LocationListener listener;
    UpdateHandler handler;
    boolean done;
    static AlertType ERROR;
    static AlertType INFORMATION;
    boolean LocationExceptionStatus = false;
    static int NO_REQUIREMENT = 0;
    private int GPS_HorizontalAccuracyRequested = 200;

    public LocationDispatcher(SoftAlarm midlet) throws LocationException {
    this.midlet= midlet;
    done = false;
    handler = new UpdateHandler();
    new Thread(handler).start();

    Criteria cr= new Criteria();
    cr.setHorizontalAccuracy(GPS_HorizontalAccuracyRequested);
    cr.setSpeedAndCourseRequired(true);
    cr.setCostAllowed(true);
    cr.setAltitudeRequired(true);
    cr.setPreferredPowerConsumption(NO_REQUIREMENT);

    try {
    provider = LocationProvider.getInstance(cr);
    provider.setLocationListener(this, 20, 20, 20);
    }
    catch (LocationException ex) {
    LocationExceptionStatus = true;
    ex.printStackTrace();
    }
    }

    public void locationUpdated(LocationProvider provider, Location location) {
    handler.handleLocationUpdate(location);
    }

    public void providerStateChanged(LocationProvider provider, int newState) {
    handler.handleStateUpdate( newState);
    }

    class UpdateHandler implements Runnable {
    private Location updatedLocation = null;
    private int updatedState = 0;

    // The run method performs the actual processing of the location
    // updates
    public void run() {
    Location locationToBeHandled = null;
    int stateToBeHandled = 0;
    while (!done) {
    synchronized(this){
    if (updatedLocation == null) {
    try {
    wait();
    } catch (Exception e) {
    // Handle interruption
    }
    }
    } //synchronized
    // Now dispach for delivery to other classes
    if (locationToBeHandled != null) {
    locationToBeHandled = updatedLocation;
    updatedLocation = null;
    processUpdate(locationToBeHandled);
    } //if
    } // while
    } // run

    public synchronized void handleLocationUpdate(Location update) {
    updatedLocation = update;
    notify();
    }

    private void handleStateUpdate(int newState){
    updatedState = newState;
    notify();
    }

    private void processState(int state) {
    safeWalkMap.LocationProviderStateRetriver(state, LocationExceptionStatus);
    }

    private void processUpdate(Location update) {
    safeWalkMap.LocationRetriver(update);
    }
    } //Runnable
    }

  2. #2
    Super Contributor
    Join Date
    Apr 2007
    Posts
    2,708

    Re: setLocationListener problem

    one idea could be to strat trying with less strict Criteria,
    also it would be pretty handy if you actually do something sensible with the exceptions, this won't help you a lot :
    catch (LocationException ex) {
    LocationExceptionStatus = true;
    ex.printStackTrace();
    }

    change the printStackTrace() to System.out.println if you test on emulator ar write to an alert if you are using on-device...

  3. #3
    Regular Contributor
    Join Date
    Mar 2009
    Posts
    80

    Re: setLocationListener problem

    Hi Tiger,

    Thank's for your feedback.

    1.
    I did relax the criteria down to null criteria and default settings (this, -1, -1, -1).
    No change. The setLocationListener seems to hang since no Location is ever supplied to the locationUpdated listener. (Neither Valid nor InValid).

    I noticed in the debugger that the "this" variable for LocationListener in the method
    setLocationListener = LocationDispatcher$UpdateHandler. I'm puzzeled because in the JSR 173 example on page 16, the LocationUpdated listener is the LocationDispatcher class, not the UpdateHandler class.
    Also, moving it down to the UpdateHandler gave an error in NetBeans.

    2.
    I've seen your kind example for using setLocationListener i Wiki.
    However when running a similar class that I wrote (without a Runnable object) my NOKIA 6210 Navigator got one location, then it stopped. In the same time I also tested the app on my SE W715 who got location after location OK.

    I then read the JSR 179 spec carefully and it says this on page 60:
    "The listener methods MUST return quickly and should not perform any extensive processing. The method calls are intended as triggers to the application. Application should do any necessary extensive processing in a separate thread and only use these methods to initiate the processing."

    So, I've come to realize that I, and probably others are looking for an official recommendation example on how to use the setLocationListener in the correct way, with a separate thread, as specified above.

    Please note that I do not want "code", merely a simple working example, like yours and other Wiki examples, on how to use this specific method in a way that result in quality code = predictable locations when the mobile phone handled in the correct way, i.e. is used outside etc..

    Lastly, as you correctly pointed out is your answer to me, quality code also include the correct error handling. I made it simple for me during this test phase..

    BR
    /Per

  4. #4
    Super Contributor
    Join Date
    Apr 2007
    Posts
    2,708

    Re: setLocationListener problem

    hhmmm ok, well to begin with its nice to see you responding so extensively and professionally
    Personally I wouldn't start out with the example code that is provided with the JSR-179, unfortunately (in my opinion) it's way too complex with all kind of handler and notifier classes... I would start with only a single simple midlet which tries to read out the latitude + longitude...
    To do that you simply can register the midlet itself as the LocationListener, as you are saying don't do anything intensive within the Locationupdated method but just simply print out the latitude and longitude...
    If that all works well then start thinking more complex architecture/classes...

  5. #5
    Regular Contributor
    Join Date
    Mar 2009
    Posts
    80

    Re: setLocationListener problem

    Hi,

    Thank you for your kind feedback.
    Actually, during the weekend I've wrote 4 different classes, two in the MIDlet and two outside. I made two variants of the JSR 179 example. Nice to hear your thoughts on the JSR 179 example, I fully agree. I all cases the code hangs in the setLocationListener. The locationUpdated is never called. I've run out of ideas on what's causing this.

    In order not to loose more development time, I'll switch back to my old polling getLocation class. My NOKIA 6210 works great with that method. The location, speed, course, altitude is delivered as a clockwork and with very good precision, ie. it works great. No hickups.
    The reason for testing the setLocationListener was that another brand did not supply all data using the getLocation.

    BR/Per

  6. #6
    Super Contributor
    Join Date
    Apr 2007
    Posts
    2,708

    Re: setLocationListener problem

    this might be a stupid comment, but if it hangs at the setLocationListener method, you did implement the locationlistener interface right ?

    public class myClass implements LocationListener

    and then something like this :

    Code:
    criteria = new Criteria();
    criteria.setCostAllowed(true);
    criteria.setPreferredPowerConsumption(Criteria.NO_REQUIREMENT);
                
    try 
    {
       locationProvider = LocationProvider.getInstance(criteria);
    } 
    catch (LocationException le) 
    {
       System.out.println("Problem creating locationProvider : " + le.toString());
    }
                
    try
    {
       locationProvider.setLocationListener(this, interval, -1, -1);
    }
    catch(SecurityException se)
    {
       System.out.println("Problem creating locationProvider : " + le.toString());
    }

  7. #7
    Regular Contributor
    Join Date
    Mar 2009
    Posts
    80

    Re: setLocationListener problem

    Correct.
    I also tried with settings:

    1. .....setLocationListener(this, -1,-1,-1) = default values(?)
    and
    2. .....getInstance(null) = default values(?)

    In the WTK emulator I always set a valid GPS Location.
    I realize that I did not try all variants on a live device.
    So I will do a couple of test shots on my 6210 Nav later today.

    Thank you very much.
    /Per

  8. #8
    Regular Contributor
    Join Date
    Mar 2009
    Posts
    80

    Re: setLocationListener problem

    After doing some more reading at this site and on the Web, it seems like the setLocationListener approach is the way that result in least fragmentation problems.
    Therefore I intended to write a robust implementation for setLocationListener.

    However, it looks like I made at least one mistake somewhere, since it never delivers any location. I have set the criteria as loose as practically possible, and set the interval to 20 seconds witch is OK when running the getLocation class.

    Since the NetBeans 6.7 IDE complains about the risk of deadlock when I implement a one class solution, I divided this implementation into two classes:
    - one class for handling getInstance/setLocationListener
    - one class with a runnable responsible for forwarding the new Location & new State to the GUI classes.
    - To make it simple I put these classes into the MIDLet.

    I would really appreciate feedback on what's wrong with this implementation.

    // CLASS 1
    public class LocationRunClass implements Runnable {
    private MIDlet midlet;
    private LocationHandler lh;
    public Location loc;
    public int state;
    public boolean LocationExceptionStatus = false;
    public LocationRunClass() {

    new Thread(this).start();
    }

    public void run() {
    while (true) {
    try {
    Thread.sleep(500);
    } catch (InterruptedException e) {
    Alert alertUser = new Alert("Thread.sleep: ", e.getMessage() ,null,null);
    alertUser.setTimeout(5000);
    alertUser.setType(ERROR);
    Display.getDisplay(midlet).setCurrent(alertUser, GUIclass);
    }
    // Finally, Export Location or State to GUI class:
    if (loc != null){
    GUIclass.LocationRetriver(loc);
    loc = null;
    }
    if (state != 0) {
    GUIclass.LocationProviderStateRetriver(state, LocationExceptionStatus);
    state = 0;
    }
    } // while
    } //run

    public synchronized void locationChanged(Location l) {
    loc = l;
    }

    public synchronized void statusChanged(int status) {
    state = status;
    }
    }

    // CLASS 2
    public class LocationHandler implements LocationListener {
    private MIDlet midlet;
    private LocationRunClass locationRunClass;
    LocationProvider p;
    public int NO_REQUIREMENT = 0;
    public int GPS_HorizontalAccuracyRequested = 500;

    public LocationHandler(MIDlet midlet) {
    this.midlet = midlet;
    //************************************************
    // *********** Location Provider ***************
    //************************************************
    Criteria cr= new Criteria();
    cr.setHorizontalAccuracy(GPS_HorizontalAccuracyRequested);
    cr.setCostAllowed(true);
    cr.setPreferredPowerConsumption(NO_REQUIREMENT);
    try {
    p = LocationProvider.getInstance(cr);
    }
    catch (LocationException ex) {
    Alert alertUser = new Alert("LocationProvider: ", ex.getMessage() ,null,null);
    alertUser.setTimeout(5000);
    alertUser.setType(ERROR);
    Display.getDisplay(midlet).setCurrent(alertUser, GUIclass);
    }
    //************************************************
    // *********** Location Listener ***************
    //************************************************
    try{
    p.setLocationListener(this, 20, -1, -1);
    }
    catch (java.lang.IllegalArgumentException ex1) {
    Alert alertUser = new Alert("setLocationListener: ", ex1.getMessage() ,null,null);
    alertUser.setTimeout(5000);
    alertUser.setType(ERROR);
    Display.getDisplay(midlet).setCurrent(alertUser, GUIclass);
    }
    catch(java.lang.SecurityException ex2) {
    System.out.println("Ej tillstånd använda LocationListener");
    Alert alertUser = new Alert("setLocationListener: ", ex2.getMessage() ,null,null);
    alertUser.setTimeout(5000);
    alertUser.setType(ERROR);
    Display.getDisplay(midlet).setCurrent(alertUser, GUIclass);
    }
    }

    public void locationUpdated(LocationProvider p, Location l) {
    locationRunClass.locationChanged(l);
    }

    public void providerStateChanged(LocationProvider p, int s) {
    locationRunClass.statusChanged(s);
    }
    }

    Thank's in advance
    /Per

  9. #9
    Regular Contributor
    Join Date
    Mar 2009
    Posts
    80

    Re: setLocationListener problem

    I fixed it.
    I moved the listener to the other class.

    /P

  10. #10
    Super Contributor
    Join Date
    Apr 2007
    Posts
    2,708

    Re: setLocationListener problem

    Good to know, so you moved it from class 2 to class 1 ?
    I did notcie though that you were using a private LocationRunClass locationRunClass;
    But I couldn't find where you actually instantiate that object whilst you do use it in the locationUpdated method... This might lead to nullexceptions or strange behaviour...

  11. #11
    Regular Contributor
    Join Date
    Mar 2009
    Posts
    80

    Re: setLocationListener problem

    I instantiate the two classes from a special commandListener in the MIDlet.
    The location service is started as a result of a SVGmenu selection of one of the GUI classes.
    I.e. I start the location service right before switching the displayable the selected GUI class.

    Thank's
    /Per

Similar Threads

  1. STLPort namespace issue
    By yickhong in forum Open C/C++
    Replies: 0
    Last Post: 2009-04-09, 08:54
  2. SyncML link problem
    By samuel_ in forum Symbian
    Replies: 4
    Last Post: 2009-03-27, 08:02
  3. Problem with eglSwapBuffers and heap corruption
    By greatape in forum Symbian Media (Closed)
    Replies: 2
    Last Post: 2007-05-24, 03:35
  4. netcards - Problem with opening adapter
    By kernj in forum Symbian Tools & SDKs
    Replies: 5
    Last Post: 2007-01-10, 08:56
  5. Problem: S60 SDK for CW in PC with .NET
    By anttij in forum Carbide.c++ IDE and plug-ins (Closed)
    Replies: 1
    Last Post: 2005-02-28, 11:36

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×