How to make a function executino wait in android - android

I am new to android programming. So please forgive me if it is a stupid question.
In my app,I am trying to develop a feature that if the location services would be turned off in a phone, then the app would prompt the user to turn it on by taking them to the location settings page on click of a button. The problem is that after turning on the location settings the phone is taking some time to give the location coordinates due to which the fragment that is suppose to show the coordinates is remaining empty for the same amount of time and is creating a confusion.
What I want to know is, if there is any way that I can schedule the execution of the function which is fetching the location coordinates after being sure that there is some coordinates to fetch.
I am using "getLastKnowLocation()". The code for fetching the location is below:-
public String getLocation()
{
// Get the location manager
LocationManager locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String bestProvider = locationManager.getBestProvider(criteria, false);
android.location.Location location = locationManager.getLastKnownLocation(bestProvider);
Double lat,lon;
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
try {
lat = location.getLatitude ();
lon = location.getLongitude ();
}
catch (NullPointerException e){
}
}

Create a boolean variable locationLoaded. In your following lines of code:
try {
lat = location.getLatitude ();
lon = location.getLongitude ();
//set the value of variable to true once you get location
locationLoaded=true;
}
catch (NullPointerException e){
}
Then create a new recursive method, which will keep checking for location, until it is not loaded, like this:
private void keepCheckingLocation(){
if(locationLoaded){
//location is loaded
return;
}
else{
//location is not loaded yet
try {
//wait for two seconds
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//call the method again to check the location
keepCheckingLocation();
}
}
Once you have called this method, it won't let the next line of code execute until the locationLoaded is not true and locationLoaded will only be true, once the location is loaded. So you can use this method whenever you want to wait for the location to get loaded.
Note: Set locationLoaded=false; if you have to check for locations again. It will make code more efficient.

Related

LocationListener takes too long until first result

I've encountered a problem. If I turn off GPS, and then turn it on again - getLastKnownLocation() returns null.
In that case the only way to get current coordinates is the LocationListener. (Correct me if I'm wrong).
So I called the listener :
locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 10, (float) 0.01, locationListener );
.....
public void onLocationChanged(final Location loc)
{
try {
addresses = geoCoder.getFromLocation( loc.getLatitude(), loc.getLongitude(), 1);
if (addresses.size() > 0)
{
String cityName = addresses.get(0).getLocality();
String streetName = addresses.get(0).getAddressLine(0);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
It takes about a whole minute(!) to find the location. Although once it finds it , it then updates it every second. But it still doesn't help me much.
I need to find the current coordinates as quickly as possible. How can that be done ? and why does it take the onLocationChanged is called so slowly the first time but much quicker the following times?
If the app needs more accurate and fresh location, use gps provider. Gps provider must be warmed up before getting locations. So being warmed up takes time and changes by where you are. You could use cached gps location calling getLastKnownLocation("gps") until gps hardware warmed up, and check this is too old or not.

Android LocationManager.removeUpdates(LocationListener)

hi guys I have created a background service which gets the person location and if the distance between the device to the destination is smaller i request location updates more often and I am using the removeUpdates(LocationListener) method... the problem is that i noticed that the listener keeps getting updates and the more the loop is going it keeps get more and more updates. does anyone have any idea why this method doesn't work?
Here is my method for using the new location.
void makeUseOfNewLocation(Location location){
manager.removeUpdates(listener);
mLocation = location;
currentLat = location.getLatitude();
currentLong = location.getLongitude();
Location.distanceBetween(currentLat, currentLong, gateLat, gateLong, results);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
currentDistanceFromDestination = results[0];
Log.d("Current Location", "Lat:"+currentLat+" Long:"+currentLong);
Log.d("Destination Distance", currentDistanceFromDestination+"");
if(currentDistanceFromDestination<3000){
if(currentDistanceFromDestination<50){
Log.d("50m closer", "Calling");
startActivity(callIntent);
stopSelf();
}
if(currentDistanceFromDestination<800){
Log.d("800m closer", "Started listening every 10 seconds.");
Toast.makeText(getApplicationContext(),currentDistanceFromDestination+"", Toast.LENGTH_LONG).show();
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10 ,90 , listener);
}else{
Log.d("3000m closer", "Started listening every 25 seconds");
Toast.makeText(getApplicationContext(),currentDistanceFromDestination+"", Toast.LENGTH_LONG).show();
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 25 * 1000, 300, listener);
}
}
}
Do you initiate the value of your listener between calls?
it might not be the same object so it cannot remove updates to it.
In that case the old listener will still be getting updates with you unable to remove them.

Trying to get latitude and latitude with Network provider

I am trying to get my current coordinates with network provider and not gps provider.
I was able to figure out the solution for that but I am a bit confused with the concept in this scenario.
Working Code
Here's my code for getting my coordinates:
public void getLocation(){
locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
if(appUtils.isOnline()){
try{
Geocoder geocoder = new Geocoder(
MainActivity.this.getApplicationContext(),
Locale.getDefault());
Location locationNetwork = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
List<Address> list;
if(locationNetwork!=null){
Toast.makeText(context,"Network Available!!",Toast.LENGTH_LONG).show();
list = geocoder.getFromLocation(locationNetwork.getLatitude(),locationNetwork.getLongitude(),3);
if(list!=null&&list.size()>0){
latitude = list.get(0).getLatitude();
longitude = list.get(0).getLongitude();
Toast.makeText(context,String.valueOf(latitude) + " (....) " + String.valueOf(longitude),Toast.LENGTH_LONG).show();
int count = 0;
while (latitude==null||longitude==null){
latitude = list.get(count).getLatitude();
longitude = list.get(count).getLongitude();
count++;
Toast.makeText(context,String.valueOf(latitude) + " --- " + String.valueOf(longitude),Toast.LENGTH_LONG).show();
}
}
}else{
Toast.makeText(context,"No response!!",Toast.LENGTH_LONG).show();
}
}catch (IOException e){
e.printStackTrace();
}
}else{
Toast.makeText(context,"Server not responding",Toast.LENGTH_LONG).show();
}
}
This piece of code is working perfectly fine when the gps is enabled. If gps is disabled, it doesn't work.
Now, if we are setting the location to NETWORK_PROVIDER:
Location locationNetwork = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Why do we still require gps ?
Now if I change it to PASSIVE PROVIDER:
Location locationNetwork = locationManager
.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
It works fine with the passive provider. Why is it that ?
Can someone explain what is the major difference here and what would be the right way to get the coordinates with network provider ?
I know this question is been asked several times and I did went through it. I just want to get cleared with this concept.
Thank's in advance.. :)
It doesn't require GPS to use the network provider, I've done it many times. However, getLastKnowLocation may not return a value if either it has never had an app request updates for that provider, or if the last time that happened was too long ago. You cannot count on that function always returning non-NULL. If you want to ensure that you get a location, use requestSingleUpdate instead. This will always get you a location (assuming the provider you use is enabled), but may take some time- a result may not be immediately available.
(There is one other time that function may never return- if you use the GPS provider and it can't get a lock on enough sattelites to find a location. Such as if you're in an underground parking garage).
This is the bit of code that I use to quickly get the current location, by checking all available network options.
private double[] getGPS(){
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
List<String> providers = lm.getProviders(true);
/* Loop over the array backwards, and if you get an accurate location, then break out the loop*/
Location l = null;
for (int i=providers.size()-1; i>=0; i--) {
l = lm.getLastKnownLocation(providers.get(i));
if (l != null) break;
}
double[] gps = new double[2];
if (l != null) {
gps[0] = l.getLatitude();
gps[1] = l.getLongitude();
}
return gps;
}

Latitude and Longitude always getting zero (GPS and TimerTask)

Below is the code I used for getting longitude and latitude within a timertask.
public void onClick(View v) {
isInternetPresent = cd.isConnectingToInternet();
if (isInternetPresent) {
try {
gpt = new GPSTracker(MainActivity.this);
System.out.println("Internet is present");
setContentView(R.layout.tracklayout);
TimerTask myTask = new TimerTask() {
#Override
public void run() {
try {
Log.d("flow", "" + "task()");
gpt = new GPSTracker(MainActivity.this);
lc = gpt.getLocation();
if (gpt.canGetLocation()) {
double latitude = gpt.getLatitude();
double longitude = gpt.getLongitude();
Log.d("latitude", "" + latitude);
Log.d("longitude", "" + longitude);
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),"Reached.. ",Toast.LENGTH_LONG).show();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
};
Timer myTimer = new Timer();
myTimer.schedule(myTask, 3000, 30000);
} catch (Exception e) {
e.printStackTrace();
}
} else {
alert.showAlertDialog(MainActivity.this,"Mobile Data is Off","Please Turn On mobile data to proceed", false);
}
}
});
Latitude and longitude are always getting zero even I manually entered co-ordinates through DDMS. There no problem with the code of GPSTracker. Outside timertask it worked fine. What is the problem with this code. Anyone please help
As you are using GPSTracker ,If GPS is not working than you can not have lat and long values for sure, you can't get an accurate location. It may take few minutes or seconds because it depends on lot of constraints like yours position inside building, weather , you device hardware quality etc as you are using sattelite to have locations, So we can say thatit depends on the device and the environment settings ( weather, Location under the sky/inside or outside building,device hardware quality etc as an example).
Why you are not using NETWORK_PROVIDER ?? if you can...
If you want to get a coarse location faster with program than you can get the location using NETWORK_PROVIDER, which isn't that accurate but can get you the location very faster.
Visit for examples
http://www.vogella.com/tutorials/AndroidLocationAPI/article.html
http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial/
http://developer.android.com/guide/topics/location/strategies.html
Don't use timertask. Implement LocationListener with that activity. Write the codes in the timertask to OnLocation changed. Not needed to run in paricular time interval because we get the same data if we are in same location.

Location mapping not returning on different devices

I have this code for getting the long and lat coordinates.
String bestProvider;
LocationManager lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
bestProvider = lm.getBestProvider(criteria, true);
Location location = lm.getLastKnownLocation(bestProvider);
if (location == null){
}else{
geocoder = new Geocoder(this);
try {
setLat((double)location.getLatitude());
setLng((double)location.getLongitude());
}catch (Exception e) {
e.printStackTrace();
}
}
I tried using different devices. Some returns a value for lat and long. Some do not. All devices were connected to the internet and gps enabled. Do you guys have any idea on what is causing this? Thanks!
It is due to getLastKnownLocation which may or may not exists. I suggest you to request single location update. Also remember that lastknownlocation is not necessarily accurate one it may belong to 2 days before.
dev guide:
http://developer.android.com/reference/android/location/LocationManager.html
A guide about single update
http://androidexperinz.wordpress.com/2012/04/19/current-location-update/
If there is no previous captured location, then getlastknown location does not return any value.So you need to implement the location listener to capture the location.

Categories

Resources