I am creating a map application, which gets location from GPS, i'm finding location from requestLocationUpdates(), but i'm not getting any response from GPS provider, however when i'am using network provider i'am getting location, can anyone help where i'm wrong,
Also i'am new to android app development, so i'll appreciate any tips to optimize my code(make more efficient with less mess),
Here's my code :
public void trackLocation(){
if (ContextCompat.checkSelfPermission(activity.getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
boolean flag;
Boolean dlg;
flag = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (flag) {
Log.v("function", "onClick");
myLocationListener = new MyLocationListener();
dlg = true;
} else {
dlg = gpsDialog();
progressBar.setVisibility(View.GONE);
}
Log.d("maps", "Requesting location updates");
if(dlg) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, myLocationListener);
}
}
}
public class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
if (ActivityCompat.checkSelfPermission(MapsActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MapsActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Log.d("maps", "on location changed : "+location.getLatitude() + "---"+ location.getLongitude());
locationManager.removeUpdates(myLocationListener);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
Log.d("maps" , "Status Changed");
}
#Override
public void onProviderEnabled(String s) {
Log.d("maps" , "Provider Enabled");
}
#Override
public void onProviderDisabled(String s) {
Log.d("maps" , "Provider Disabled");
}
}
public Boolean gpsDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage("Do you want to start GPS?")
.setCancelable(false)
.setTitle("GPS DISABLED")
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// finish the current activity
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
activity.startActivity(myIntent);
dialog.cancel();
}
})
.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// cancel the dialog box
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
progressBar.setVisibility(View.GONE);
return false;
}
Google maps uses user's lastKnownLocation for location, If the lastknownLocation is unknown it takes time to fetch location through different provider say GPS or Network, whichever is easy. I would suggest to use lastKnownLocation as base location and update it with LocationListener. It is most optimized way of processing location.
if (ActivityCompat.checkSelfPermission
(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&&
ActivityCompat.checkSelfPermission
(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
requestPermissions(new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
}, 1);
}
else {
// enable location buttons
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
// fetch last location if any from provider - GPS.
final LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
final Location loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//if last known location is not available
if (loc == null) {
final LocationListener locationListener = new LocationListener() {
#Override
public void onLocationChanged(final Location location) {
// getting location of user
final double latitude = location.getLatitude();
final double longitude = location.getLongitude();
//do something with Lat and Lng
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
//when user enables the GPS setting, this method is triggered.
}
#Override
public void onProviderDisabled(String provider) {
//when no provider is available in this case GPS provider, trigger your gpsDialog here.
}
};
//update location every 10sec in 500m radius with both provider GPS and Network.
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10*1000, 500, locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 500, locationListener);
}
else {
//do something with last known location.
// getting location of user
final double latitude = loc.getLatitude();
final double longitude = loc.getLongitude();
}
}
Permission handling:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults[0] != PackageManager.PERMISSION_GRANTED){
//do something
}
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Your code is correct. GPS usually doesn't give you any info within the building, if you try to test the app outside, you will get the results.
firstly check gps_enabled return true or not.
LocationManager lm = (LocationManager) mCtx
.getSystemService(Context.LOCATION_SERVICE);
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
By this code you get accurate lat , long
Location net_loc = null, gps_loc = null, finalLoc = null;
if (gps_enabled)
gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (network_enabled)
net_loc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (gps_loc != null && net_loc != null) {
if (gps_loc.getAccuracy() >= net_loc.getAccuracy())
finalLoc = gps_loc;
else
finalLoc = net_loc;
// I used this just to get an idea (if both avail, its upto you which you want to take as I taken location with more accuracy)
} else {
if (gps_loc != null) {
finalLoc = net_loc;
} else if (net_loc != null) {
finalLoc = gps_loc;
}
}
Related
How can I refresh the marker position (for example, when user is moving) on Android maps?
I set up the refresh time for 3 seconds in locationManager.requestLocationUpdates but it seems that it's not working.
Here is my 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 = 50; // 3 seconds
// 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;
}
public void stopUsingGPS() {
if (locationManager != null) {
locationManager.removeUpdates(GPSTracker.this);
}
}
public double getLatitude() {
if (location != null) {
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
public double getLongitude() {
if (location != null) {
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
public boolean canGetLocation() {
return this.canGetLocation;
}
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;
}
}
And here is my Maps Activity where I create map and add a marker to it:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
private final static int REQUEST_CODE_ASK_PERMISSIONS = 1;
private static final String[] REQUIRED_SDK_PERMISSIONS = new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_NETWORK_STATE};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
checkPermissions();
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mapsCreate();
}
public void mapsCreate() {
GPSTracker tracker = new GPSTracker(MapsActivity.this);
double lat = tracker.getLatitude();
double lng = tracker.getLongitude();
// Add a marker for current location and move the camera
LatLng currentLocation = new LatLng(lat, lng);
mMap.addMarker(new MarkerOptions().position(currentLocation).title("Current Location Marker"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(currentLocation));
}
protected boolean checkPermissions() {
final List<String> missingPermissions = new ArrayList<String>();
// check all required dynamic permissions
for (final String permission : REQUIRED_SDK_PERMISSIONS) {
final int result = ContextCompat.checkSelfPermission(this, permission);
if (result != PackageManager.PERMISSION_GRANTED) {
missingPermissions.add(permission);
}
}
if (!missingPermissions.isEmpty()) {
// request all missing permissions
final String[] permissions = missingPermissions
.toArray(new String[missingPermissions.size()]);
ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE_ASK_PERMISSIONS);
} else {
final int[] grantResults = new int[REQUIRED_SDK_PERMISSIONS.length];
Arrays.fill(grantResults, PackageManager.PERMISSION_GRANTED);
onRequestPermissionsResult(REQUEST_CODE_ASK_PERMISSIONS, REQUIRED_SDK_PERMISSIONS,
grantResults);
return true;
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[],
#NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS:
for (int index = permissions.length - 1; index >= 0; --index) {
if (grantResults[index] != PackageManager.PERMISSION_GRANTED) {
// exit the app if one permission is not granted
Toast.makeText(this, "Required permission '" + permissions[index]
+ "' not granted, exiting", Toast.LENGTH_LONG).show();
finish();
return;
}
}
// all permissions were granted
break;
}
}
Any help would be much appreciated! Thank you
Save the marker object after adding to maps.
myMarker = mMap.addMarker(new MarkerOptions().position(currentLocation).title("Current Location Marker"));
After getting new location in location updates callback update marker's position.
.....
myMarker.setPosition(newLatLng);
I working with a project to find the address using latitude and longitude. I got answer in Jellybean but when comes to Lollipop and Marshmallow it only showing latitude and longitude, not getting address. It shows location provider is not found. Is there any error in my code?
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
mprovider = locationManager.getBestProvider(criteria, false);
if (mprovider != null && !mprovider.equals("")) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
return;
}
Location location = locationManager.getLastKnownLocation(mprovider);
locationManager.requestLocationUpdates(mprovider,5000, 0,this);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
if (location != null)
onLocationChanged(location);
else
Toast.makeText(getBaseContext(), "No Location Provider Found Check Your Code", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onLocationChanged(Location location) {
TextView longitude = (TextView) findViewById(R.id.textView);
TextView latitude = (TextView) findViewById(R.id.textView1);
longitude.setText("Current Longitude:" + location.getLongitude());
latitude.setText("Current Latitude:" + location.getLatitude());
Geocoder geo = new Geocoder(getApplicationContext(), Locale.getDefault());
// String mylocation;
try {
List < Address > addresses = geo.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
if (addresses != null && addresses.size() > 0) {
String address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
address1.setText(address);
String city = addresses.get(0).getLocality();
textViewCity.setText(city);
String state = addresses.get(0).getAdminArea();
textViewState.setText(state);
String country = addresses.get(0).getCountryName();
textViewCountry.setText(country);
String postalCode = addresses.get(0).getPostalCode();
textViewPostal.setText(postalCode);
String knownName = addresses.get(0).getFeatureName();
System.out.println("Address >> " + address + " " +city+ " \n" + state + " \n" + country+ "\n"+postalCode+ "\n"+knownName);
}
} catch (IOException e) {
e.printStackTrace();
}
add this class.
public class SingleShotLocationProvider {
public static interface LocationCallback {
public void onNewLocationAvailable(GPSCoordinates location);
}
// calls back to calling thread, note this is for low grain: if you want higher precision, swap the
// contents of the else and if. Also be sure to check gps permission/settings are allowed.
// call usually takes <10ms
public static void requestSingleUpdate(final Context context, final LocationCallback callback) {
final LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (isNetworkEnabled) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context, 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.requestSingleUpdate(criteria, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
callback.onNewLocationAvailable(new GPSCoordinates(location.getLatitude(), location.getLongitude()));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}, null);
} else {
boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (isGPSEnabled) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
locationManager.requestSingleUpdate(criteria, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
callback.onNewLocationAvailable(new GPSCoordinates(location.getLatitude(), location.getLongitude()));
}
#Override public void onStatusChanged(String provider, int status, Bundle extras) { }
#Override public void onProviderEnabled(String provider) { }
#Override public void onProviderDisabled(String provider) { }
}, null);
}
}
}
// consider returning Location instead of this dummy wrapper class
public static class GPSCoordinates {
public float longitude = -1;
public float latitude = -1;
public GPSCoordinates(float theLatitude, float theLongitude) {
longitude = theLongitude;
latitude = theLatitude;
}
public GPSCoordinates(double theLatitude, double theLongitude) {
longitude = (float) theLongitude;
latitude = (float) theLatitude;
}
}
}
and use like this:
SingleShotLocationProvider.requestSingleUpdate(getActivity(),
new SingleShotLocationProvider.LocationCallback() {
#Override
public void onNewLocationAvailable(SingleShotLocationProvider.GPSCoordinates location) {
lat = location.latitude;
lag = location.longitude;
}
});
here you can get lat - lag if your device location is enable. so also check that is enable or not.
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
showEnableLocationDialog();
} else {
SingleShotLocationProvider.requestSingleUpdate(getActivity(),
new SingleShotLocationProvider.LocationCallback() {
#Override
public void onNewLocationAvailable(SingleShotLocationProvider.GPSCoordinates location) {
lat = location.latitude;
lag = location.longitude;
}
});
}
public void showEnableLocationDialog() {
final android.app.AlertDialog.Builder builderDialog = new android.app.AlertDialog.Builder(getActivity());
builderDialog.setTitle("Enable Location");
builderDialog.setMessage("Please enable location for near by search");
builderDialog.setPositiveButton("Enable",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
}
});
builderDialog.setNegativeButton("No",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
//fetchImages();
}
});
android.app.AlertDialog alert = builderDialog.create();
alert.show();
}
and i hope you are asking run-time permission for location first. otherwise you will never get location.
I want to get current latitude and longitude when user clicks on a button . to do so ,I've written these codes :
LocationManager mlocManager=null;
LocationListener mlocListener;
mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
if (mlocManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
Log.v("this",MyLocationListener.latitude+ " lat");
if(MyLocationListener.latitude>0){
in = new Intent(DrawerActivity.this, Barbers.class);
in.putExtra("w", "nearest");
in.putExtra("latitude",Double.toString(MyLocationListener.latitude));
in.putExtra("longitude",Double.toString(MyLocationListener.longitude));
startActivity(in);
}else{
MyToast.makeText(DrawerActivity.this, Z_Farsi.Convert(getString(R.string.gpsfinding)));
}
} else {
MyToast.makeText(DrawerActivity.this, Z_Farsi.Convert(getString(R.string.gpsoffline)));
}
The gps is on and the current location is showing on google map perfectly .
What is the problem ? why it returns 0.0 ?
how to solve this ?
getLastKnownLocation is missing. You should have something like this :
Location location = null;
if (mlocManager!= null) {
location = mlocManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
This file will do the work for you. It will get the data from network-operator or GPS.
GPSTracker.java
public class GpsTracker extends Service implements LocationListener {
private final Context mContext;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location;
double latitude;
double longitude;
private final long MIN_DISTANCE = 10;
private final long MIN_TIME = 30;
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 enabled
} else {
this.canGetLocation = true;
// first get location from network provider
if (isNetworkEnabled) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.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.NETWORK_PROVIDER, MIN_TIME, MIN_DISTANCE, 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 provider
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME, MIN_DISTANCE, this);
Log.d("GPS provider", "GPS provider");
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, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.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(GpsTracker.this);
}
}
// functions to get latitude and longitude
public double getLatitude()
{
if(location != null){
latitude = location.getLatitude();
}
return latitude;
}
public double getLongitude()
{
if(location != null){
longitude = location.getLongitude();
}
return longitude;
}
// function to check whether GPS/WiFi is enabled
public boolean canGetLocation()
{
return this.canGetLocation;
}
/* Function to show alert dialog
* on pressing settings button will launch settings options */
public void showAlertDialog()
{
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
alertDialog.setTitle("GPS Settings").setMessage("GPS not Enabled. /n Want to enable it ? ").setCancelable(false);
alertDialog.setPositiveButton("Settings", new OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
// Implicit intent
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
alertDialog.setNegativeButton("No", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int arg1) {
dialog.cancel();
}
});
alertDialog.show();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onLocationChanged(Location arg0) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}
Try like this
manager.requestLocationUpdates("gps", 10, 10, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
double lat=location.getLatitude();
double lon=location.getLognitude()
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
});
What I have come to notice with location features is that you cannot acquire a user location instantly. You have to wait for the device to give you the location.
Normally, I would have my code in my Application class then for example when a user clicks the button, you call a method inside the application class and let the user know (through a progress dialog??) that they should wait for the latitude and longitude to be acquired.
Next thing would be to use an event to notify the activity or fragment of the location availability then dismissing the progress dialog once you have your data.
Just know that you cannot easily get the current location when you want like immediately. Sometimes, when indoors, it doesn't even work as expected.
Good luck!
How do I get the current Latitude and Longitude of the mobile device in android using location tools?
Use the LocationManager.
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
double longitude = location.getLongitude();
double latitude = location.getLatitude();
The call to getLastKnownLocation() doesn't block - which means it will return null if no position is currently available - so you probably want to have a look at passing a LocationListener to the requestLocationUpdates() method instead, which will give you asynchronous updates of your location.
private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();
}
}
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener);
You'll need to give your application the ACCESS_FINE_LOCATION permission if you want to use GPS.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
You may also want to add the ACCESS_COARSE_LOCATION permission for when GPS isn't available and select your location provider with the getBestProvider() method.
Here is the class LocationFinder to find the GPS location. This class will call MyLocation, which will do the business.
LocationFinder
public class LocationFinder extends Activity {
int increment = 4;
MyLocation myLocation = new MyLocation();
// private ProgressDialog dialog;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.intermediat);
myLocation.getLocation(getApplicationContext(), locationResult);
boolean r = myLocation.getLocation(getApplicationContext(),
locationResult);
startActivity(new Intent(LocationFinder.this,
// Nearbyhotelfinder.class));
GPSMyListView.class));
finish();
}
public LocationResult locationResult = new LocationResult() {
#Override
public void gotLocation(Location location) {
// TODO Auto-generated method stub
double Longitude = location.getLongitude();
double Latitude = location.getLatitude();
Toast.makeText(getApplicationContext(), "Got Location",
Toast.LENGTH_LONG).show();
try {
SharedPreferences locationpref = getApplication()
.getSharedPreferences("location", MODE_WORLD_READABLE);
SharedPreferences.Editor prefsEditor = locationpref.edit();
prefsEditor.putString("Longitude", Longitude + "");
prefsEditor.putString("Latitude", Latitude + "");
prefsEditor.commit();
System.out.println("SHARE PREFERENCE ME PUT KAR DIYA.");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
// handler for the background updating
}
MyLocation
public class MyLocation {
Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled=false;
boolean network_enabled=false;
public boolean getLocation(Context context, LocationResult result)
{
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}
//Toast.makeText(context, gps_enabled+" "+network_enabled, Toast.LENGTH_LONG).show();
//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;
if(gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if(network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1=new Timer();
timer1.schedule(new GetLastLocation(), 10000);
// Toast.makeText(context, " Yaha Tak AAya", Toast.LENGTH_LONG).show();
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
LocationListener locationListenerNetwork = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
class GetLastLocation extends TimerTask {
#Override
public void run() {
//Context context = getClass().getgetApplicationContext();
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if(gps_loc!=null){
locationResult.gotLocation(gps_loc);
return;
}
if(net_loc!=null){
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}
With google things changes very often: non of the previous answers worked for me.
based on this google training here is how you do it using
fused location provider
this requires Set Up Google Play Services
Activity class
public class GPSTrackerActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
Location mLastLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnected(Bundle bundle) {
try {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
Intent intent = new Intent();
intent.putExtra("Longitude", mLastLocation.getLongitude());
intent.putExtra("Latitude", mLastLocation.getLatitude());
setResult(1,intent);
finish();
}
} catch (SecurityException e) {
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
usage
in you activity
Intent intent = new Intent(context, GPSTrackerActivity.class);
startActivityForResult(intent,1);
And this method
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1){
Bundle extras = data.getExtras();
Double longitude = extras.getDouble("Longitude");
Double latitude = extras.getDouble("Latitude");
}
}
you can got Current latlng using this
`
public class MainActivity extends ActionBarActivity {
private LocationManager locationManager;
private String provider;
private MyLocationListener mylistener;
private Criteria criteria;
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Define the criteria how to select the location provider
criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE); //default
// user defines the criteria
criteria.setCostAllowed(false);
// get the best provider depending on the criteria
provider = locationManager.getBestProvider(criteria, false);
// the last known location of this provider
Location location = locationManager.getLastKnownLocation(provider);
mylistener = new MyLocationListener();
if (location != null) {
mylistener.onLocationChanged(location);
} else {
// leads to the settings because there is no last known location
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
// location updates: at least 1 meter and 200millsecs change
locationManager.requestLocationUpdates(provider, 200, 1, mylistener);
String a=""+location.getLatitude();
Toast.makeText(getApplicationContext(), a, 222).show();
}
private class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
// Initialize the location fields
Toast.makeText(MainActivity.this, ""+location.getLatitude()+location.getLongitude(),
Toast.LENGTH_SHORT).show()
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Toast.makeText(MainActivity.this, provider + "'s status changed to "+status +"!",
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(MainActivity.this, "Provider " + provider + " enabled!",
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(MainActivity.this, "Provider " + provider + " disabled!",
Toast.LENGTH_SHORT).show();
}
}
`
Above solutions is also correct, but some time if location is null then it crash the app or not working properly. The best way to get Latitude and Longitude of android is:
Geocoder geocoder;
String bestProvider;
List<Address> user = null;
double lat;
double lng;
LocationManager lm = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
bestProvider = lm.getBestProvider(criteria, false);
Location location = lm.getLastKnownLocation(bestProvider);
if (location == null){
Toast.makeText(activity,"Location Not found",Toast.LENGTH_LONG).show();
}else{
geocoder = new Geocoder(activity);
try {
user = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
lat=(double)user.get(0).getLatitude();
lng=(double)user.get(0).getLongitude();
System.out.println(" DDD lat: " +lat+", longitude: "+lng);
}catch (Exception e) {
e.printStackTrace();
}
}
Best way is
Add permission manifest file
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Then you can get GPS location or if GPS location is not available then this function return NETWORK location
public static Location getLocationWithCheckNetworkAndGPS(Context mContext) {
LocationManager lm = (LocationManager)
mContext.getSystemService(Context.LOCATION_SERVICE);
assert lm != null;
isGpsEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkLocationEnabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
Location networkLoacation = null, gpsLocation = null, finalLoc = null;
if (isGpsEnabled)
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return null;
}gpsLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (isNetworkLocationEnabled)
networkLoacation = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (gpsLocation != null && networkLoacation != null) {
//smaller the number more accurate result will
if (gpsLocation.getAccuracy() > networkLoacation.getAccuracy())
return finalLoc = networkLoacation;
else
return finalLoc = gpsLocation;
} else {
if (gpsLocation != null) {
return finalLoc = gpsLocation;
} else if (networkLoacation != null) {
return finalLoc = networkLoacation;
}
}
return finalLoc;
}
You can use FusedLocationProvider
For using Fused Location Provider in your project you will have to add the google play services location dependency in our app level build.gradle file
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
...
...
...
implementation 'com.google.android.gms:play-services-location:17.0.0'
}
Permissions in Manifest
Apps that use location services must request location permissions. Android offers two location permissions: ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
As you may know that from Android 6.0 (Marshmallow) you must request permissions for important access in the runtime. Cause it’s a security issue where while installing an application, user may not clearly understand about an important permission of their device.
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION),
PERMISSION_ID
)
Then you can use the FusedLocationProvider Client to get the updated location in your desired place.
mFusedLocationClient.lastLocation.addOnCompleteListener(this) { task ->
var location: Location? = task.result
if (location == null) {
requestNewLocationData()
} else {
findViewById<TextView>(R.id.latTextView).text = location.latitude.toString()
findViewById<TextView>(R.id.lonTextView).text = location.longitude.toString()
}
}
You can also check certain configuration like if the device has location settings on or not. You can also check the article on Detect Current Latitude & Longitude using Kotlin in Android for more functionality.
If there is no cache location then it will catch the current location using:
private fun requestNewLocationData() {
var mLocationRequest = LocationRequest()
mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
mLocationRequest.interval = 0
mLocationRequest.fastestInterval = 0
mLocationRequest.numUpdates = 1
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
mFusedLocationClient!!.requestLocationUpdates(
mLocationRequest, mLocationCallback,
Looper.myLooper()
)
}
Plug and play location-manager that can be used both in XML-based projects and Jetpack Compose projects (personally using it in JetpackCompose)
class LocationManager(context: Context): LocationCallback() {
val context = context
var publicCompletion: ((Double, Double) -> Unit)? = null
var fusedLocationProviderClient = FusedLocationProviderClient(
context
)
fun requestLocationPermission() {
val activity = context as Activity?
ActivityCompat.requestPermissions(
activity!!,
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION
),
101
)
}
fun checkIfLocationPermissionIsGranted(): Boolean {
return (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
)
}
fun getLatitudeLongitude(completion: (Double, Double) -> Unit) {
publicCompletion = { latitude, longitude ->
completion(latitude, longitude)
}
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
val activity = context as Activity?
fusedLocationProviderClient.lastLocation.addOnCompleteListener(activity!!) { task ->
var location: Location? = task.result
if (location != null) {
publicCompletion?.let { it(location!!.latitude, location!!.longitude) }
} else {
requestLocationUpdates()
}
}
}
}
fun requestLocationUpdates() {
var request = LocationRequest()
request.priority = com.google.android.gms.location.LocationRequest.PRIORITY_HIGH_ACCURACY
request.fastestInterval = 0
request.numUpdates = 1
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
fusedLocationProviderClient.requestLocationUpdates(
request, this, Looper.myLooper()
)
}
}
override fun onLocationResult(p0: LocationResult?) {
super.onLocationResult(p0)
publicCompletion?.let { it(p0!!.lastLocation!!.latitude, p0!!.lastLocation!!.longitude) }
}
override fun onLocationAvailability(p0: LocationAvailability?) {
super.onLocationAvailability(p0)
}
}
Just follow Google recommendation and prepared codes in kotlin: (Supports also Android 11 and 12):
https://github.com/googlecodelabs/while-in-use-location
and its step by step explanation:
https://codelabs.developers.google.com/codelabs/while-in-use-location
I need a method to simply get latitude and longitude. I'm developing my first app... can you tell me if i'm doing it in the right way?
Here is my method:
private void getCoordinates() {
getCurrentLocation();
boolean gpsEnabled = lManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean netEnabled = lManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!gpsEnabled && !netEnabled && location != null) {
Builder alarm = new AlertDialog.Builder(this);
alarm.setTitle("Error");
alarm.setMessage("Localization OFF").create().show();
} else if (location != null && (gpsEnabled || netEnabled)) {
lManager.removeUpdates(lListener);
lat = String.valueOf(location.getLatitude());
lon = String.valueOf(location.getLongitude());
} else {
Builder alarm = new AlertDialog.Builder(this);
alarm.setTitle("Error");
alarm.setMessage("Localization OFF").create().show();
}
}
private void getCurrentLocation() {
lManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
lListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onLocationChanged(Location loc) {
location = loc;
}
};
LocationProvider gpsProvider = lManager.getProvider(LocationManager.GPS_PROVIDER);
if (gpsProvider != null) {
boolean gpsEnabled = lManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean netEnabled = lManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!gpsEnabled && netEnabled) {
lManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, lListener);
location = lManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
} else if (gpsEnabled) {
lManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, lListener);
location = lManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
} else {
Builder alarm = new AlertDialog.Builder(this);
alarm.setTitle("Error");
alarm.setMessage("GPS provider not supported").create().show();
}
}
Please fix it if you can see anything wrong or give me any suggestions.
The problem is when you setup a listener for the location it does not receive a location instantly- especially with a GPS location. So your location is not returning the current coordinates.
You can call the getLastKnownLocation in your location manager but this could be an old or non-existant location. The other option is to call something from
#Override
public void onLocationChanged(Location loc) {
someCallBack(loc);
}
Have a look at my NoteLocation example on github
Link