I'm writing an app where a method is executed based on the users geo location. I'm using an Activity which implements LocationListener. Location latitude and longitude is stored in a database, and whenever the user gets within range of the current location, compared to the location stored, a method is executed.
My problem is that, the methods startTimer(), startTimer() is executed whenever the user moves around whithin the proximity. I want startTimer() to be executed once, whenever the user enters the area, and stopTimer() whenever the user exits the area.
So far i got this, but only seems to work when leaving the area:
#Override
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();
Log.i("", "Latitude: " + latitude);
Log.i("", "Longitude: " + longitude);
if(activities != null) {
for (Activity activity : activities) {
Location newLocation = new Location(provider);
newLocation.setLongitude(activity.getLongitude());
newLocation.setLatitude(activity.getLatitude());
if(location.distanceTo(newLocation) > 15) {
activity.setInProximity(false);
stopTimer(activity.getId());
}
if (location.distanceTo(newLocation) <= 15 && !activity.isInProximity()) {
activity.setInProximity(true);
startTimer(activity.getId());
}
}
}
}
It looks like you are almost there/tried to implement this already - just missed the calls to your function in the first if statement (and also should be an if/else statement)
#Override
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();
Log.i("", "Latitude: " + latitude);
Log.i("", "Longitude: " + longitude);
if(activities != null) {
for (Activity activity : activities) {
Location newLocation = new Location(provider);
newLocation.setLongitude(activity.getLongitude());
newLocation.setLatitude(activity.getLatitude());
if(location.distanceTo(newLocation) > 15 && activity.isInProximity()) {
activity.setInProximity(false);
stopTimer(activity.getId());
}
else if (location.distanceTo(newLocation) <= 15 && !activity.isInProximity()) {
activity.setInProximity(true);
startTimer(activity.getId());
}
}
}
}
where
void setInProximity(boolean status)
and
boolean isInProximity()
should be getters/setters to a private boolean data member of the Activity class you iterate through
Related
I developed a GPS app but it works correctly when location service turns off and again turn on. When getting GPS without location service turn off and again turn on GPS ,latitude and longitude are not correct. How can I fix it?
public void onLocationChanged(Location location) {
try {
latitute = location.getLatitude();
longitude = location.getLongitude();
accuracy = location.getAccuracy();
Provider = location.getProvider();
Toast.makeText(getContext(), "onLocationChanged: " + "Lat: " + latitute + "Lon: " + longitude, Toast.LENGTH_SHORT).show();
latituteField.setText(String.valueOf((double) latitute));
longitudeField.setText(String.valueOf((double) longitude));
txtaccuracy.setText(String.valueOf((double) accuracy));
txtprovider.setText(String.valueOf(Provider));
} catch (Exception e) {
}
Check in your onResume() method of your activity that Gps is enabled or not.
if Gps is not enabled then ask user to enable GPS/network in settings.
after Gps enable start your GPSTracker service to get location.
#Override
protected void onResume() {
super.onResume();
// Check if GPS is not enabled
if (!canGetLocation) {
// GPS or network is not enabled.
// Ask user to enable GPS/network in settings.
}
}
am trying to create a Google Maps activity that gets the users current location and places a pin on the users' current location. I have tried the code with static latitude and longitude values and the map worked as it should. When I tried to get the LatLong values programmatically, the system threw a NullPointerException at line 127 containing the code double longitude = location.getLongitude();.
What am I doing wrong and how can I rectify it? Thanks in advance for your assistance.
Activity Code
#Override
public void onMapReady(GoogleMap googleMap) {
try {
if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(getActivity(), new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 101);
}
} catch (Exception e){
e.printStackTrace();
}
LocationManager lm = (LocationManager)getActivity().getSystemService(Context.LOCATION_SERVICE);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
double longitude = location.getLongitude();
double latitude = location.getLatitude();
gmap = googleMap;
gmap.setMinZoomPreference(12);
gmap.setIndoorEnabled(true);
UiSettings uiSettings = gmap.getUiSettings();
uiSettings.setIndoorLevelPickerEnabled(true);
uiSettings.setMyLocationButtonEnabled(true);
uiSettings.setMapToolbarEnabled(true);
uiSettings.setCompassEnabled(true);
uiSettings.setZoomControlsEnabled(true);
LatLng ny = new LatLng(latitude, longitude);
gmap.moveCamera(CameraUpdateFactory.newLatLng(ny));
}
Logcat
Process: ke.co.mytech.mytech, PID: 8425
java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLongitude()' on a null object reference
at ke.co.mytech.mytech.HomeFragment.onMapReady(HomeFragment.java:127)
at com.google.android.gms.maps.zzac.zza(Unknown Source)
at com.google.android.gms.maps.internal.zzaq.dispatchTransaction(Unknown Source)
at com.google.android.gms.internal.maps.zzb.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:392)
at fg.b(:com.google.android.gms.dynamite_mapsdynamite#13280046#13.2.80 (040306-211705629):19)
at com.google.android.gms.maps.internal.bg.a(:com.google.android.gms.dynamite_mapsdynamite#13280046#13.2.80 (040306-211705629):5)
at com.google.maps.api.android.lib6.impl.be.run(:com.google.android.gms.dynamite_mapsdynamite#13280046#13.2.80 (040306-211705629):5)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5728)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
A few things that might help.
One, try using the FusedLocationProviderClient to get the location.
FusedLocationProviderClient fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context);
fusedLocationProviderClient.getLastLocation()
.addOnSuccessListener(new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if(location != null) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
Log.i(TAG, "Latitude: " + latitude + " | Longitude: " + longitude);
} else {
Log.e(TAG, "Unable to retrieve location");
}
}
});
Second, I had this issue when I was testing on the emulator and it always raised the same exception as you are mentioning. What I did to fix it was to go into the Google Maps application on my emulator and let it pinpoint my location by clicking on the circle target button. I am not sure as to why it worked (I think it was because it saved my location which it was unable to do before).
Got the answer to what I was doing wrong in this question
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I'm trying to get the difference between 2 locations of which i have taken from the gps, Whenever i click on a button to go to my MapsActivity i get crashed with this error
Attempt to invoke virtual method 'com.google.android.gms.maps.model.Marker com.google.android.gms.maps.GoogleMap.addMarker(com.google.android.gms.maps.model.MarkerOptions)' on a null object reference
And When i comment the code which checks difference in distance it works just fine, i don't understand the connection between the Marker options and the DistanceTo
Here's my Code (Keep in mind that all works fine it's just the DistanceTo which doesn't work)
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
//get the latitude and longitude from the location
double latitude = location.getLatitude();
double longitude = location.getLongitude();
//get the location name from latitude and longitude
Geocoder geocoder = new Geocoder(getApplicationContext());
try {
if(location != null)
// this gives address list from the maps, not important and commented
{
List<Address> addresses =
geocoder.getFromLocation(latitude, longitude, 1);
// Marker options where the issue occurs
//String result = addresses.get(0).getSubLocality()+":";
//result += addresses.get(0).getLocality()+":";
// result += addresses.get(0).getCountryCode();
LatLng latLng = new LatLng(latitude, longitude);
mMap.addMarker(new MarkerOptions().position(latLng).title("Marker Title"));
mMap.setMaxZoomPreference(20);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}
} catch (IOException e) {
e.printStackTrace();
}
//Where it checks for the locations and the distance between them
if(LocationA == null) {
LocationA = location;
}
LocationB = location;
LocationA = LocationB;
DiffernceInDistance = LocationA.distanceTo(LocationB);
}
Code where i made the Map
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if(ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
The issue was that i was asking for locations and also applying a marker at the same time, so markers couldn't load to the location, to solve it I commented, It doesn't crash anymore but it didn't solve my main issue (DistanceTo not working but that's not the reason i made this post therefore i won't ask for anymore help thanks )
mMap.addMarker(new MarkerOptions().position(latLng).title("Marker Title"));
I have been developing an app that keeps track of distance run/walked by a user.
I used the FusedLocationProviderClient with a foreground service. I set the following parameters for the LocationRequest object,
mLocationRequest.setInterval(3000);
mLocationRequest.setFastestInterval(500);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(6.4008) //7 yards
And, for getting location updates,
mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
Location location = locationResult.getLastLocation();
if (mLocation == null) {
if (location.hasAccuracy() && isLocationAccurate(location)) {
mLocation = location;
isGpsAccurate = true;
}
} else {
if (location.hasAccuracy() && isLocationAccurate(location))
calculateDistance(location);
}
}
};
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
Here's the code for isLocationAccurate(location),
boolean isLocationAccurate(Location location) {
float accuracy = location.getAccuracy();
return accuracy > 0 && accuracy < MIN_ACCURACY;
}
And Here's the code for calculateDistance(location),
private calculateDistance(location){
distance += mLocation.distanceTo(location);
mLocation = location;
}
That's the code, works well when moving, but when stationary and indoors(sometimes outdoors), the value keeps changing.
Am I doing something wrong here?
Note: I verified with Strava and Runkeeper. Distance remains constant over there. So, my device(ONE PLUS 3T) works fine.
*There is a getSpeed() function
simple format is
if(location.getSpeed() > 50){
calculateDistance(location);
}
so if the device is in movement means tracking will started otherwise no need to track, just show marker in the last updated position
i wan to ask you: i am using google Maps in my application and when i open the activity that has the map i want the user current location to be determine, i am using this code to retrieve the current user location
public void locat ()
{
//Use the LocationManager class to obtain GPS locations
LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
}
// Class My Location Listener
public class MyLocationListener implements LocationListener
{
#Override
public void onLocationChanged(Location loc)
{
loc.getLatitude();
loc.getLongitude();
String Text = "My current location is: " + "Latitud = " + loc.getLatitude() +"Longitud = " + loc.getLongitude();
Toast.makeText( getApplicationContext(),
Text,
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider)
{
Toast.makeText( getApplicationContext(),"Gps Disabled",Toast.LENGTH_SHORT ).show();
}
#Override
public void onProviderEnabled(String provider)
{
Toast.makeText( getApplicationContext(),"Gps Enabled",Toast.LENGTH_SHORT).show();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}// End of Class MyLocationListener */
but it is just give me the latitude and longitude and that is not what i want! i want to determine the user current location in google maps!how can i do it ? do you need my code to google MAps? Please please help me! THANK YOU
If I understand your question correctly you want to get the users current position and show it on a map. You have the latitude and longitude values, all you need to do is construct a GeoPoint and animate to that position on the map. You can also add a custom overlay to the map if desired. Something like the following should help.
double lat = location.getLatitude();
double longi = location.getLongitude();
long time = location.getTime();
GeoPoint currentGeo = new GeoPoint(toMicroDegrees(lat), toMicroDegrees(longi));
MapController controller = map.getController();
controller.animateTo(currentGeo);
You are never actually passing the information to a map in order to display the location.
What you need to do is get the MapView from the layout you displaying.
Then get the controller of the map view and set the users location as the centre/animate to their location.
Something similar to this:
mapView1 = (MapView) this.findViewById(R.id.map);
MapController mapControl = mapView1.getController();
GeoPoint geo = new GeoPoint((int)(lat)*1e6), (int(long*1e6));
mapControl.animateTo(geo);
This link should help http://mobiforge.com/developing/story/using-google-maps-android
You can open google maps with a geo uri like so:
String url = "geo:48.200927,16.369548,192";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
Edit: It appears that you want reverse geocoding. Here is an example:
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
List<Address> addresses = geocoder.getFromLocation(lat, lng, 1);
Here is the documentation for the android Geocoder class - http://developer.android.com/reference/android/location/Geocoder.html