At the moment I'am working on project to messure frequency with gps :-). I like to get the gps information as soon as possible from GPS/Wifi. I also want to get it in the most highest frequency as possible. My goal is to messure a frequency from this data. At the moment I try it this way
final public void run() {
Looper.prepare();
while(gps){
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocationListener);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
try {
Thread.sleep(100) ;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mLocationManager.removeUpdates(mLocationListener);
}
Looper.loop();
}//run
Is there a better way to get a faster "samplerate"?
From http://developer.android.com/guide/topics/location/obtaining-user-location.html:
You can control the frequency at which your listener receives updates with the second and third parameter—the second is the minimum time interval between notifications and the third is the minimum change in distance between notifications—setting both to zero requests location notifications as frequently as possible.
requestLocationUpdates gives you what you want. Not sure what you're trying to do with the while loop.
Get lat long using GPS in every 10 min.
// Des: Start Device's GPS and get current latitude and longitude
public void GPS() throws IOException {
// Des: This is a background service and called after every 10 minutes and fetch latitude-longitude values
background = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < j; i++) {
if (ProjectStaticVariable.GPSExit == true ) {
try {
Thread.sleep(600000); //10 minutes
mainhandler.sendMessage(mainhandler.obtainMessage());
j++;
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
}
});
background.start();
mainhandler = new Handler() {
public void handleMessage(Message msg) {
// Check Internet status
isInternetPresent = cd.isConnectingToInternet();
if (isInternetPresent) {
lat_long_Service_flag = true;
mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener(getApplicationContext());
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000, 0, mlocListener);
mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
}
};
}
// Des: Location Listener through which we get current latitude and longitude
public class MyLocationListener implements LocationListener {
public MyLocationListener(Context mContext) {}
public MyLocationListener(Runnable runnable) {}
#Override
public void onLocationChanged(Location loc) {
longitude = loc.getLongitude();
latitude = loc.getLatitude();
final_latitude = Double.toString(latitude);
final_longitude = Double.toString(longitude);
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
Related
I have a service that needs to know the phone's location. The main activities of the service are carried out in a thread as follows (with processing stuff removed:
Semaphore locationAcquired = new Semaphore(1);
LocationFinder finder;
...
public void run() {
delaySeconds = 60;
Looper.prepare();
while (true) {
try {
finder.StartFinder();
locationAcquired.acquire();
// do some stuff...
} catch (InterruptedException e) {
if (isDestroy) {
Log.d(TAG, "Closing Monitor Thread");
break;
} // else just wake up and process the location
} catch (Exception e) {
e.printStackTrace();
}
} // end while
} // end run
The LocationFinder class implementation (again, slightly simplified):
package com.ksdagile.opengate;
import...
public class LocationFinder {
public static final int ONE_SECOND = 1000;
LocationListener locationListener;
String provider = LocationManager.PASSIVE_PROVIDER; // passive by default
LocationManager locationManager;
public Location currentLocation;
long updateSeconds;
private boolean isLooking = false;
OpenGateService openGateService;
public LocationFinder(LocationManager _lm, OpenGateService _openGateService) {
openGateService = _openGateService;
locationManager = _lm;
// initialize with whatever location might be available
currentLocation = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
// A new location update is received. Do something useful with it. In this case,
// we're sending the update to a handler which then updates the UI with the new
// location.
currentLocation = location;
String newLoc = String.format("Found new Location lat:%.2f long:%.2f", currentLocation.getLatitude(), currentLocation.getLongitude());
Log.d(getClass().getName(), newLoc);
openGateService.locationAcquired.release();
}
// simple implementations of onProvider<> etc.
};
}
public void SetProvider(boolean isActive) {
if (isActive)
provider = LocationManager.GPS_PROVIDER;
else
provider = LocationManager.PASSIVE_PROVIDER;
}
public void SetFrequency(long delay) {
updateSeconds = delay;
}
public void StartFinder() {
if (!isLooking) {
isLooking = true;
locationManager.requestLocationUpdates(provider, updateSeconds*ONE_SECOND, 10, locationListener);
Log.d(getClass().getName(), String.format("Request location from %s provider, every %d sec.", provider, updateSeconds));
} else
Log.d(getClass().getName(), "Location request running");
}
public void StopFinder() {
locationManager.removeUpdates(locationListener);
isLooking = false;
}
public boolean IsLocating() {
return isLooking;
}
}
My problem is that the onLocationChanged routine is not called, even though I know there are new readings. For example, when configured to read in Passive Mode, I run Waze and see myself moving. Is it possible that the call to onLocationChanged being blocked by the semaphore? If so, how do I get around this? I want to be able to change the parameters for requestLocationUpdate dynamically.
I think getting a tumbleweed badge is a very dubious honor, but here is the answer:
Yes, the .acquire() call blocks the thread, and the onLocationChanged() method is not called.
The solution is to have a handler run a runnable, such as:
public void onLocationChanged(Location location) {
xxxService.locHandler.post(xxxService.locationRun);
}
where
Runnable locationRun = new Runnable() {
#Override
public void run() {
// handle stuff for new location
}
};
The general principle is that you send and handle events, rather than running a polling loop. If you need to handle a non-event, e.g. no new location read, then you set up a countdown timer.
i'm trying to get user's current location via the code, the basic idea is like this:
public class LocationProducer extends Thread {
// Timer timer1;
LocationManager lm;
boolean gps_enabled = false;
UpdateInterface mUpdateInterface;
private Looper mThreadLooper;
private Handler mHandler;
public LocationProducer(Context context, UpdateInterface updateInterface,
String name) {
super(name);
mContext = context;
mUpdateInterface = updateInterface;
}
public void run() {
Looper.prepare();
if (lm == null)
lm = (LocationManager) mContext
.getSystemService(Context.LOCATION_SERVICE);
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
}
if (gps_enabled) {
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
locationListenerGps);
}
Log.d(TAG, "requestLocationUpdates int thread:"
+ Thread.currentThread().getName());
// timer1 = new Timer();
// timer1.schedule(new GetLastLocation(), MAXWAITTIME);
mThreadLooper = Looper.myLooper();
mHandler = new Handler();
mHandler.postDelayed(GetLastLocation, MAXWAITTIME);
Looper.loop();
}
public void quitLooper() {
lm.removeUpdates(locationListenerGPSLongTimeRun);
lm.removeUpdates(locationListenerNetworkLongTimeRun);
mThreadLooper.quit();
// mHandler.getLooper().quit();
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
Log.d(TAG,
"get location int short time run locationlistenerGPS, in thread"
+ Thread.currentThread().getName());
// timer1.cancel();
mHandler.removeCallbacks(GetLastLocation);
mUpdateInterface.update(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,
MINUPDATETIME, MINUPDATEDISTANCE,
locationListenerGPSLongTimeRun);
if (network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
MINUPDATETIME, MINUPDATEDISTANCE,
locationListenerNetworkLongTimeRun);
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
the basic idea is to get user location. i have to use looper to regist a listener in a non UI thread, but when i get handler of this loop. i found that the thread just wait,in nativePollOnce as
so if new gps location update comes ,the listener just don't work anymore.
is there any way to make the listener work again ? thank you very much.
hi there can anybody give me a sample code for get location for every five minutes please i have tried and i can get location once by cliking on button,
but i need it to be displayed once for five minutes.
thank you
this is my code :
public void checkLocation(View v) {
//initialize location manager
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//check if GPS is enabled
//if not, notify user with a toast
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Toast.makeText(this, "GPS is disabled.", Toast.LENGTH_SHORT).show();
} else {
//get a location provider from location manager
//empty criteria searches through all providers and returns the best one
String providerName = manager.getBestProvider(new Criteria(), true);
Location location = manager.getLastKnownLocation(providerName);
TextView tv = (TextView)findViewById(R.id.locationResults);
if (location != null) {
tv.setText(location.getLatitude() + " latitude, " + location.getLongitude() + " longitude");
} else {
tv.setText("Last known location not found. Waiting for updated location...");
}
//sign up to be notified of location updates every 15 seconds - for production code this should be at least a minute
manager.requestLocationUpdates(providerName, 15000, 1, this);
}
}
#Override
public void onLocationChanged(Location location) {
TextView tv = (TextView)findViewById(R.id.locationResults);
if (location != null) {
tv.setText(location.getLatitude() + " latitude, " + location.getLongitude() + " longitude");
} else {
tv.setText("Problem getting location");
}
}
#Override
public void onProviderDisabled(String arg0) {}
#Override
public void onProviderEnabled(String arg0) {}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {}
// Find the closest Bart Station
public String findClosestBart(Location loc) {
double lat = loc.getLatitude();
double lon = loc.getLongitude();
double curStatLat = 0;
double curStatLon = 0;
double shortestDistSoFar = Double.POSITIVE_INFINITY;
double curDist;
String curStat = null;
String closestStat = null;
//sort through all the stations
// write some sort of for loop using the API.
curDist = Math.sqrt( ((lat - curStatLat) * (lat - curStatLat)) +
((lon - curStatLon) * (lon - curStatLon)) );
if (curDist < shortestDistSoFar) {
closestStat = curStat;
}
return closestStat;
}
Here is the code for getting location and set the listener for gps to get current location on few minute and distance, also I have used runnable object to get the location on every few minutes.
Location gpslocation = null;
private static final int GPS_TIME_INTERVAL = 60000; // get gps location every 1 min
private static final int GPS_DISTANCE= 1000; // set the distance value in meter
/*
for frequently getting current position then above object value set to 0 for both you will get continues location but it drown the battery
*/
private void obtainLocation(){
if(locMan==null)
locMan = (LocationManager) getSystemService(LOCATION_SERVICE);
if(locMan.isProviderEnabled(LocationManager.GPS_PROVIDER)){
gpslocation = locMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(isLocationListener){
locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER,
GPS_TIME_INTERVAL, GPS_DISTANCE, GPSListener);
}
}
}
}
Now use this method to get the current location and the listener was called on location change with every 1 min and 1000 meter of distance.
For getting every 5 min you can use this handler and runnable to get this location on well set period time:
private static final int HANDLER_DELAY = 1000*60*5;
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
myLocation = obtainLocation();
handler.postDelayed(this, HANDLER_DELAY);
}
}, START_HANDLER_DELAY);
Here is GPS listener for location change event:
private LocationListener GPSListener = new LocationListener(){
public void onLocationChanged(Location location) {
// update location
locMan.removeUpdates(GPSListener); // remove this listener
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
You can set interval time for listener and handler same for getting GPS location.
Hi Use the below timer code.
You can use the below options
option 1
this will get the locations if mobile moved 100meters.
captureFrequencey=3*60*1000;
LocationMngr.requestLocationUpdates(LocationManager.GPS_PROVIDER, captureFrequencey, 100, this);
have a look at this link http://developer.android.com/reference/android/location/LocationManager.html#requestLocationUpdates%28java.lang.String,%20long,%20float,%20android.location.LocationListener%29
Option 2
TimerTask refresher;
// Initialization code in onCreate or similar:
timer = new Timer();
refresher = new TimerTask() {
public void run() {
handler.sendEmptyMessage(0);
};
};
// first event immediately, following after 1 seconds each
timer.scheduleAtFixedRate(refresher, 0,1000);
//=======================================================
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case REFRESH:
//your code here
break;
default:
break;
}
}
};
Timer will call the handler for your time duration (change 1000 into your required time ).
Hope this will help you.
I used runnable for doing this,
final Runnable r = new Runnable() {
public void run() {
//Here add your code location listener call
handler.postDelayed(this, 300000 );
}
};
handler.postDelayed(r, 300000 );
try like this:
private Handler handler = new Handler();
handler.postDelayed(runnable, 300000);
private Runnable runnable = new Runnable() {
public void run() {
if (location != null) {
onLocationChanged(location);
} else {
System.out.println("Location not avilable");
}
handler.postDelayed(this, 300000);
}
};
This question already has answers here:
What is the simplest and most robust way to get the user's current location on Android?
(28 answers)
Closed 9 years ago.
What is the best way to get the current location in android for the following scenario,
If GPS is not available, get location from Network provider
If GPS is available and can get current location, get location from GPS provider
If GPS is available but can't get current location(i.e continuously searching location), get location from the network provider.
now i can getting a location from network if gps not available, the best answer to satisfy the above scenario is highly appreciated. thanks in advance.
Well, you can use Timer and TimerTask classes.
LocationManager manager;
TimerTask mTimertask;
GPSLocationListener mGPSLocationListener;
int i = 0; //Here i works as counter;
private static final int MAX_ATTEMPTS = 250;
public void getCurrentLocation() {
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mGPSLocationListener = new GPSLocationListener();
manager.addGpsStatusListener(mGPSStatusListener);
mTimerTask = new LocTimerTask(LocationManager.GPS_PROVIDER);
if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Log.v(TAG, "GPS ENABLED");
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L,
50.0f, mGPSLocationListener);
} else {
turnGPSOn();
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L,
50.0f, mGPSLocationListener);
}
if(manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000L,
50.0f, mNetworkLocationListener);
}
if (manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
Log.v(TAG, "GPS ENABLED");
manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
1000L, 50.0f, mGPSLocationListener);
}
myLocTimer = new Timer("LocationRunner", true);
myLocTimer.schedule(mTimerTask, 0, 500);
}
GPSStatusListener
private GpsStatus.Listener mGPSStatusListener = new GpsStatus.Listener() {
#Override
public synchronized void onGpsStatusChanged(int event) {
switch (event) {
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
Log.v(TAG, "GPS SAtellitestatus");
GpsStatus status = manager.getGpsStatus(null);
mSattelites = 0;
Iterable<GpsSatellite> list = status.getSatellites();
for (GpsSatellite satellite : list) {
if (satellite.usedInFix()) {
mSattelites++;
}
}
break;
case GpsStatus.GPS_EVENT_FIRST_FIX:
/*
* Toast.makeText(getApplicationContext(), "Got First Fix",
* Toast.LENGTH_LONG).show();
*/
break;
case GpsStatus.GPS_EVENT_STARTED:
/*
* Toast.makeText(getApplicationContext(), "GPS Event Started",
* Toast.LENGTH_LONG).show();
*/
break;
case GpsStatus.GPS_EVENT_STOPPED:
/*
* Toast.makeText(getApplicationContext(), "GPS Event Stopped",
* Toast.LENGTH_LONG).show();
*/
break;
default:
break;
}
}
};
LocationListener
public class GPSLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location argLocation) {
location = argLocation;
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
TimerTask class
class LocTimerTask extends TimerTask {
String provider;
public LocTimerTask(String provider) {
this.provider = provider;
}
final Handler mHandler = new Handler(Looper.getMainLooper());
Runnable r = new Runnable() {
#Override
public void run() {
i++;
Log.v(TAG, "Timer Task run" + i);
location = manager.getLastKnownLocation(provider);
if (location != null) {
Log.v(TAG, "in timer task run in if location not null");
isGPS = true;
onLocationReceived(location);
myLocTimer.cancel();
myLocTimer.purge();
mTimerTask.cancel();
return;
} else {
Log.v(TAG, "in timer task run in else location null");
isGPS = false;
if (location == null && i == MAX_ATTEMPTS) {
Log.v(TAG, "if 1 max attempts done");
turnGPSOff();
location = manager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
Log.v(TAG,
"if 1 max attempts done Location from network not null");
Log.v(TAG,
"if 1 max attempts done Location from network not null coordinates not null");
onLocationReceived(location);
myLocTimer.cancel();
myLocTimer.purge();
mTimerTask.cancel();
return;
}
} else {
return;
}
}
i = 0;
}
};
public void run() {
mHandler.post(r);
}
}
Here the timer has been scheduled to run on every 500 milliseconds. Means, on every 500 milliseconds the timer task's run method will executed. In run method try get location from GPS provider for specific no. of attempts(Here MAX_ATTEMPTS) say 5 or 10. If it gets location within specified no. of attempts then use that location else if counter(Here i) value has exceeded MAX_ATTEMPTS, then get location from Network Provider. on getting location, I had passed that location to callback method onLocationReceived(Location mLoc) in which you can do your further work with location data. Here's how you will use callback method:
Listener
public interface OnLocationReceivedListener {
public void onLocationReceived(Location mLoc); //callback method which will be defined in your class.
}
Your class should implement the above defined listener. In your class:
#Override
public void onLocationReceived(Location mLoc) {
//Do your stuff
}
Hope it helps. If anybody have a better approach, then please let me know.
If GPS is available and can get current location,
For the above question you can try like this..
Using this you can get the latitude and longitude for the current location then pass the value to get the map.
public class MyLocationListener implements LocationListener
{
#Override
public void onLocationChanged(Location loc)
{
loc.getLatitude();
loc.getLongitude();
String Text = “My current location is: “ +
“Latitud = “ + loc.getLatitude() +
“Longitud = “ + loc.getLongitude();
Toast.makeText( getApplicationContext(),
Text,
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider)
{
Toast.makeText( getApplicationContext(),
“Gps Disabled”,
Toast.LENGTH_SHORT ).show();
}
#Override
public void onProviderEnabled(String provider)
{
Toast.makeText( getApplicationContext(),
“Gps Enabled”,
Toast.LENGTH_SHORT).show();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
}
class member boolean mIsGpsFix;
Request Gps location update and set up a countdown timer
mCountDown.start();
private CountDownTimer mCountDown = new CountDownTimer(time to wait for Gps fix, same as right)
{
#Override
public void onTick(long millisUntilFinished)
{
}
#Override
public void onFinish()
{
// No fix after the desire amount of time collapse
if (!mIsGpsFix)
// Register for Network
}
};
I can get longitude and latitude by network provider, but unable to get it by GPS. How can I do that?
public void onCreate(Bundle savedInstanceState) {
...
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (mLocation != null) {
gp1 = getGeoByLocation(mLocation);
gp2 = gp1;
refreshMapView();
if( !mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 2000,
10, mLocationListener);
}else{
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000,
10, mLocationListener);
}
private GeoPoint getGeoByLocation(Location location) {
GeoPoint gp = null;
try {
if (location != null) {
double geoLatitude = location.getLatitude() * 1E6;
double geoLongitude = location.getLongitude() * 1E6;
gp = new GeoPoint((int) geoLatitude, (int) geoLongitude);
}
} catch (Exception e) {
e.printStackTrace();
}
return gp;
}
Get lat long using GPS in every 10 min.
// Des: Start Device's GPS and get current latitude and longitude
public void GPS() throws IOException {
// Des: This is a background service and called after every 10 minutes and fetch latitude-longitude values
background = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < j; i++) {
if (ProjectStaticVariable.GPSExit == true ) {
try {
Thread.sleep(600000); //10 minutes
mainhandler.sendMessage(mainhandler.obtainMessage());
j++;
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
}
});
background.start();
mainhandler = new Handler() {
public void handleMessage(Message msg) {
// Check Internet status
isInternetPresent = cd.isConnectingToInternet();
if (isInternetPresent) {
lat_long_Service_flag = true;
mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener(getApplicationContext());
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000, 0, mlocListener);
mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
}
};
}
// Des: Location Listener through which we get current latitude and longitude
public class MyLocationListener implements LocationListener {
public MyLocationListener(Context mContext) {}
public MyLocationListener(Runnable runnable) {}
#Override
public void onLocationChanged(Location loc) {
longitude = loc.getLongitude();
latitude = loc.getLatitude();
final_latitude = Double.toString(latitude);
final_longitude = Double.toString(longitude);
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}