Related
With this code I'm trying to get get the location this code only works the first time I execute the emulator the Ihave to close the emulator in order to work again ,and it doesn't launch any error
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_insert);
myContext = this;
position =(TextView)findViewById(R.id.position);
locationManager=(LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(android.location.Location location) {
double latitude=location.getLatitude();
double longitude=location.getLongitude();
position.setText("lat:"+latitude+" lon:"+longitude);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
101);
}
else{
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null){
}
else{
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0,
0, locationListener);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
try {
switch (requestCode) {
case 101: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
} else {
}
return;
}
}
}
catch(SecurityException err_permission) {
}
}
}
and this permision on manifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
But the position is not shown on the textview, I think I don't missed anything,Do I?Maybe coarse_location permission ?I don'k know what is wrong on this code it has the locationmanager and the listener, and aks form permission...
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null){
}
else{
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0,
0, locationListener);
}
If you have the location you are not starting periodic updates, you may be looking for this:
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0,
0, locationListener);
if(location != null){
//Do things with the first location
}
So you start with something and keep updating with the listener
If there is a last known location from locationManager.getLastKnownLocation then you don't request location updates.
when my location is null my application force closes. I'm certain it's because the location returns null. I tried using the code with Mock GPS and the code works when it passes through the "if (myLocation != null)". I just can't "return myLocation;" after the "if (myLocation == null)"
Please help. Thank you.
#Override
public void onMapReady(GoogleMap googleMap) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
}, 10);
}
return;
}
gMap = googleMap;
if(!gMap.isMyLocationEnabled())
gMap.setMyLocationEnabled(true);
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location myLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (myLocation == null) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
String provider = lm.getBestProvider(criteria, true);
myLocation = lm.getLastKnownLocation(provider);
}
if I add "return myLocation;" after the "if( myLocation == null )"
It returns an error.
its because you are using void type return
public void onMapReady(GoogleMap googleMap)
use Location type.
public Location onMapReady(GoogleMap googleMap)
public void onMapReady(GoogleMap googleMap) is a abstract "call back" usage method, but i can see that you want to have a method to return a Location obj to use. There is several way to do.
One is use a global object to store the returned result like:
private Location location = null;
#Override
public void onMapReady(GoogleMap googleMap){
......
this.location = myLocation;
}
public void someMethodIUseLocation(){
//TO CALL this.location if need to use
}
just depends on how you wanted to call the way to implement is different
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;
}
}
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 am trying to find my current location for an android project. When the application is loaded my current location is always null. I have set up the permissions in the manifest etc. When I find the current location I intend to use the coordinates to find distances to other locations on the map. My code snippet is below. Why do I always get a null value?
locMan = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria crit = new Criteria();
towers = locMan.getBestProvider(crit, false);
location = locMan.getLastKnownLocation(towers);
if (location != null) {
System.out.println("Location is not null!");
lat = (int) (location.getLatitude() *1E6);
longi = (int) (location.getLongitude() * 1E6);
GeoPoint ourLocation = new GeoPoint(lati, longi);
OverlayItem overlayItem = new OverlayItem(ourLocation, "1st String",
"2nd String");
CustomPinpoint custom = new CustomPinpoint(d, MainMap.this);
custom.insertPinpoint(overlayItem);
overlayList.add(custom);
overlayList.clear();
} else {
System.out.println("Location is null! " + towers);
Toast.makeText(MainMap.this, "Couldn't get provider",Toast.LENGTH_SHORT)
.show();
}
getLastKnownLocation() uses the location(s) previously found by other applications. if no application has done this, then getLastKnownLocation() will return null.
One thing you can do to your code to have a better chance at getting as last known location- iterate over all of the enabled providers, not just the best provider. For example,
private Location getLastKnownLocation() {
List<String> providers = mLocationManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
Location l = mLocationManager.getLastKnownLocation(provider);
ALog.d("last known location, provider: %s, location: %s", provider,
l);
if (l == null) {
continue;
}
if (bestLocation == null
|| l.getAccuracy() < bestLocation.getAccuracy()) {
ALog.d("found best last known location: %s", l);
bestLocation = l;
}
}
if (bestLocation == null) {
return null;
}
return bestLocation;
}
If your app can't deal without having a location, and if there's no last known location, you will need to listen for location updates. You can take a look at this class for an example,
https://github.com/farble1670/autobright/blob/master/src/org/jtb/autobright/EventService.java
See the method onStartCommand(), where it checks if the network provider is enabled. If not, it uses last known location. If it is enabled, it registers to receive location updates.
if u find current location of devices the use following method in main class
public void find_Location(Context con) {
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);
}
}
}
And Add User Permission method in your manifest file
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Try this this will not give you null current location
class GetLastLocation extends TimerTask {
LocationManager mlocManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListenerTmp = new CustomLocationListener();
private final Handler mLocHandler;
public GetLastLocation(Handler mLocHandler) {
this.mLocHandler = mLocHandler;
}
#Override
public void run() {
timer.cancel();
mlocManager.removeUpdates(mlocListenerTmp);
Location location = mlocManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
{
if (mlocListenerTmp != null) {
mlocManager.removeUpdates(mlocListenerTmp);
}
currentLocation = location;
}
if (location != null) {
String message = String.format(
"Location \n Longitude: %1$s \n Latitude: %2$s",
location.getLongitude(), location.getLatitude());
Log.d("loc", " :" + message);
Bundle b = new Bundle();
{
b.putBoolean("locationRetrieved", true);
{
Message msg = Message.obtain();
{
msg.setData(b);
mLocHandler.sendMessage(msg);
}
}
}
} else {
Log.d(
"loc",
":No GPS or network signal please fill the location manually!");
location = mlocManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
currentLocation = location;
Bundle b = new Bundle();
{
b.putBoolean("locationRetrieved", true);
{
Message msg = Message.obtain();
{
msg.setData(b);
mLocHandler.sendMessage(msg);
}
}
}
} else {
Bundle b = new Bundle();
{
b.putBoolean("locationRetrieved", false);
{
Message msg = Message.obtain();
{
msg.setData(b);
mLocHandler.sendMessage(msg);
}
}
}
}
}
}
}
call it like this
timer.schedule(new GetLastLocation(mLocHandler), 3000);
and the customLocationclass is as follows
public class CustomLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
loc.getLatitude();
loc.getLongitude();
currentLocation = loc;
String Text = "My current location is: " + "Latitud = "
+ loc.getLatitude() + "Longitud = " + loc.getLongitude();
Log.d("loc", "onLocationChanged" + Text);
}
#Override
public void onProviderDisabled(String provider) {}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
}
If you are trying it out in a marshmallow device, try enabling location permission for your app manually.
turn on your GPS by using below method. it helps you to show your current location without any ERROR. call it in onCreate
public void displayLocationSettingsRequest(Context context, int requestCode) {
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API).build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(10000);
locationRequest.setFastestInterval(10000 / 2);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(result1 -> {
final Status status = result1.getStatus();
if (status.getStatusCode() == LocationSettingsStatusCodes.RESOLUTION_REQUIRED)
try {
status.startResolutionForResult((Activity) context, requestCode);
} catch (IntentSender.SendIntentException ignored) {
}
});
If you are getting a null error with your provider list, change...
List<String> providers = mLocationManager.getProviders(true);
to...
List<String> providers = locationManager.getAllProviders();
This worked for me, and make sure that you have the following in your AndroidManifest.xml file...
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Have you tried reversing the code? For example, if(location==null) then print that location is null, and else print location is not null. I got that problem once before and that seemed to have fixed it (i don't know why). Try that.
If that doesn't work, perhaps the google maps API is returning the null value, in which case its a problem with the GM-API or with the call method. Any of these could be the problem.