I am trying to retrieve location via fused location api.I have tried to build a helper class so that I can use it throughout my app.
Code:
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class GPSTracker2 implements ConnectionCallbacks,
OnConnectionFailedListener,LocationListener {
// LogCat tag
private static final String TAG = GPSTracker2.class.getSimpleName();
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private Location mLastLocation;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
// boolean flag to toggle periodic location updates
private boolean mRequestingLocationUpdates = false;
private LocationRequest mLocationRequest;
// Location updates intervals in sec
private static int UPDATE_INTERVAL = 1000; // 10 sec
private static int FATEST_INTERVAL = 500; // 5 sec
private static int DISPLACEMENT = 10; // 10 meters
Context context;
// flag for GPS status
boolean canGetLocation = true;
double latitude,longitude;
public GPSTracker2(Context context) {
// TODO Auto-generated constructor stub
// First we need to check availability of play services
this.context=context;
createLocationRequest();
if (checkPlayServices()) {
// Building the GoogleApi client
buildGoogleApiClient();
}
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
// Show location button click listener
}
/**
* Method to display the location on UI
* */
/*private void displayLocation() {
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
} else {
}
}*/
/**
* Method to display the location on UI
* */
private void displayLocation() {
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
Toast.makeText(context,latitude+" "+longitude,Toast.LENGTH_LONG).show();
} else {
}
}
/**
* Function to get latitude
* */
public double getLatitude(){
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
this.canGetLocation = true;
double latitude = mLastLocation.getLatitude();
System.out.println("In GetLat==>"+latitude);
return latitude;
}else{
System.out.println("last known null");
return 0.0;
}
}
/**
* Function to get longitude
* */
public double getLongitude(){
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
this.canGetLocation = true;
longitude = mLastLocation.getLongitude();
System.out.println("In Getlong==>"+longitude);
}
return longitude;
}
/**
* Creating google api client object
* */
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
/**
* Method to verify google play services on the device
* */
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(context);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, (Activity) context,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Toast.makeText(context,
"context device is not supported.", Toast.LENGTH_LONG)
.show();
//finish();
}
return false;
}
return true;
}
/**
* Creating location request object
* */
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
/**
* Starting the location updates
* */
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
/**
* Stopping location updates
*/
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
/**
* Google api callback methods
*/
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
#Override
public void onConnected(Bundle arg0) {
// Once connected with google api, get the location
// displayLocation();
//getLatitude();
//getLongitude();
displayLocation();
System.out.println("On Connected");
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
// Assign the new location
mLastLocation = location;
Toast.makeText(context, "Location changed!",
Toast.LENGTH_SHORT).show();
displayLocation();
// Displaying the new location on UI
// displayLocation();
// getLatitude();
// getLongitude();
}
/**
* Function to check GPS/wifi enabled
* #return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
}
I am trying to use this as:
The CallingClass.java
GPSTracker2 gps=new GPSTracker2(SettingsActivity.this);
if(gps.canGetLocation())
{
System.out.println("lat-->"+gps.getLatitude()+" long===>"+gps.getLongitude());
}else{
showSettingsAlert(true);
}
The Problem:
Methods gps.getLatitude() and gps.getLongitude() is returning 0.0.But in the toast message (within the displayLocation(); method) the latitude and longitude is coming perfectly.
Hence I debugged my application and found that after calling the constructor of GpsTracker2 class,control is going back to the calling class and after finishing the onCreate of the calling class,the GoogleApiclient is getting connected.Hence it cannot fetch the latitude and longitude within the onCreate() of the calling class and hence the result.
How can I overcome this problem??
You are querying your gps helper before it has a location. For example in your getLatitude method.
public double getLatitude(){
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
// At first mLastKnownLocation will be null
if (mLastLocation != null) {
this.canGetLocation = true;
double latitude = mLastLocation.getLatitude();
System.out.println("In GetLat==>"+latitude);
return latitude;
} else {
System.out.println("last known null");
return 0.0; // This here is what is being returned.
}
}
It isn't until your apiclient has called public void onLocationChanged(Location location) that a location will become available.
Method 1
Return a Location object instead of primitives. This way you can return null if it is being queried too early and the caller can handle it.
Method 2
The users of your GPS helper register a callback with it. Now they will be notified when a location is available.
In the GPSTracker class
List<LocationListener> listeners = new ArrayList<>();
public void registerListener(LocationListener listener) {
listeners.add(listener);
}
public void removeListener(LocationListener listener) {
listeners.remove(listener);
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
for (LocationListener listener : listeners) {
listener.onLocationChanged(location);
}
}
User of GPSTracker
GPSTracker gps = new GPSTracker();
LocationListener myCallback = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
// This code runs every time your gps gets a new location
System.out.println("lat-->"+location.getLatitude()+" long===>"+location.getLongitude());
doStuffWithLocation(location);
}
};
gps.registerListener(myCallback);
// Then when you are finished
gps.removeListener(myCallback);
I find class GooglePlayServicesHelper
after use code below in Activity
geoGPS = new GooglePlayServicesHelper(mContext, true);
mLocationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
Logger.debug("lat: " + latitude);
Logger.debug("long: " + longitude);
}
};
Related
I am working on an app that requires the user's current location to be marked on a MapView. I've looked all around the internet, and haven't found anything that works with my code. I've looked at many questions on this site and on other Android tutorial sites/YouTube videos. I have tried getting permission to access fine location and then creating a string with the current latitude and longitude inside it. However, this just doesn't work.
I've tried playing around with the code, but I just can't figure it out. What I want to do is get the user's current location and then place a marker on a MapView that also contains a marker placed at a location. I understand the code, I just don't know a) why it isn't working and b) what I need to do to fix it. I have included the activity's code below.
import android.content.Intent;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
public class fthactivity extends AppCompatActivity implements
OnMapReadyCallback {
private GoogleApiClient googleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fthactivity);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.fthmap);
mapFragment.getMapAsync(this);
findViewById(R.id.fthphone).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialContactPhone(" 1234567890");
}
});
Button btn = (Button) findViewById(R.id.fthweb);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent myWebLink = new Intent(android.content.Intent.ACTION_VIEW);
myWebLink.setData(Uri.parse("http://google.ca/"));
startActivity(myWebLink);
}
});
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 3);
return;
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
GoogleMap mMap = googleMap;
LatLng fthloc = new LatLng(51.036585, -114.066152);
mMap.addMarker(new MarkerOptions().position(fthloc).title("Certain Location"));
float zoomLevel = (float) 10.0f;
mMap.moveCamera(CameraUpdateFactory.newLatLng(fthloc));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.036585, -114.066152), 18.0f));
}
protected void onLocationChanged(GoogleMap mMap, Location location) {
LatLng urloc = new LatLng(location.getLatitude(), location.getLongitude());
mMap.addMarker(new MarkerOptions().position(urloc).title("Your Location)"));
float zoomLevel = (float) 10.0f;
mMap.moveCamera(CameraUpdateFactory.newLatLng(urloc));
}
private void dialContactPhone(final String phoneNumber) {
startActivity(new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phoneNumber, null)));
}
}
This is how I get location from one of my apps.
public class LocationProvider extends Service implements LocationListener {
private final Context mContext;
//flag gor GPS status
boolean isGPSEnabled = false;
//flag for network status
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
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 LocationProvider(Context context) {
this.mContext = context;
location = 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;
if (isNetworkEnabled) {
try {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
}catch (SecurityException e) {e.printStackTrace();}
//Log.d("NetworkLocation", "Network");
if (locationManager != null) {
try {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
} catch (SecurityException e){e.printStackTrace();}
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
// Log.i("LOC_Net:latitude",String.valueOf(latitude));
// Log.i("LOC_Net:langitude",String.valueOf(longitude));
}
}
}
// If GPS enabled, get latitude/longitude using GPS Services
if (isGPSEnabled) {
if (location == null) {
try {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
} catch (SecurityException e){e.printStackTrace();}
// Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
try {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
} catch (SecurityException e) {e.printStackTrace();}
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){
try{
locationManager.removeUpdates(LocationProvider.this);
}catch (SecurityException e){e.printStackTrace();}
}
}
/**
* 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/Wi-Fi enabled
* #return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog.
* On pressing the Settings button it will launch Settings Options.
* */
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("Turn On Location");
// Setting Dialog Message
alertDialog.setMessage("Location is not enabled. Do you want to go to settings menu?");
// On pressing the 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 the 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;
}
In your activity declare variables
private double latitude;
private double longitude;
and create a method like this:
private boolean getLocation(){
locationProvider = new LocationProvider(this);
Location location = locationProvider.getLocation();
if (locationProvider.canGetLocation()){
latitude = locationProvider.getLatitude();
longitude = locationProvider.getLongitude();
return true;
} else {
//Can't get location//GPS or network is not enabled
//Ask user to enable GPS/Network in settings
locationProvider.showSettingsAlert();
return false;
}
}
I am trying to get location of user as longitude and latitude from GPS/network which ever is available and i want to get it fast , or else previous location coordinates will return if cannot get new one right now.
Here is my attempt:
public class GPSTracker extends Service{
// 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
private final Context mContext;
// Declaring a Location Manager
protected LocationManager locationManager;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location = null; // location
double latitude; // latitude
double longitude; // longitude
myLocationLitener locationLitener;
public GPSTracker(Context context) {
this.mContext = context;
locationLitener = new myLocationLitener();
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;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES,locationLitener);
Log.d("Network", "Network Enabled");
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) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return null;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, locationLitener);
Log.d("GPS", "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) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
locationManager.removeUpdates(locationLitener);
}
}
/**
* 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 IBinder onBind(Intent arg0) {
return null;
}
private class myLocationLitener implements LocationListener{
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
}
How i use this class?
Suppose i am running below function in async task (who don't have knowledge of android annotation #Background is doing this)
#Background
void getmyLocationAndSend(){
GPSTracker gps = new GPSTracker(context);
// check if GPS location can get Location
if (gps.canGetLocation()) {
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
Log.d("Your Location", "latitude:" + gps.getLatitude()
+ ", longitude: " + gps.getLongitude());
latitude = gps.getLatitude(); // set the globals
longitude = gps.getLongitude(); // set the globals
}else{
showToast("Network is connected..");
if (progress != null && progress.isShowing()) {
progress.dismiss();
}
}
}else{
showToast("Cannot get location from gps..");
if (progress != null && progress.isShowing()) {
progress.dismiss();
}
}
}
my goal is to get coordinates in less than 30 seconds , and never get 0.0 value , how can i achieve that any help appreciated ?
Please check how i'm using in my app and its working perfect.I'm using fused api for update location please follow few steps.Currently you using very old approach.So, there is no need now
and pass here your time in milliseconds what you want
UPDATE_INTERVAL_IN_MILLISECONDS
Step 1. Make this class
GoogleLocationService.java
public class GoogleLocationService {
private GoogleServicesCallbacks callbacks = new GoogleServicesCallbacks();
LocationUpdateListener locationUpdateListener;
Context activity;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 30000;
public GoogleLocationService(Context activity, LocationUpdateListener locationUpdateListener) {
this.locationUpdateListener = locationUpdateListener;
this.activity = activity;
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
//Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(activity)
.addConnectionCallbacks(callbacks)
.addOnConnectionFailedListener(callbacks)
.addApi(LocationServices.API)
.build();
createLocationRequest();
mGoogleApiClient.connect();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private class GoogleServicesCallbacks implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
#Override
public void onConnected(Bundle bundle) {
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
if (connectionResult.getErrorCode() == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED) {
Toast.makeText(activity, "Google play service not updated", Toast.LENGTH_LONG).show();
}
locationUpdateListener.cannotReceiveLocationUpdates();
}
#Override
public void onLocationChanged(Location location) {
if (location.hasAccuracy()) {
if (location.getAccuracy() < 30) {
locationUpdateListener.updateLocation(location);
}
}
}
}
private static boolean locationEnabled(Context context) {
boolean gps_enabled = false;
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
ex.printStackTrace();
}
return gps_enabled;
}
private boolean servicesConnected(Context context) {
return isPackageInstalled(GooglePlayServicesUtil.GOOGLE_PLAY_STORE_PACKAGE, context);
}
private boolean isPackageInstalled(String packagename, Context context) {
PackageManager pm = context.getPackageManager();
try {
pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
return true;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return false;
}
}
public void startUpdates() {
/*
* Connect the client. Don't re-start any requests here; instead, wait
* for onResume()
*/
if (servicesConnected(activity)) {
if (locationEnabled(activity)) {
locationUpdateListener.canReceiveLocationUpdates();
startLocationUpdates();
} else {
locationUpdateListener.cannotReceiveLocationUpdates();
Toast.makeText(activity, "Unable to get your location.Please turn on your device Gps", Toast.LENGTH_LONG).show();
}
} else {
locationUpdateListener.cannotReceiveLocationUpdates();
Toast.makeText(activity, "Google play service not available", Toast.LENGTH_LONG).show();
}
}
//stop location updates
public void stopUpdates() {
stopLocationUpdates();
}
//start location updates
private void startLocationUpdates() {
if (checkSelfPermission(activity, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(activity, ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, callbacks);
}
}
public void stopLocationUpdates() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, callbacks);
}
}
public void startGoogleApi() {
mGoogleApiClient.connect();
}
public void closeGoogleApi() {
mGoogleApiClient.disconnect();
}
}
Step2. Make this interface
LocationUpdateListener.java
public interface LocationUpdateListener {
/**
* Called immediately the service starts if the service can obtain location
*/
void canReceiveLocationUpdates();
/**
* Called immediately the service tries to start if it cannot obtain location - eg the user has disabled wireless and
*/
void cannotReceiveLocationUpdates();
/**
* Called whenever the location has changed (at least non-trivially)
* #param location
*/
void updateLocation(Location location);
/**
* Called when GoogleLocationServices detects that the device has moved to a new location.
* #param localityName The name of the locality (somewhere below street but above area).
*/
void updateLocationName(String localityName, Location location);
}
Step 3. Make this Location service class
LocationService.java
public class LocationService extends Service {
private GoogleLocationService googleLocationService;
#Override
public void onCreate() {
super.onCreate();
//start the handler for getting locations
//create component
updateLocation(getApplicationContext());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
//get current location os user
private void updateLocation(Context context) {
googleLocationService = new GoogleLocationService(context, new LocationUpdateListener() {
#Override
public void canReceiveLocationUpdates() {
}
#Override
public void cannotReceiveLocationUpdates() {
}
//update location to our servers for tracking purpose
#Override
public void updateLocation(Location location) {
if (location != null ) {
Timber.e("updated location %1$s %2$s", location.getLatitude(), location.getLongitude());
}
}
#Override
public void updateLocationName(String localityName, Location location) {
googleLocationService.stopLocationUpdates();
}
});
googleLocationService.startUpdates();
}
IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
public LocationService getServerInstance() {
return LocationService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
//stop location updates on stopping the service
#Override
public void onDestroy() {
super.onDestroy();
if (googleLocationService != null) {
googleLocationService.stopLocationUpdates();
}
}
}
Edited Answer:
How to use service,
Start service in your main activity,like this
startService(new Intent(context, LocationService.class));
for stop,
stopService(new Intent(context, LocationService.class));
and declare in manifest like this,
<service
android:name=".service.location.LocationService"
android:enabled="true"></service>
Note: I have done this because i need location after killed the app.If you dont want service.Then,you can call directly below code in class where location need to be update and remove locationservice.
private GoogleLocationService googleLocationService;
googleLocationService = new GoogleLocationService(context, new LocationUpdateListener() {
#Override
public void canReceiveLocationUpdates() {
}
#Override
public void cannotReceiveLocationUpdates() {
}
//update location to our servers for tracking purpose
#Override
public void updateLocation(Location location) {
if (location != null ) {
Timber.e("updated location %1$s %2$s", location.getLatitude(), location.getLongitude());
}
}
#Override
public void updateLocationName(String localityName, Location location) {
googleLocationService.stopLocationUpdates();
}
});
googleLocationService.startUpdates();
and call this onDestroy
if (googleLocationService != null) {
googleLocationService.stopLocationUpdates();
}
Remember Locationservice should be declare in manifest as well.
According to me this is the best solution.I have done alot of work on location.
Thanks hope this will help you
Check out FusedLocationApi. It does a great job of that and it gives you options for minimizing battery performance.
You can take a look to RxGpsService (An Android service to retrieve GPS locations and route stats using RxJava). It retrieves a RouteStats object which contains the current speed, distance, time elapsed and waypoints.
Also is customizable, so you can set your interval by using .withInterval(30000) and .withFastestInterval(30000) .
I'm looking to create an app in android that basically tracks a phones location and periodically adds a marker to the google maps api so that a route can be displayed, the problem I have is that I don't know how to get the location periodically and in the background.
Here is my code:
public class MapsActivity extends FragmentActivity implements LocationListener {
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
Button btnCurrent, btnPrevious;
ArrayList<Double> latitude = new ArrayList<>();
ArrayList<Double> longitude = new ArrayList<>();
LocationManager lm;
LocationListener ll;
Location networkLocation;
Location gpsLocation;
double LONG;
double LAT;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
networkLocation = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
gpsLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
lm.requestLocationUpdates(lm.GPS_PROVIDER, 10, 0, new android.location.LocationListener() {
#Override
public void onLocationChanged(Location location) {
LONG = networkLocation.getLongitude();
LAT = networkLocation.getLatitude();
latitude.add(LAT);
longitude.add(LONG);
Log.d("COORDS", LAT+" , "+LONG);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
});
setUpMapIfNeeded();
btnCurrent = (Button)findViewById(R.id.btn_currentLoc);
btnPrevious = (Button) findViewById(R.id.btn_prevLoc);
btnCurrent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mMap.clear();
double curLong, curLat;
String test = lm.getAllProviders().toString();
LatLng CurrentLoc;
Log.d("PROVIDERS ", test);
if((lm.isProviderEnabled("gps"))==true)
{
curLong = gpsLocation.getLongitude();
curLat = gpsLocation.getLatitude();
CurrentLoc = new LatLng(curLat,curLong);
Log.d("GPS", "true");
}else
{
curLong = networkLocation.getLongitude();
curLat = networkLocation.getLatitude();
CurrentLoc = new LatLng(curLat,curLong);
Log.d("GPS", "false");
}
mMap.addMarker(new MarkerOptions().position(new LatLng(curLat,curLong)).title("LOCATION "+ curLat + ", " + curLong));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(CurrentLoc,15));
Log.d("LOCATION", curLat + "," + curLong);
}
});
btnPrevious.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for(int i = 0;i<latitude.size();i++)
{
mMap.addMarker(new MarkerOptions().position(new LatLng(latitude.get(i),longitude.get(i))).title("LOCATION "+ latitude.get(i) + ", " + longitude.get(i)));
Log.d("LOCATION", latitude.get(i)+ "," + longitude.get(i));
}
}
});
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
}
private void getCurrentLocation(){
}
private void seeAllLocations(){
}
#Override
public void onLocationChanged(Location location) {
}
}
Any help would be appreciated.
Check this below code which helps you to get current location on button click and also #some timeInterval.
public class MainActivity extends Activity implements ConnectionCallbacks,
OnConnectionFailedListener, LocationListener {
// LogCat tag
private static final String TAG = MainActivity.class.getSimpleName();
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private Location mLastLocation;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
// boolean flag to toggle periodic location updates
private boolean mRequestingLocationUpdates = false;
private LocationRequest mLocationRequest;
// Location updates intervals in sec
private static int UPDATE_INTERVAL = 10000; // 10 sec
private static int FATEST_INTERVAL = 5000; // 5 sec
private static int DISPLACEMENT = 10; // 10 meters
// UI elements
private TextView lblLocation;
private Button btnShowLocation, btnStartLocationUpdates;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lblLocation = (TextView) findViewById(R.id.lblLocation);
btnShowLocation = (Button) findViewById(R.id.btnShowLocation);
btnStartLocationUpdates = (Button) findViewById(R.id.btnLocationUpdates);
// First we need to check availability of play services
if (checkPlayServices()) {
// Building the GoogleApi client
buildGoogleApiClient();
createLocationRequest();
}
// Show location button click listener
btnShowLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
displayLocation();
}
});
// Toggling the periodic location updates
btnStartLocationUpdates.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
togglePeriodicLocationUpdates();
}
});
}
#Override
protected void onStart() {
super.onStart();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
#Override
protected void onResume() {
super.onResume();
checkPlayServices();
// Resuming the periodic location updates
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
}
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
/**
* Method to display the location on UI
* */
private void displayLocation() {
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
lblLocation.setText(latitude + ", " + longitude);
} else {
lblLocation
.setText("(Couldn't get the location. Make sure location is enabled on the device)");
}
}
/**
* Method to toggle periodic location updates
* */
private void togglePeriodicLocationUpdates() {
if (!mRequestingLocationUpdates) {
// Changing the button text
btnStartLocationUpdates
.setText(getString(R.string.btn_stop_location_updates));
mRequestingLocationUpdates = true;
// Starting the location updates
startLocationUpdates();
Log.d(TAG, "Periodic location updates started!");
} else {
// Changing the button text
btnStartLocationUpdates
.setText(getString(R.string.btn_start_location_updates));
mRequestingLocationUpdates = false;
// Stopping the location updates
stopLocationUpdates();
Log.d(TAG, "Periodic location updates stopped!");
}
}
/**
* Creating google api client object
* */
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
/**
* Creating location request object
* */
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
/**
* Method to verify google play services on the device
* */
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Toast.makeText(getApplicationContext(),
"This device is not supported.", Toast.LENGTH_LONG)
.show();
finish();
}
return false;
}
return true;
}
/**
* Starting the location updates
* */
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
/**
* Stopping location updates
*/
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
/**
* Google api callback methods
*/
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
#Override
public void onConnected(Bundle arg0) {
// Once connected with google api, get the location
displayLocation();
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
// Assign the new location
mLastLocation = location;
Toast.makeText(getApplicationContext(), "Location changed!",
Toast.LENGTH_SHORT).show();
// Displaying the new location on UI
displayLocation();
}
}
My problem is not new, but none of answers in Stackoverflow was helpful for me.
Situation: I have a service which works with an Alarm. it repeats every 1 minutes and run a service for me. in that service I need to send GPS data to a web server.
the codes are as below:
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.AsyncTask;
import android.os.IBinder;
import bliksund.taxitracking.tools.Cachepref;
import bliksund.taxitracking.tools.PostData;
public class SendData extends Service {
Cachepref cachepref;
GET_GPS gps;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
cachepref = new Cachepref(this);
gps = new GET_GPS(this);
new getloc().execute();
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private class getloc extends AsyncTask<Void, Void, Void> {
String username;
Double lt;
Double lg;
Location location;
#Override
protected Void doInBackground(Void... params) {
username = cachepref.getUsername();
location = gps.getLocation();
lt = location.getLatitude();
lg = location.getLongitude();
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
PostData postData = new PostData(username, 1, lt, lg);
super.onPostExecute(aVoid);
}
}
}
this is my service.
+ PostData will Post the parameters to a web page.
+ Cachepref saves username for user Session.
Problem: When the codes go to get GPS Location. it will make an error that says:
location = gps.getLocation(); // will cause to below line error
Can't create handler inside thread that has not called Looper.prepare()
I used AsynTask to solve this problem, but it is still there.
GET_GPS code are as below:
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
public class GET_GPS 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
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
protected LocationManager locationManager;
public GET_GPS(Context mContext) {
this.mContext = mContext;
}
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;
}
public void stopUsingGPS(){
if(locationManager != null){
locationManager.removeUpdates(GET_GPS.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;
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
with the help of ρяσѕρєя K . he said to move these codes to PostExecute and it was running, the problem with PostData happened. and I I solved in the way below. I hope it helps others.
private class getloc extends AsyncTask<Void, Void, Void> {
String username;
Double lt;
Double lg;
Location location;
#Override
protected Void doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
username = cachepref.getUsername();
location = gps.getLocation();
lt = location.getLatitude();
lg = location.getLongitude();
new Thread(new Runnable() {
#Override
public void run() {
PostData postData = new PostData(username, 1, lt, lg);
}
}).start();
super.onPostExecute(aVoid);
}
}
I am trying to create an app which tracks the user's walking route and accesses the gps to get their location. I will then draw polylines between these points to show the route. I was wondering how exactly I would loop to keep getting the points and then how to then put those on the maps to display the route. This is what I have so far. Will this loop work to put the points in a list? If not how would I go about doing what I want to achieve?
One small issue is that it is saying variable mContext may not have been initialized. This was after I added
public GPSTracker(){
arrayPoints = new ArrayList<LatLng>();
}
GPSTracker class:
import com.google.android.gms.maps.model.LatLng;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
import javax.crypto.spec.GCMParameterSpec;
public class GPSTracker extends Service implements LocationListener {
//array with latitude and longitude points for polylines
public static ArrayList<LatLng> arrayPoints;
// intent.putExtra("arrayPoints", arrayPoints);
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 GPSTracker(){
arrayPoints = new ArrayList<LatLng>();
}
public ArrayList<LatLng> 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");
while(locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
arrayPoints.add(new LatLng(latitude, longitude));
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return arrayPoints;
}
public ArrayList<LatLng> getPoints(){
return arrayPoints;
}
/**
* 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 disabled");
// Setting Dialog Message
alertDialog.setMessage("GPS is not enabled. Turn it on in settings.");
// 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;
}
MapsActivity Class:
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private GPSTracker gpsTracker;
public static final String TAG = MapsActivity.class.getSimpleName();
Location Location;
public MapsActivity(){
gpsTracker = new GPSTracker();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(40.0139, -105.1507), 3));
try {
GPSTracker gps = new GPSTracker(MapsActivity.this);
// check if GPS enabled
if (gps.canGetLocation()) {
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
// \n is for new line
Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
} else {
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
}
// Loading map
initializeMap();
} catch (Exception e) {
e.printStackTrace();
}
}
private void initializeMap() {
if (mMap == null) {
mMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
// check if map is created successfully or not
if (mMap == null) {
Toast.makeText(getApplicationContext(),
"Error: Unable to create map", Toast.LENGTH_SHORT)
.show();
}
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
}
}
public void onMapReady(GoogleMap mMap) {
ArrayList<LatLng> arrayPoints = gpsTracker.getPoints();
if (arrayPoints.size() > 1) {
PolylineOptions polyline_options = new PolylineOptions()
.addAll(arrayPoints).color(Color.GREEN).width(2);
Polyline polyline = mMap.addPolyline(polyline_options);
}
}
/* #Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}*/
/**
* Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
* installed) and the map has not already been instantiated.. This will ensure that we only ever
* call {#link #setUpMap()} once when {#link #mMap} is not null.
* <p/>
* If it isn't installed {#link SupportMapFragment} (and
* {#link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
* install/update the Google Play services APK on their device.
* <p/>
* c * A an return to this FragmentActivity after following the prompt and correctly
* installing/updating/enabling the Google Play services. Since the FragmentActivity may not
* have been completely destroyed during this process (it is likely that it would only be
* stopped or paused), {#link #onCreate(Bundle)} may not be called again so we should call this
* method in {#link #onResume()} to guarantee that it will be called.
*/
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
}
Thanks for the help, tell me if I need to clarify more or show less code.
Just trying to give you an idea: You can keep track of the latest added markers and return user current location based every once in awhile, and if the distance of user current latLong and the previous latLong marker is larger than a certain value, add new marker. iterate the process updating the previous marker and user current latLong. Just an idea, please give it a shot.