Tom11
Tom11

Reputation: 2519

Toast in loop is not displaying properly

I have the following code in my main activity (Note: GPSTracker in this application works):

    double latitude, longitude;
    gps = new GPSTracker(MainActivity.this);
    if(gps.canGetLocation()){
         latitude = gps.getLatitude();
         longitude = gps.getLongitude();
         Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
    }
    else{
         gps.showSettingsAlert();
    }

I want to create a loop, which would display in some time intervals Toast with my current position. I´ve tried this:

    double latitude, longitude;
    long currentTime = System.currentTimeMillis();
    long myTimestamp = currentTime;
    int i = 0;
    gps = new GPSTracker(MainActivity.this);
    while(i < 5)
    {
        myTimestamp = System.currentTimeMillis();
        if((myTimestamp - currentTime) > 5000)
        {
            i++;
            currentTime = System.currentTimeMillis();
            if(gps.canGetLocation()){
                latitude = gps.getLatitude();
                longitude = gps.getLongitude();
                Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();  
            }else{
                gps.showSettingsAlert();
            }
        }
    }

With this code, Toast is shown only one time (the last iteration). Could you help me with this? Thanks in advance.

Upvotes: 0

Views: 1877

Answers (2)

Sam
Sam

Reputation: 86948

I want it to be shown every iteration (for example every 5 seconds).

The code above doesn't loop every five seconds, it loops continuously but only increments your counter every five seconds... This is a very inefficient way of creating a time delay because nothing else can happen while the loop runs. (Even if you run this on a separate thread it is still not good tactic.)

Instead use LocationManager's requestLocationUpdates which will use callbacks so your app can do things between updates. A couple quick notes:

  • Understand that the GPS may not be able to get a fix every five seconds and that this interval is really short so use it sparingly or you'll run the battery down.
  • Some pre-Jelly Bean devices may not observe the minTime parameter, but you can enforce your time parameter yourself as I describe in Android Location Listener call very often.

All that aside, you use your existing code but I recommend a Handler and Runnable, like this:

handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        // Fetch your location here

        // Run the code again in about 5 seconds
        handler.postDelayed(this, 5000);
    }
}, 5000);

Upvotes: 1

Bradford Needham
Bradford Needham

Reputation: 681

One problem is that this method does a 'busy-wait', which, I suspect, prevents the toast from being displayed. Try doing a sleep() to wait until it's time for the next Toast:

public void sleepForMs(long sleepTimeMs) {
    Date now = new Date();
    Date wakeAt = new Date(now.getTime() + sleepTimeMs);
    while (now.before(wakeAt)) {
        try {
            long msToSleep = wakeAt.getTime() - now.getTime();
            Thread.sleep(msToSleep);
        } catch (InterruptedException e) {
        }

        now = new Date();
    }

}

Upvotes: 0

Related Questions