I am implementing an android application in java to retrieve Location but the location doesn't update every time i call the function , it always returns me the same positions and i don't understand why.First i collect the position by calling the getCurrentLocation function ,then the callbackLocation function to update the location and finally the onstartLocationUpdates() to call the callbackLocation function; .I also allow all the permission when launching the app. Here is the code i've implemented :
public class TimeService extends Service {
private final static String TAG = TimeService.class.getName();
BroadcastReceiver mReceiver;
private LocationCallback locationCallback;
LocationRequest locationRequest;
FusedLocationProviderClient fusedClient;
double Longitude, Latitude, Altitude;
float Accuracy;
#Override
public void onCreate() {
super.onCreate();
fusedClient = LocationServices.getFusedLocationProviderClient(this);
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, new IntentFilter("sendLocationIntent"));
getCurrentLocation();
callbackLocation();
}
//Here when i am trying to update the location when i receive the upcoming message
private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (!intent.getAction().equals("sendLocationIntent")) {
return;
}
onstartLocationUpdates();
String socket_id = intent.getStringExtra("socket_id");
String messageTosend = Latitude + ":" + Longitude + ":" + Altitude + ":" + Accuracy + ":" + socket_id + ":" + globals.getDeviceIMEI(TimeService.this);
;
sendLocationMessageWithStatus();
}
};
protected void sendLocationMessageWithStatus(String phoneNumber, String Msg) {
//Send message block
}
public void getCurrentLocation() {
fusedClient.getLastLocation()
.addOnSuccessListener(getMainExecutor(), new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if (location != null) {
Latitude = location.getLatitude();
Longitude = location.getLongitude();
Accuracy = location.getAccuracy();
}
}
});
//Setting
createLocationRequest();
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
SettingsClient client = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
task.addOnSuccessListener(getMainExecutor(), new OnSuccessListener<LocationSettingsResponse>() {
#Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
// All location settings are satisfied. The client can initialize
// location requests here.
// ...
}
});
}
protected void createLocationRequest() {
locationRequest = new LocationRequest();
LocationRequest.Builder locationRequestBuilder = new LocationRequest.Builder(locationRequest);
locationRequestBuilder.setIntervalMillis(10000);
locationRequestBuilder.setMinUpdateIntervalMillis(5000);
locationRequestBuilder.setPriority(Priority.PRIORITY_HIGH_ACCURACY);
}
private void onstartLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
fusedClient.requestLocationUpdates(locationRequest,
locationCallback,
Looper.getMainLooper());
private void callbackLocation(){
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
Latitude = location.getLatitude();
Longitude = location.getLongitude();
Accuracy = location.getAccuracy();
}
}
};
}
}
Related
i am implementing an app using GPS functionalities to get positions . The problem is , sometimes it takes a lot of time to get the different positions ,sometimes not .Plus there are sometimes i get 0.0 for all the positions i get and i don't understand why; and finally there are some moments ,i can retrieve the same positions anytime i make a request even if i change places .. Here is the code i've implement :
#RequiresApi(api = Build.VERSION_CODES.R)
public class TimeService extends Service {
private final static String TAG = TimeService.class.getName();
BroadcastReceiver mReceiver;
//region data
FusedLocationProviderClient fusedClient;
double Longitude,Latitude,Altitude;
float Accuracy;
private LocationRequest mRequest;
private LocationCallback mCallback;
private Location currentLocation;
#Override
public void onCreate() {
super.onCreate();
locationInitiate();
startLocationUpdates();
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, new IntentFilter("sendLocationIntent"));
}
protected void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
fusedClient.requestLocationUpdates(mRequest, mCallback, null);
}
public void locationInitiate() {
mCallback = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location loc : locationResult.getLocations()) {
//ltext.setText("\n"+ loc.getProvider() + ":Accu:(" + loc.getAccuracy() + "). Lat:" + loc.getLatitude() + ",Lon:" + loc.getLongitude());
Log.d("##########" ,"time service 1 "+loc.getProvider() + ":Accu:(" + loc.getAccuracy() + "). Lat:" + loc.getLatitude() + ",Lon:" + loc.getLongitude() );
if (loc.getAccuracy() <= 20f) {
fusedClient.removeLocationUpdates(mCallback);
sendLocation(loc);
Latitude=loc.getLatitude();
Longitude=loc.getLongitude();
Accuracy=loc.getAccuracy();
sendLocation(loc);
break;
}
currentLocation = loc;
}
}
#Override
public void onLocationAvailability(#NonNull LocationAvailability locationAvailability) {
super.onLocationAvailability(locationAvailability);
}
};
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
} else {
locationWizardry();
}
}
/*loc in bacground*/
private void locationWizardry() {
fusedClient = LocationServices.getFusedLocationProviderClient(this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
fusedClient.getLastLocation().addOnSuccessListener(location -> {
if (location != null) {
String loc = location.getProvider() + ":Accu:(" + location.getAccuracy() + "). Lat:" + location.getLatitude() + ",Lon:" + location.getLongitude();
currentLocation = location;
}
});
createLocRequest();
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mRequest);
SettingsClient client = LocationServices.getSettingsClient(getApplicationContext());
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
task.addOnFailureListener(e -> {
});
}
protected void createLocRequest() {
mRequest = new LocationRequest();
mRequest.setInterval(1000);
mRequest.setFastestInterval(5000);
mRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(!intent.getAction().equals("sendLocationIntent")){
return;
}
String socket_id = intent.getStringExtra("socket_id");
String messageTosend=Latitude +":"+Longitude+":"+Altitude+":"+Accuracy+":"+socket_id+":"+ globals.getDeviceIMEI(TimeService.this);
Log.d("TAG", "onReceive: location information "+messageTosend);
String cryptedMessage=globals.encryptMessage(messageTosend,"0123456776543210");
sendLocationMessageWithStatus("6564","1212 "+cryptedMessage);
}
};
}
'''
public class GpsActivity extends FragmentActivity implements OnMapReadyCallback {
private static final int PRIORITY_HIGH_ACCURACY = 100;
private GoogleMap mMap;
private static final int PERMISSIONS_FINE_LOCATION = 99;
Location loc;
LatLng curPo;
boolean state = false;
private LocationRequest locationRequest;
private FusedLocationProviderClient fusedLocationProviderClient;
Button rstart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locationRequest = LocationRequest.create()
.setInterval(5000)
.setPriority(PRIORITY_HIGH_ACCURACY)
.setSmallestDisplacement(5);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(locationRequest);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(GpsActivity.this);
setContentView(R.layout.activity_gps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
rstart = findViewById(R.id.rstart);
rstart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
changeState();
}
});
askforPermission();
}
#SuppressLint("MissingPermission")
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if(checkPermission()){
mMap.setMyLocationEnabled(true);
}
mMap.getUiSettings().setMyLocationButtonEnabled(true);
}
#Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart");
if (checkPermission()) {
Log.d(TAG, "onStart : call mFusedLocationClient.requestLocationUpdates");
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, null);
if (mMap!=null)
mMap.setMyLocationEnabled(true);
}
}
#Override
protected void onStop() {
super.onStop();
if(fusedLocationProviderClient != null){
fusedLocationProviderClient.removeLocationUpdates(locationCallback);
}
}
// Methods
private void askforPermission(){
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED){
LocationCallback mCallback = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
for(Location location : locationResult.getLocations()){
setCurrentLocation(location);
}
}
};
fusedLocationProviderClient.requestLocationUpdates(locationRequest,mCallback,null);
fusedLocationProviderClient.removeLocationUpdates(mCallback);
}else{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_FINE_LOCATION);
}
}
}
private boolean checkPermission() {
int hasFineLocationPermission = ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
int hasCoarseLocationPermission = ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION);
if (hasFineLocationPermission == PackageManager.PERMISSION_GRANTED &&
hasCoarseLocationPermission == PackageManager.PERMISSION_GRANTED ) {
return true;
}
return false;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case PERMISSIONS_FINE_LOCATION:
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
askforPermission();
}else{
Toast.makeText(this,"this App requires permission for gps", Toast.LENGTH_SHORT).show();
finish();
}
}
}
public void setCurrentLocation(Location location) {
LatLng startLatLng = new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(startLatLng, 15);
mMap.moveCamera(cameraUpdate);
//mMap.addMarker(new MarkerOptions().position(currentLatLng)); //확인용
}
LocationCallback locationCallback = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
List<Location> savedLocation = locationResult.getLocations();
if(savedLocation.size() > 0){
loc = savedLocation.get(savedLocation.size() - 1);
curPo = new LatLng(loc.getLatitude(), loc.getLongitude());
String curPoLog = "Lat: " + loc.getLatitude() + "Long: " + loc.getLongitude();
Log.d(TAG,"OnLocationResult: " + curPoLog);
setCurrentLocation(loc);
}
}
};
public void changeState() {
if(!state){
mMap.clear();
state = true;
Toast.makeText(this, "Recording Start", Toast.LENGTH_SHORT).show();
if(state && checkPermission()){
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper());
addMarkerSingle();
}
rstart.setText("Stop");
}else{
state = false;
Toast.makeText(this, "Recording Stop", Toast.LENGTH_SHORT).show();
if(!state) {
addMarkerSingle();
fusedLocationProviderClient.removeLocationUpdates(locationCallback);
}
rstart.setText("Start");
}
}
public void addMarkerSingle(){
if(checkPermission()){
fusedLocationProviderClient.getLastLocation()
.addOnSuccessListener(new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
double markerLat = location.getLatitude();
double markerLong = location.getLongitude();
LatLng startEnd = new LatLng(markerLat, markerLong);
mMap.addMarker(new MarkerOptions().position(startEnd));
}
});
}
}
}
'''
Hi I'm a noob to programming this is my first project after learning 3month and I have no
idea how to make it happen
I want to draw a real time foot print tracking polyline but no matter what I do, it never works I tried to get a LatLng and draw a polyline from inside LocationCallback and I also tried making a new Thread to handle it I tried in onCreate, onMapReady and everything but it never works. so I came here to ask how you guys handle these kindda stuff.
I know it's shitty code and I know I suck plz understand, among 3 month of lessons java class went for only 2weeks we never even got to using Thread part, plz help me out.
the code above is code with out any errors. I can check my location on real time and there is start marker and end marker. What I want to do is track the paths I walked and show it with polyline. not after i finish I want it to keep updating real time
Thank you for your time and help
You need to store/cache the list of LatLng you get from LocationCallback.
Create a property
private ArrayList<String> myPath = new ArrayList<>();
Now every time a new location is received in the LocationCallback you add it to the myPath and update your map
LocationCallback locationCallback = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
List<Location> savedLocation = locationResult.getLocations();
if(savedLocation.size() > 0){
loc = savedLocation.get(savedLocation.size() - 1);
curPo = new LatLng(loc.getLatitude(), loc.getLongitude());
String curPoLog = "Lat: " + loc.getLatitude() + "Long: " + loc.getLongitude();
Log.d(TAG,"OnLocationResult: " + curPoLog);
setCurrentLocation(loc);
//add this
myPath.add(loc)
updateMap()
}
}
};
Your updateMap() method might look like this
PolylineOptions polylineOptions = new PolylineOptions();
polylineOptions.addAll(myPath);
polylineOptions.width(10f)
.color(Color.RED)
.geodesic(true);
if(mMap != null {
mMap.addPolyline(polylineOptions);
}
polyLineCollection.addPolyline(polylineOptions)
tempLine.tag = MarkerID(line.id, line.layerId , null)
try this code
//...
LocationCallback locationCallback = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
List<Location> savedLocation = locationResult.getLocations();
Polyline polyline1 = googleMap.addPolyline(new PolylineOptions()
.clickable(false);
for(int i = 0; i<savedLocation.size; i++){
polyline1.add(new LatLng(savedLocation[i].latitude, savedLocation[i].longitude)));
}
// Store a data object with the polyline, used here to indicate an arbitrary type.
polyline1.setTag("A");
// Style the polyline.
stylePolyline(polyline1);
if(savedLocation.size() > 0){
loc = savedLocation.get(savedLocation.size() - 1);
curPo = new LatLng(loc.getLatitude(), loc.getLongitude());
String curPoLog = "Lat: " + loc.getLatitude() + "Long: " + loc.getLongitude();
Log.d(TAG,"OnLocationResult: " + curPoLog);
setCurrentLocation(loc);
}
}
};
...//
I am Trying to make a map activity that i can choose my current location and make a marke on any location in the map,, i tried to use google documentation but i didn't understand how can i get latlng from this method any one have and idea about that !
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setInterval(10000);
locationRequest.setFastestInterval(5000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
// ...
SettingsClient client = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
#Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
// All location settings are satisfied. The client can initialize
// location requests here.
// ...
}
});
For your problem create a function like follows :
public void centreMapOnLocation(Location location, String title){
if (location != null) {
LatLng userLocation = new LatLng(location.getLatitude(), location.getLongitude());
mMap.addMarker(new MarkerOptions().position(userLocation).title(title));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15));
}
}
In onMapReady function add the following code :
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setOnMapLongClickListener(this);
mMap.clear();
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
centreMapOnLocation(location, "Your Location");
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
};
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0 , 0, locationListener);
Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
centreMapOnLocation(lastKnownLocation, "Your Location");
}else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},1);
}
}
In the onMapLongClick :
Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
String address = "";
try {
List<Address> listAddresses = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1);
if(listAddresses != null && listAddresses.size() > 0){
if (listAddresses.get(0).getThoroughfare() != null){
address += listAddresses.get(0).getThoroughfare() + " ";
}
address += listAddresses.get(0).getSubThoroughfare() + " ";
}
}catch (Exception e){
e.printStackTrace();
}
if (address.equals("")){
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm dd-MM-yyyy");
address += sdf.format(new Date());
}
mMap.addMarker(new MarkerOptions().position(latLng).title(address));
SharedPreferences sharedPreferences = this.getSharedPreferences("com.luv.memorableplaces", Context.MODE_PRIVATE);
try {
ArrayList<String> lat = new ArrayList<String>();
ArrayList<String> lng = new ArrayList<String>();
for (LatLng coord : MainActivity.locations){
lat.add(Double.toString(coord.latitude));
lng.add(Double.toString(coord.longitude));
sharedPreferences.edit().putString("latitudes", ObjectSerializer.serialize(lat)).apply();
sharedPreferences.edit().putString("longitudes", ObjectSerializer.serialize(lng)).apply();
}
sharedPreferences.edit().putString("places", ObjectSerializer.serialize(MainActivity.places)).apply();
}catch (Exception e){
e.printStackTrace();
}
Toast.makeText(this, "Location Saved", Toast.LENGTH_SHORT).show();
This will also help you save the previous location. Try it out, it should work.
While I install my app first time its always return null Location but IF any other app use location then I re- run the app then my app can get my location address. How can I update location successfully from the first run?
//here is my code
public class UserinfoActivity extends AppCompatActivity implements LocationListener {
private Button button;
private EditText editText_pin, editText_mobile, editText_address;
DatabaseReference databaseReference;
MyPreferences myPreferences;
FusedLocationProviderClient fusedLocationProviderClient;
private static final int REQUEST_CODE = 101;
Location currentLocation;
Intent intentThatCalled;
public double latitude;
public double longitude;
public LocationManager locationManager;
public Criteria criteria;
public String bestProvider;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_userinfo);
databaseReference = FirebaseDatabase.getInstance().getReference("user_responses");
myPreferences = MyPreferences.getPreferences(this);
fusedLocationProviderClient= LocationServices.getFusedLocationProviderClient(this);
intentThatCalled = getIntent();
getLocation();
//optional_check
if ( ContextCompat.checkSelfPermission( this, android.Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions( this, new String[] { android.Manifest.permission.ACCESS_COARSE_LOCATION },
REQUEST_CODE);
}
Task<Location> task=fusedLocationProviderClient.getLastLocation();
task.addOnSuccessListener(new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if(location!=null){
currentLocation=location;
}
}
});
public static boolean isLocationEnabled(Context context) {
//...............
return true;
}
protected void getLocation() {
if (isLocationEnabled(UserinfoActivity.this)) {
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
criteria = new Criteria();
bestProvider = String.valueOf(locationManager.getBestProvider(criteria, true)).toString();
//You can still do this if you like, you might get lucky:
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;
}
Location location = locationManager.getLastKnownLocation(bestProvider);
if (location != null) {
Log.e("TAG", "GPS is on");
Double latitude = location.getLatitude();
float float_latitude = latitude.floatValue();
myPreferences.setlatitude(float_latitude);
Double longitude = location.getLongitude();
float float_longitude = longitude.floatValue();
myPreferences.setlongitude(float_longitude);
/*Toast.makeText(MainActivity.this, "latitude:" + latitude + " longitude:" + longitude, Toast.LENGTH_SHORT).show();
searchNearestPlace(voice2text);*/
}
else{
//This is what you need:
locationManager.requestLocationUpdates(bestProvider, 1000, 0, this);
}
}
else
{
//prompt user to enable location....
//.................
}
}
#Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location location) {
locationManager.removeUpdates(this);
//open the map:
latitude = location.getLatitude();
longitude = location.getLongitude();
/*Toast.makeText(MainActivity.this, "latitude:" + latitude + " longitude:" + longitude, Toast.LENGTH_SHORT).show();
searchNearestPlace(voice2text);*/
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
This link might help you
http://shaoniiuc.com/android/android-receiving-location-updates-kotlin/
I'm assuming you've already COARSE and FINE locations in your manifest
Or something like this:
Log.d("Find Location", "in find_location");
this.con = con;
String location_context = Context.LOCATION_SERVICE;
locationManager = (LocationManager) con.getSystemService(location_context);
List<String> providers = locationManager.getProviders(true);
for (String provider : providers) {
locationManager.requestLocationUpdates(provider, 1000, 0,
new LocationListener() {
public void onLocationChanged(Location location) {}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status,
Bundle extras) {}
});
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
addr = ConvertPointToLocation(latitude, longitude);
String temp_c = SendToUrl(addr);
}
}
}
Call this from any method.
Source: https://stackoverflow.com/a/9873478/13319579
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