I'm trying to build an Android app that gets the location in the background the whole time the device is powered on.
Its used in a business situation and is permanently powered, so battery consumption is irrelevant.
On device boot, I enable a PARTIAL_WAKE_LOCK, and start a location service which starts requesting location updates.
Intent intentLocation = new Intent(context, LocationService.class);
context.startService(intentLocation);
In the onLocationChanged method I am processing the data.
But after a random amount of time, it could be half a day, or a couple of days, the app stops getting location updates.
When the app stops getting location updates, I either need to reboot the device or stop the app and start it again.
I assume Android is killing the process and its not restarting correctly even though I've specified START_STICKY?
Do I need to get location data in another thread or is there something else that I can do to ensure the location updates continue to come through?
This is my location class.
public class LocationService extends Service implements LocationListener {
public Context context;
private static final String TAG = "LocationService";
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location; // location
// Declaring a Location Manager
protected LocationManager locationManager;
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 10000;
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0;
/*
* Callback that fires when the location changes.
*/
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged called");
locationBroadcast(location);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT).show();
}
#SuppressWarnings("MissingPermission")
public Location getLocation() {
try {
locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
Toast.makeText(getApplicationContext(), "Turn on location services", Toast.LENGTH_SHORT).show();
} else {
this.canGetLocation = true;
// First get location from Network Provider
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d(TAG, "Network GPS provider being used");
}
// if GPS Enabled get location using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d(TAG, "GPS provider being used");
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.d(TAG, "Received start id " + startId + ": " + intent);
return START_STICKY;
}
#Override
public void onCreate() {
Log.d(TAG, "onCreate");
context = this;
getLocation();
}
#Override
public void onDestroy() {
Log.e(TAG, "onDestroy");
super.onDestroy();
locationManager.removeUpdates(this);
}
private void locationBroadcast(Location currentLocation) {
Intent intent = new Intent("gpsdata");
sendLocationBroadcast(intent, currentLocation);
}
private void sendLocationBroadcast(Intent intent, Location currentLocation){
JSONObject locationData = new JSONObject();
try {
locationData.put("latitude", currentLocation.getLatitude());
locationData.put("longitude", currentLocation.getLongitude());
locationData.put("altitude", Math.round(currentLocation.getAltitude()));
locationData.put("accuracy", Math.round(currentLocation.getAccuracy()));
locationData.put("speed", Math.round(currentLocation.getSpeed()));
} catch (JSONException e) {
Log.e(TAG, e.toString());
}
intent.putExtra("locationobject", locationData.toString());
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
Related
I have a service that get the location of my phone. When i turn the GPS off and turn it on again, i can't get the location anymore.
Some times it return null the latitude and longitude but GPS is on...
I have a checkbox when i check it, it begin to send to my server the latitude and longitude of my device.
Here is the code. Can someone help me to optimize my code please?
SERVICE
public class LocalizationService extends Service implements Runnable {
private static final int tempo = (30 * 1000); // 1800
private LocationManager locationManager = null;
private Thread t;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (t == null || !t.isAlive()) {
t = new Thread(this, "ServicoId: " + startId);
t.start();
}
return Service.START_STICKY;
}
#Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
sendLocation();
Thread.sleep(tempo);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void sendLocation() {
LatLng latlong = getLocation();
PolifreteApplication manager = (PolifreteApplication) getApplicationContext();
Veiculo veiculo = manager.getTransportador().getVeiculo();
int user = manager.getTransportador().getCodigo();
if (latlong == null) {
} else {
veiculo.setLatitude(latlong.latitude + "");
veiculo.setLongitude(latlong.longitude + "");
VeiculoDAL.SendLocationVeiculo(veiculo, user);
}
}
public LatLng getLocation() {
// Get the location manager
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
String bestProvider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(bestProvider);
Double lat, lon;
try {
lat = location.getLatitude();
lon = location.getLongitude();
return new LatLng(lat, lon);
} catch (NullPointerException e) {
e.printStackTrace();
return null;
}
}
}
ACTIVITY METHOD
public void onCheckboxClicked(View view) {
if (WebService.conexaoOk()) {
CheckBox cblocalizacao = (CheckBox) findViewById(R.id.checkboxlocalizacao);
boolean checked = ((CheckBox) view).isChecked();
locationManager = (LocationManager) this
.getSystemService(Context.LOCATION_SERVICE);
boolean isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
switch (view.getId()) {
case R.id.checkboxlocalizacao:
if (checked && !isGPSEnabled) {
cblocalizacao.setChecked(false);
showSettingsAlert();
} else if (checked && isGPSEnabled) {
Intent i = new Intent(this, LocalizationService.class);
this.startService(i);
} else {
cblocalizacao.setChecked(false);
}
}
}
}
If you want to get location from Gps, see this link, http://www.androidhive.info/2012/07/android-Gps-location-manager-tutorial/, getting location from Gps is not instantaneous, you need to implement location listener and wait the call back from the Gps provider:
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
or you can use network provider
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Just visit the link, and you will find the best strategy to get the most accurate possible location..
This video from Udacity gives idea about using the location services in GoogleApiClient.
Since your LocationListener tries to get location using only Network not GPS, with this code snippet: locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
probably you are getting latitude and longitude values but with a delay. I had the same problem then I begin to use new/latest Location service API and use:
GoogleApiClient.
First you need to implement
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener
from you activity that want to fetch the location data.
Define
private GoogleApiClient mGoogleApiClient;
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
If you haven't add
<uses-permission `android:name="android.permission.ACCESS_FINE_LOCATION"/>`
to the manifest file, add that.
For further documentation : https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient
More comprehensive answer about GoogleClientApi:
https://stackoverflow.com/a/33599343/2644905
I am trying to create an app that shows my current location
I have all the permisson neccessary,
I have another class name GPS tracker to get my gps locations
Heres my code :
GPSTracker gpsTracker = new GPSTracker(this);
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
latitude = gpsTracker.latitude;
longitude = gpsTracker.longitude;
LatLng latLng = new LatLng(latitude, longitude);
map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
map.animateCamera(CameraUpdateFactory.zoomTo(18));
Here is the GPSTracker class:
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
// First get location from Network Provider
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
/**
* Stop using GPS listener
* Calling this function will stop using GPS in your app
* */
public void stopUsingGPS(){
if(locationManager != null){
locationManager.removeUpdates(GPSTracker.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
* #return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog
* On pressing Settings button will lauch Settings Options
* */
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS is settings");
// Setting Dialog Message
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing Settings button
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
DO NOT USE THE GPS TRACKER CLASS. It's horribly horribly broken. In so many ways I wrote a long blog post about it tonight: see http://gabesechansoftware.com/location-tracking/
Here's the ways its broken:
1)It doesn't track GPS. Sometimes it tracks network location instead
2)The canGetLocation function is broken. It returns true before it has a location
3)Its horribly inefficient, forcing you to poll.
4)It doesn't differentiate stale from fresh data- and doesn't let you do it either
I'd go on but I already wrote it up tonight.
I wrote a much better GPS tracker library at my blog. Here it is repeated for SO use
LocationTracker.java
package com.gabesechan.android.reusable.location;
import android.location.Location;
public interface LocationTracker {
public interface LocationUpdateListener{
public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime);
}
public void start();
public void start(LocationUpdateListener update);
public void stop();
public boolean hasLocation();
public boolean hasPossiblyStaleLocation();
public Location getLocation();
public Location getPossiblyStaleLocation();
}
ProviderLocationTracker.java
package com.gabesechan.android.reusable.location;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
public class ProviderLocationTracker implements LocationListener, LocationTracker {
// The minimum distance to change Updates in meters
private static final long MIN_UPDATE_DISTANCE = 10;
// The minimum time between updates in milliseconds
private static final long MIN_UPDATE_TIME = 1000 * 60;
private LocationManager lm;
public enum ProviderType{
NETWORK,
GPS
};
private String provider;
private Location lastLocation;
private long lastTime;
private boolean isRunning;
private LocationUpdateListener listener;
public ProviderLocationTracker(Context context, ProviderType type) {
lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
if(type == ProviderType.NETWORK){
provider = LocationManager.NETWORK_PROVIDER;
}
else{
provider = LocationManager.GPS_PROVIDER;
}
}
public void start(){
if(isRunning){
//Already running, do nothing
return;
}
//The provider is on, so start getting updates. Update current location
isRunning = true;
lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE, this);
lastLocation = null;
lastTime = 0;
return;
}
public void start(LocationUpdateListener update) {
start();
listener = update;
}
public void stop(){
if(isRunning){
lm.removeUpdates(this);
isRunning = false;
listener = null;
}
}
public boolean hasLocation(){
if(lastLocation == null){
return false;
}
if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
return false; //stale
}
return true;
}
public boolean hasPossiblyStaleLocation(){
if(lastLocation != null){
return true;
}
return lm.getLastKnownLocation(provider)!= null;
}
public Location getLocation(){
if(lastLocation == null){
return null;
}
if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
return null; //stale
}
return lastLocation;
}
public Location getPossiblyStaleLocation(){
if(lastLocation != null){
return lastLocation;
}
return lm.getLastKnownLocation(provider);
}
public void onLocationChanged(Location newLoc) {
long now = System.currentTimeMillis();
if(listener != null){
listener.onUpdate(lastLocation, lastTime, newLoc, now);
}
lastLocation = newLoc;
lastTime = now;
}
public void onProviderDisabled(String arg0) {
}
public void onProviderEnabled(String arg0) {
}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
}
FallbackLocationTracker.java
package com.gabesechan.android.reusable.location;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
public class FallbackLocationTracker implements LocationTracker, LocationTracker.LocationUpdateListener {
private boolean isRunning;
private ProviderLocationTracker gps;
private ProviderLocationTracker net;
private LocationUpdateListener listener;
Location lastLoc;
long lastTime;
public FallbackLocationTracker(Context context, ProviderLocationTracker.ProviderType type) {
gps = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.GPS);
net = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.NETWORK);
}
public void start(){
if(isRunning){
//Already running, do nothing
return;
}
//Start both
gps.start(this);
net.start(this);
isRunning = true;
}
public void start(LocationUpdateListener update) {
start();
listener = update;
}
public void stop(){
if(isRunning){
gps.stop();
net.stop();
isRunning = false;
listener = null;
}
}
public boolean hasLocation(){
//If either has a location, use it
return gps.hasLocation() || net.hasLocation();
}
public boolean hasPossiblyStaleLocation(){
//If either has a location, use it
return gps.hasPossiblyStaleLocation() || net.hasPossiblyStaleLocation();
}
public Location getLocation(){
Location ret = gps.getLocation();
if(ret == null){
ret = net.getLocation();
}
return ret;
}
public Location getPossiblyStaleLocation(){
Location ret = gps.getPossiblyStaleLocation();
if(ret == null){
ret = net.getPossiblyStaleLocation();
}
return ret;
}
public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime) {
boolean update = false;
//We should update only if there is no last location, the provider is the same, or the provider is more accurate, or the old location is stale
if(lastLoc == null){
update = true;
}
else if(lastLoc != null && lastLoc.getProvider().equals(newLoc.getProvider())){
update = true;
}
else if(newLoc.getProvider().equals(LocationManager.GPS_PROVIDER)){
update = true;
}
else if (newTime - lastTime > 5 * 60 * 1000){
update = true;
}
if(update){
lastLoc = newLoc;
lastTime = newTime;
if(listener != null){
listener.onUpdate(lastLoc, lastTime, newLoc, newTime);
}
}
}
}
The interface defines a generic location tracker so you can switch between them. ProviderLocationTracker will allow you to track via GPS or network, depending on the parameter you pass to its constructor. FallbackLocationTracker will track via both, giving you only the most accurate info currently available but falling back to network if GPS isn't ready.
use this code
and implemets your activity from "implements LocationListener"
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,3000, // 3 sec
5, this);
boolean isGPS = locationManager.isProviderEnabled (LocationManager.GPS_PROVIDER);
if(!isGPS)
{
showSettingsAlert();
GPS_imageview.setBackgroundResource(R.drawable.gpsnonfix);
//Toast.makeText(getApplicationContext(), "Please Start GPS to get more Accurate location", Toast.LENGTH_SHORT) .show();
}
and use following also
#Override
public void onLocationChanged(Location location) {
int a=location.getExtras().getInt("satellites") ;
if(a>4)
{
String str = "Latitude: "+location.getLatitude()+" \nLongitude: "+location.getLongitude();
// Toast.makeText(getBaseContext(), str, Toast.LENGTH_LONG).show();
Double lat=location.getLatitude();
Double lan=location.getLongitude();
}else{
}
String str = "Latitude: "+location.getLatitude()+" \nLongitude: "+location.getLongitude();
Toast.makeText(getBaseContext(), str, Toast.LENGTH_LONG).show();
}
#Override
public void onProviderDisabled(String provider) {
/******** Called when User off Gps *********/
Latitude="0.0";
Longitude="0.0";
Toast.makeText(getBaseContext(), "Gps turned off ", Toast.LENGTH_LONG).show();
}
#Override
public void onProviderEnabled(String provider) {
/******** Called when User on Gps *********/
Toast.makeText(getBaseContext(), "Gps turned on ", Toast.LENGTH_LONG).show();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
This code get no of sattelite .if no of sattelite is greter than 4 then get proper result..thats accuracy of result is good...
When you start your app, your GPS probably has not yet made connection and gives you a default location such as 0,0. If your phone finds its coordinates at a later point in time, your app has no way of detecting this.
This line:
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
states that every time your phone discovers a change of location, the "OnLocationChanged"-method (of the object in which you called that line of code), is called. As far as I can see, you did not implement this method yet.
I suggest the following. Change your third line to:
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, gpsTracker);
So it uses the implementation of the onLocationChanged method of your gpsTracker.
Now, implement the OnLocationChanged-method of the GPSTracker-class which you already defined, but not yet implemented:
#Override
public void onLocationChanged(Location location) {
//This method is triggered every time your location changes.
//The 'location' argument can be used to access the current location.
}
I'm trying to write application that track my gps coordinates.
Every 10 seconds i want to send my coordinates to server - for this i using AlarmManager.
For getting coordinates i'm using Service that implement onClickListener.
How i start service:
public void startAlarm() {
Intent intent = new Intent(this, GpsService.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, 0,
10 * 1000, pintent);
}
My gps service:
public class GpsService extends Service implements LocationListener {
// Declaring a Location Manager
private LocationManager locationManager;
Location location; // location
double latitude; // latitude
double longitude; // longitude
double accuracy;
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 10 * 1; //10secs
#Override
public void onCreate() {
super.onCreate();
if(locationManager == null ) {
locationManager = (LocationManager) this
.getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
getLocation();
if (location != null) {
//send to server
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
locationManager.removeUpdates(this);
locationManager = null;
super.onDestroy();
}
#Override
public void onLocationChanged(Location location) {
Log.v("myLogs", "GetLocation service: ONLOCATIONCHANGED");
this.location = location;
}
public Location getLocation() {
try {
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!isGPSEnabled ) {
stopSelf();
} else {
this.canGetLocation = true;
if (isGPSEnabled) {
if (location == null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
}
It work perfect on emulator, but on real device it only show GPS Finding icon. What is problem?
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'm implementing my app which could get location for users. However, I found LocationManager didn't always work in all devices, you know, there are lots of different Android devices. Then I'm thinking about getting raw gps data and sending it to a location web service to get location back would be better.
After looked around over SO, I failed to get a robust solution, is there any idea? I'm really curious that how some GPS apps in market can work on every device.
Code Snippet
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
MyLocationListener locationListener = new MyLocationListener(locationManager);
locationListener.start();
Listener,
public class MyLocationListener implements LocationListener{
public static int PERMISSION_DENIED = 1;
public static int POSITION_UNAVAILABLE = 2;
public static int TIMEOUT = 3;
protected LocationManager locationManager;
protected boolean running = false;
public MyLocationListener(LocationManager locationManager )
{
this.locationManager = locationManager;
}
public void onProviderDisabled(String provider) {
Log.d(TAG, "Location provider '" + provider + "' disabled.");
}
public void onProviderEnabled(String provider) {
Log.d(TAG, "Location provider "+ provider + " has been enabled");
}
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "The status of the provider " + provider + " has changed");
if (status == 0) {
Log.d(TAG, provider + " is OUT OF SERVICE");
}
else if (status == 1) {
Log.d(TAG, provider + " is TEMPORARILY_UNAVAILABLE");
}
else {
Log.d(TAG, provider + " is AVAILABLE");
}
}
public void onLocationChanged(Location location) {
Log.d(TAG, "The location has been updated!");
Log.d(TAG, "latitude = "+location.getLatitude()+" altitude = "+location.getAltitude());
}
public void start() {
if (!this.running) {
if (this.locationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
this.running = true;
Log.d(TAG,"using gps");
this.locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 600000, 0, this);
} else {
Log.d(TAG, "GPS provider is not available.");
}
}
if (!this.running) {
if (this.locationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
this.running = true;
Log.d(TAG,"using network");
this.locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 600000, 10, this);
} else {
Log.d(TAG, "Network provider is not available.");
}
}
}
private void stop() {
if (this.running) {
this.locationManager.removeUpdates(this);
this.running = false;
}
}
/**
* Destroy listener.
*/
public void destroy() {
this.stop();
}
Sometimes, onStatusChanged simply got nothing.
LocationManager is The Only Approach. All devices have Android API - what not all devices have is GPS module inside. But you can check it using LocationManager as well.