I just want to get user's postcode once. I am looking to start my app, check the user's current position once and stop checking. In the event I am unable to get it due to no connection, then I want to just use last known position provided it exists. Can I get some advice on this please.
My following code keeps showing null for last known position since I don't have one. And I do not want to look for location change. Irregardless of whether I move or not, check for position on app start and stop checking after.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
provider = locationManager.getBestProvider(new Criteria(), false);
Location location;
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
1);
return;
}
location = locationManager.getLastKnownLocation(provider); // this is null and not ideal. I want current position.
Log.i("lat", String.valueOf(location.getLatitude()));
Log.i("lng", String.valueOf(location.getLongitude()));
getPostCode(location.getLatitude(), location.getLongitude());
}
private void getPostCode(double lat, double lng){
Geocoder geoCoder = new Geocoder(getApplicationContext(), Locale.getDefault());
List<Address> address = null;
try {
address = geoCoder.getFromLocation(lat, lng, 1);
} catch (IOException e) {
e.printStackTrace();
}
if (address != null) {
if (address.size() > 0) {
String postCode = address.get(0).getPostalCode();
Log.i("postcode", postCode);
}
}
}
Related
I am trying to ask for user location permission but I need to set some kind of listener to the user response otherwise, I cant get the user location and the app crashes due to null pointer exception.
This are the functions I am using to get and set the location
private void setLocation() {
if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 44);
}
LocationManager locationManager;
locationManager = (LocationManager) getSystemService(ScoreActivity.this.LOCATION_SERVICE);
Location location = locationManager.getLastKnownLocation(locationManager.NETWORK_PROVIDER);
onLocationChanged(location);
}
#Override
public void onLocationChanged(#NonNull Location location) {
locationDetails=new LatLng(location.getLatitude(),location.getLongitude());
}
So I'm making this app which finds restaurants near you, fetching information from a food-delivery app, using JSoup library.
The only problem with it is that sometimes the latitude and the longitude are getting null value.
Situations in which my application is working:
-turning on GPS and the waiting at least 1-2 minutes;
-opening google maps, closing it, and then returning to the application;
So the main problem: I can't fetch the location right after I enable it and hit the 'Find restaurants' button, I need to wait 1-2 minutes after enabling location, then it's working.
private TextView result;
private FusedLocationProviderClient client;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermission();
client = LocationServices.getFusedLocationProviderClient(this);
getBtn = findViewById(R.id.getRestaurants);
result = findViewById(R.id.restaurantsList);
getBtn.setOnClickListener(this);
}
private void requestPermission(){
ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION}, 1 );
}
public void onClick(View v) {
if (ActivityCompat.checkSelfPermission(MainActivity.this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
return;
}
client.getLastLocation().addOnSuccessListener(MainActivity.this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
result.setText("Getting location...");
if(location != null){
double latitude = getLat(location);
double longitude = getLng(location);
result.setText("Finding restaurants near you...");
getWebsite(latitude, longitude);
}else{
result.setText("Couldn't fetch location!");
}
}
});
Here is a good way to implement the FusedLocationProvider in Kotlin (you might adapt to Java or use Java and Kotlin side by side) :
private fun startLoc() {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
try {
fusedLocationClient.lastLocation
.addOnSuccessListener { location: Location? ->
//showDialog(this#MapsActivity, TAG, "last know loc = ${location?.latitude} + ${location?.longitude}")
if (location != null){
lastKnowLoc = LatLng(location.latitude, location.longitude)
addMarkerToLocation(lastKnowLoc)
}
}
val locationRequest = LocationRequest()
locationRequest.interval = 10000
locationRequest.fastestInterval = 10000
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
locationResult ?: return
for (location in locationResult.locations){
//showDialog(this#MapsActivity, "locationResult", "location=${location.latitude};${location.longitude}")
addMarkerToLocation(LatLng(location.latitude, location.longitude))
val speed = location.speed
updateCamera(location.bearing)
}
}
}
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null)
btnStartLoc.isEnabled = false
btnStopLoc.isEnabled = true
}catch (e:SecurityException){}
}
you must use requestLocationUpdates()
you are using getLastLocation() and when the GPS is off and turned on after the last known location becomes null so you must call requestLocationUpdates()
you can find more information in the below link
https://developer.android.com/training/location/receive-location-updates
It is OK when I open the GPS long times, I can get my current location, but when I turn off and then turn on the GPS, it returns null as the current location. I need to refresh or reinstall the app to make the current location work. Is it possible to get the location after a few seconds of turning on the GPS?
Here is my code:
client = LocationServices.getFusedLocationProviderClient(this);
LocationManager locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);
finish();
} else {
if (ActivityCompat.checkSelfPermission(MapsActivity.this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
return;
}
client.getLastLocation().addOnSuccessListener(MapsActivity.this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if(location!= null){
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
});
}
I found out that I need to use requestsLoctionUpdates, but I cannot find any tutorial that explains me how to do it in the new version of android studio (Location : 11.8.0). Can anyone can tell me how to use this code?
Im facing some problem with my application, specifically with route plot/draw on my google maps. Ive made test route around my house and found out, that GPS providers are not as accurate as similar applications like runtastic or endomondo.
Sometimes Location listener makes incomprehensible changes on my map and the polyline then draws any lines on the map near my location even with perfect GPS signal.
Some other time, it just doesnot work. It does not listen to location change.
Can anybody explain me (like Im five) how does other fitness application get their current position and the plot route onto the google map? Thanks!
//Map Fragment
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.fragment1)).getMap();
map.setMyLocationEnabled(true);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, true);
//Permission gain
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) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION},
MY_PERMISSION_ACCESS_COURSE_LOCATION);
return;
}
isLocationEnabled(getApplicationContext());
Location myLocation = locationManager.getLastKnownLocation(provider);
if (myLocation != null) {
latitude = myLocation.getLatitude();
longitude = myLocation.getLongitude();
float zoom = (float) 17.0;
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), zoom));
Log.e("TAG", "GPS is on");
Toast.makeText(MainActivity.this, "latitude:" + latitude + " longitude:" + longitude, Toast.LENGTH_SHORT).show();
} else {
locationManager.requestLocationUpdates(provider, 5000, 0, this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 10, this);
}
public void onLocationChanged(Location mylocation) {
if (lastLocationloc == null) {
lastLocationloc = mylocation;
}
LatLng lastLatLng = locationToLatLng(lastLocationloc);
LatLng thisLatLng = locationToLatLng(mylocation);
map.addPolyline(new PolylineOptions().add(lastLatLng).add(thisLatLng).width(6).color(Color.RED));
lastLocationloc = mylocation;
Toast.makeText(MainActivity.this, "!!!!Location CHANGE!!!!", Toast.LENGTH_SHORT).show();
}
public static LatLng locationToLatLng(Location loc) {
if (loc != null)
return new LatLng(loc.getLatitude(), loc.getLongitude());
return null;
}
For example, I want to plot it like this:
But my application works its own way..
First of all, you need to take into account the accuracy of the received location. You can get the accuracy using the Location.getAccuracy() method (documentation). The accuracy is measured in meters, so the lower the better:
if (location.getAccuracy() < MINIMUM_ACCURACY) {
// Add the new location to your polyline
}
You can set your MINIMUM_ACCURACY to be 10 meter for example.
On the other hand, you may want to add a new location to your polyline only if your new location is farther than a given distance to your last added location. As an example:
private static final float MINIMUM_ACCURACY = 10;
private static final float MINIMUM_DISTANCE_BETWEEN_POINTS = 20;
private Location lastLocationloc;
// ...
public void onLocationChanged(Location mylocation) {
if (mylocation.getAccuracy() < MINIMUM_ACCURACY) {
if (lastLocationloc == null || lastLocationloc.distanceTo(mylocation) > MINIMUM_DISTANCE_BETWEEN_POINTS) {
// Add the new location to your polyline
lastLocationloc = mylocation;
}
}
}
I am getting the longitude and latitude of my device, but it takes at 30 seconds to a minute to do so. Any suggestions to cut the time down?
public class MainActivity extends Activity
{
public String zipcode;
public double latG;
public double lonG;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean enabled = service.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!enabled)
{
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.getLastKnownLocation(Context.LOCATION_SERVICE);
LocationListener locationListener = new LocationListener()
{
public void onLocationChanged(Location location)
{
if (location != null)
{
latG = location.getLatitude();
lonG = location.getLongitude();
Toast.makeText(MainActivity.this,
latG + " " + lonG,
Toast.LENGTH_LONG).show();
}
}
public void onProviderDisabled(String provider)
{
}
public void onProviderEnabled(String provider)
{
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
List<Address> addresses = null;
try
{
addresses = geocoder.getFromLocation(latG, lonG, 1);
}
catch (IOException e)
{
Context context = this;
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
alertDialogBuilder.setTitle("Error");
alertDialogBuilder.setMessage("Error in getting address information.");
alertDialogBuilder.setCancelable(true);
}
for (Address address : addresses)
{
if(address.getPostalCode() != null)
{
zipcode = address.getPostalCode();
Toast.makeText(MainActivity.this, zipcode, Toast.LENGTH_LONG).show();
break;
}
}
}
}
You are using GPS_PROVIDER for fetching the GPS data. GPS_PROVIDER fetches details directly from the satellite so it takes time for the first time you load this. Moreover GPS_PROVIDER takes more than 30 seconds if your are not below the open sky. GPS_PROVIDER may return NULL when you are inside the office or in basement.
There is an alternative way for this is to use NETWORK_PROVIDER. This provider will give you GPS details based on your current Network state. This will not be much accurate like GPS_PROVIDER but it works faster.
hi you are using GPS PROVIDER which can take some time as it depends on several constraints like yours building position, physical position, weather as gps data is available from the satellite so use a network provider which may faster in yours case please have a look on the given code snippet at
http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial/
Best option is to use Google Play Services and its LocationClient.
http://developer.android.com/google/play-services/location.html
This gives you a provider that automatically picks the best available information from all the provider types and can return the location immediately in some cases using getLastLocation()
try to run it in device rather than running it in the emulator.
try this
try {
gps_enabled = locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
}
try {
network_enabled = locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {}
if (gps_enabled) {
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);
}
if (network_enabled) {
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locListener);
It will give the response what ever the service is available.Even you can place your priority
Use this code to fetch faster,
String provider;
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
if (provider != null && !provider.equals("")) {
Location location = locationManager.getLastKnownLocation(provider);
locationManager.requestLocationUpdates(provider, 20000, 1, this);
if (location != null)
{
onLocationChanged(location);
//your remaining code
}