I am working on project where i need to access user's gps location. Due to android 6, I need run time permissions. I tried to do it , first time it asked for gps location on activity starts, but without giving me location. I am still not getting any location coordinates. Hope someone can help ?
public class benzinpriser_akt extends AppCompatActivity implements OnItemClickListener {
public static final int MY_PERMISSION_REQUEST_GPS_LOCATION = 1 ;
LocationManager locationManager;
LocationListener locationListener;
Location currentLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
currentLocation = location;
System.out.println("Current Location "+ currentLocation );
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
};
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSION_REQUEST_GPS_LOCATION);
}
}
// Some other code regarding listview and fetching data from database
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSION_REQUEST_GPS_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
System.out.println("Permission Granted");
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
First of all add theese two lines to your build.gradle:
compile 'com.google.android.gms:play-services-maps:8.4.0'
compile 'com.google.android.gms:play-services-location:8.4.0'
Then in your activity you must implement like that :
public class benzinpriser_akt extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,LocationListener, android.location.LocationListener {
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private int UPDATE_INTERVAL = 20000; // 20 sec
private int FASTEST_INTERVAL = 10000; // 10 sec
private int DISPLACEMENT = 50; // get location per 50 meter change
protected final String TAG = "Location Service";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(yourlayout);
//build google api client
buildGoogleApiClient();
} //oncreate end
protected synchronized void buildGoogleApiClient() {
Log.v(TAG, "google client building");
if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
mGoogleApiClient = new GoogleApiClient.Builder(thisService)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
if (!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
startListenLocation();
} else {
Log.e(TAG, "unable to connect to google play services.");
}
}
public void createLocationRequestWithDialog(final Activity activity){
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
//**************************
builder.setAlwaysShow(true); //this is the key ingredient
//**************************
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(
activity, 1000);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
break;
}
}
});
}
public void checkGpsPermission(Activity activity) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_ACCESS_GPS);
}
else
{
createLocationRequestWithDialog(activity);
}
}
protected void startListenLocation() {
if (ActivityCompat.checkSelfPermission(thisService, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//no permission , create a notification and want permission
NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
Notification n = new Notification.Builder(thisService)
.setContentTitle(" notification")
.setContentText("there is no permission about using gps services, please give location permissions")
.setSmallIcon(R.drawable.logo)
.setAutoCancel(true)
.build();
notificationManager.notify((int)System.currentTimeMillis(), n);
} else {
// permission has been granted, continue as usual
if(mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if (mGoogleApiClient.isConnected() && mLastLocation != null) {
createLocationRequestWithDialog();
startListenLocation();
}
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
//TODO add other override methods , onresume, onproviderenabled etc...
}//class end
Battery drain :
/*
Priority update interval Battery drain per hour (%) Accuracy
HIGH_ACCURACY 5 seconds 7.25% ~10 meters
BALANCED_POWER 20 seconds 0.6% ~40 meters
NO_POWER N/A small ~1 mile
*/
Related
Hi I am creating an android map application that will get the user location, but when users open their map sometimes the location is not accurate and will slowly pinpoint your location.
I have tried this. But It still calls the handler and the TOASTS won't stop.
private LocationManager locationManager;
private Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps_page);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
handler.postDelayed(runnable,3000);
}
#Override
public void onProviderDisabled(String provider) {
handler.removeCallbacks(runnable);
}
});
private Runnable runnable = new Runnable() {
#Override
public void run() {
getCurrentLocation();
Toast.makeText(mapsPage.this, "GETTING LOCATION", Toast.LENGTH_SHORT).show();
handler.postDelayed(this, 3000);
}
};
private void getCurrentLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (location != null) {
longitude = location.getLongitude();
latitude = location.getLatitude();
moveMap();
Integer loc = Math.round(location.getAccuracy());
textings.setText(Integer.toString(loc));
if(loc <= 100)
{
handler.removeCallbacks(runnable);
Toast.makeText(mapsPage.this, "HANDLER STOPPED", Toast.LENGTH_SHORT).show();
}
}
}
//Function to move the map
private void moveMap() {
LatLng latLng = new LatLng(latitude, longitude);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(17));
mMap.addMarker(new MarkerOptions().position(latLng).draggable(false));
}
I have added a handler that will run every 5 seconds checking the users location, and when the getAccuracy data is either equal or lesser than 100 it will stop. How would I do this?
getCurrentLocation may call handler.removeCallbacks(runnable);, but then the runnable will always call handler.postDelayed(this, 3000); right after.
To fix this there has to be some condition for the Runnable to check to see if it should post itself again.
A solution would be to make getCurrentLocation return a boolean indicating if it was successful (enough):
private boolean getCurrentLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return false;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (location != null) {
longitude = location.getLongitude();
latitude = location.getLatitude();
moveMap();
Integer loc = Math.round(location.getAccuracy());
textings.setText(Integer.toString(loc));
if(loc <= 100) {
handler.removeCallbacks(runnable);
Toast.makeText(mapsPage.this, "HANDLER STOPPED", Toast.LENGTH_SHORT).show();
return true;
}
}
return false;
}
Then in your Runnable check if you need to have another run:
#Override
public void run() {
if(!getCurrentLocation()) {
handler.postDelayed(this, 3000);
}
}
However, all of that being said, you should just check the Location in onLocationChanged of your LocationListener and do something if that location is accurate enough. Then you don't need the Runnable at all.
You should definitely accept RobCo's answer as the correct one because it addresses your question directly and also offers an additional key insight (i.e. you don't really need the Runnable at all).
But, I was curious what RobCo's approach would look like, so I created one possible implementation of it.
It turns out that if we avoid the Runnable and rely on Google's callbacks instead, we can get away with using only the newer location provider API (LocatonServices.FusedLocationApi). The older LocationManager API can just be eliminated.
So, in this implementation, I let the Google location service trigger callbacks if/when the location changes (instead of using a periodic poll from the client):
public class MainActivity extends AppCompatActivity implements
ActivityCompat.OnRequestPermissionsResultCallback, GoogleApiClient.OnConnectionFailedListener,
GoogleApiClient.ConnectionCallbacks,
com.google.android.gms.location.LocationListener {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int PERMISSION_REQUEST_CODE = 10001;
public static final int LOCATION_UPDATE_INTERVAL = 5000; // milliseconds
private GoogleApiClient googleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
googleApiClient = new GoogleApiClient.Builder(this, this, this)
.enableAutoManage(this, this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
}
private void requestPermission() {
ActivityCompat.requestPermissions(this,
new String[]{ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_CODE);
}
private void initLocationServices() {
try {
// make initial, synchronous request for current location
Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (location != null) {
moveMap(location);
}
// request future location updates which will come in as callbacks later, when available
LocationRequest locationRequest = new LocationRequest();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(LOCATION_UPDATE_INTERVAL);
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
} catch (SecurityException se) {
Log.w(TAG, "App does not have sufficient permission to request location. " +
"Requesting permission now...");
requestPermission();
}
}
private void moveMap(Location location) {
Log.v(TAG, "moveMap");
// TODO: actual map moving code goes here
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.e(TAG, "Connection failed:" + connectionResult.getErrorMessage());
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CODE && grantResults[0] == PERMISSION_GRANTED && grantResults[1] == PERMISSION_GRANTED) {
Log.v(TAG, "User granted permission. Will request current location.");
initLocationServices();
} else {
Log.w(TAG, "User did not grant permission. Cannot request location. Cannot proceed.");
}
}
#Override
public void onLocationChanged(Location newLocation) {
Log.v(TAG, "onLocationChanged:" + newLocation.toString());
moveMap(newLocation);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if ((ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) == PERMISSION_GRANTED)
&& (ActivityCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) == PERMISSION_GRANTED)) {
initLocationServices();
} else {
Log.w(TAG, "onCreate: requesting sufficient permission from user");
requestPermission();
}
}
#Override
public void onConnectionSuspended(int i) {
Log.v(TAG, "onConnectionSuspended");
}
}
A downside of this particular implementation is that the MainActivity implements several interfaces and that adds some confusion (what are all these methods doing here?, etc)
Dunno. Maybe it's useful. In any event, good luck with your app.
I have an app that displays the latitude, longitude, speed, and distance, in a textview above of the map. The first location is displayed but when I move to another location the textview does not update the information. I also don't know if I am calculating the distance correctly. I am not sure if onLocationChanged is called. My code is below.
---EDIT---
As of now I am no longer working on this project anymore. I believe I was able to fix the issues I had, but I not longer have the code for this project anymore. As this post has been down voted 2 times, I don't believe that it has been very helpful to the community and so I would like to close and delete this post if possible, but there needs to be more votes to close and then delete it. Unless there is any other reason for why this post should stay open?
public class MainActivity extends AppCompatActivity
implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
GoogleMap mGoogleMap;
SupportMapFragment mapFrag;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
private ArrayList<Location> locations = new ArrayList<Location>();
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setTitle("Map");
mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFrag.getMapAsync(this);
}
#Override
public void onPause() {
super.onPause();
//stop location updates when Activity is no longer active
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
#Override
public void onMapReady(GoogleMap googleMap)
{
mGoogleMap=googleMap;
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Location Permission already granted
buildGoogleApiClient();
mGoogleMap.setMyLocationEnabled(true);
} else {
//Request Location Permission
checkLocationPermission();
}
}
else {
buildGoogleApiClient();
mGoogleMap.setMyLocationEnabled(true);
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
#Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
#Override
public void onConnectionSuspended(int i) {}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {}
#Override
public void onLocationChanged(Location location)
{
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
double latitude = location.getLatitude();
double longitude = location.getLongitude();
double speed = location.getSpeed();
double distance = 0;
locations.add(location);
for(int i = 0; i < locations.size()-1; i++) {
distance += locations.get(i).distanceTo(locations.get(i +1));
}
StringBuilder stBuilder = new StringBuilder();
stBuilder.append(" Latitude: ");
stBuilder.append(latitude);
stBuilder.append("\n");
stBuilder.append(" Logitude: ");
stBuilder.append(longitude);
stBuilder.append("\n");
stBuilder.append(" Speed: ");
stBuilder.append(speed + " ");
stBuilder.append("Distance: ");
stBuilder.append(distance);
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText(stBuilder);
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mGoogleMap.addMarker(markerOptions);
//move map camera
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,11));
//optionally, stop location updates if only current location is needed
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
private void checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new AlertDialog.Builder(this)
.setTitle("Location Permission Needed")
.setMessage("This app needs the Location permission, please accept to use location functionality")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION );
}
})
.create()
.show();
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION );
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mGoogleMap.setMyLocationEnabled(true);
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "permission denied", LENGTH_LONG).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
}
In your onLocationChanged() method there is no need to stop the location Service:
Remove this:
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
calling this immediately will stop the location service and so your onLocationChnage() will not be called.
Besides you are adding it in onPause().
#Override
public void onPause() {
super.onPause();
//stop location updates when Activity is no longer active
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
I am creating an app which will get a user name from DB and print the ID and then on button click it will show the current GPS coordinates. I have implemented it but don't know why its not working.
Here is my Manifest file
<uses-permission android:name="android.permission.INTERNET"/>
<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"/>
Below is my MainActivity.java
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final String TAG = "MainActivity";
private TextView tv_lat;
private TextView tv_long;
private Button btn_loc;
private GoogleApiClient googleApiClient;
private Location location;
private LocationManager mLocationManager;
private LocationManager locationManager;
private LocationRequest locationRequest;
private LocationListener locationListener;
private long UPDATE_INTERVAL = 2 * 1000; /* 10 secs */
private long FASTEST_INTERVAL = 2000; /* 2 sec */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_lat = (TextView)findViewById(R.id.tv_lat);
tv_long = (TextView)findViewById(R.id.tv_long);
btn_loc = (Button)findViewById(R.id.btn_loc);
// show location button click event
btn_loc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
googleApiClient = new GoogleApiClient.Builder(MainActivity.this)
.addConnectionCallbacks(MainActivity.this)
.addOnConnectionFailedListener(MainActivity.this)
.addApi(LocationServices.API)
.build();
}
});
mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
checkLocation(); //check whether location service is enable or not in your phone
}
#Override
public void onConnected(Bundle bundle) {
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;
}
startLocationUpdates();
location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if(location == null)
{
startLocationUpdates();
}
if (location != null)
{
}
else {
Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection Suspended");
googleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode());
}
#Override
protected void onStart() {
super.onStart();
if (googleApiClient != null) {
googleApiClient.connect();
}
}
#Override
protected void onStop() {
super.onStop();
if (googleApiClient.isConnected()) {
googleApiClient.disconnect();
}
}
private void startLocationUpdates() {
// Create the location request
locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
// Request location updates
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;
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient,
locationRequest, this);
Log.d("reque", "--->>>>");
}
#Override
public void onLocationChanged(Location location) {
double lattitude = location.getLatitude();
double longitude = location.getLongitude();
String msg = "Updated Location: " +
Double.toString(lattitude) + " , " +
Double.toString(longitude);
tv_lat.setText("Latitude is " + lattitude );
tv_long.setText("Longitude is " + longitude);
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
// You can now create a LatLng Object for use with maps
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
}
private boolean checkLocation() {
if(!isLocationEnabled())
showAlert();
return isLocationEnabled();
}
private boolean isLocationEnabled() {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
private void showAlert() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("Enable Location")
.setMessage("Your Locations Settings is set to 'Off'.\nPlease Enable Location to " +
"use this app")
.setPositiveButton("Location Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
}
});
dialog.create().show();
}
}
else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION );
}
}
}
When i run my app on the my device, below result is shown
When i click on the get location coordinates nothing happens. Also no errors or warnings are shown in logcat.
Update 1
I have moved all the code outside from the button click event
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
And then debugged it, and i got the below result.
I don't know why the coordinates are not showing :(
Any help would be highly appreciated.
When your device is over Android 6.0 Marshmallow, you have to check, that the location permission is allowed in the application settings. You can turn it manually in the settings on or you use the runtime permission library. I've found a very useful library for that: https://github.com/ParkSangGwon/TedPermission
go to mobile settings-->location settings
check whether your mobile GPS service is on or off
and turn on if it is off.
hope this helps.
I am working on accessing the user current location and have gone through this tutorial Current location and this tutorial Current Location. Everything seems fine but latitude and longitude are not coming up in the TextView field.
Here is my code
#Keep
public class edit_information extends Fragment implements AdapterView.OnItemSelectedListener, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener, ResultCallback<LocationSettingsResult> {
protected final static String TAG = "EditInformation";
private static final int MY_PERMISSIONS_ACCESS_LOCATION = 1;
private RadioGroup radioGroup;
private RadioGroup musicRadioGroup;
private RadioGroup decorRadioGroup;
protected static final int REQUEST_CHECK_SETTINGS = 0x1;
//The desired interval for location updates
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
//The fastest rate for active location updates
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2;
//Keys for storing activity state in bundle
protected static final String KEY_REQUESTING_LOCATION_UPDATES = "requesting-location-updates";
protected static final String KEY_LOCATION = "location";
protected static final String KEY_LAST_UPDATED_TIME_STRING = "last-updated-time-string";
/*
Provides entry point to Google play service
*/
protected GoogleApiClient mGoogleApiClient;
//Store parametrers for request to the FusedLocationProviderApi
protected LocationRequest mLocationRequest;
//location setting request
protected LocationSettingsRequest mLocationSettingsRequest;
protected Location mCurrentLocation;
//UI
protected TextView mLatitudeText;
protected TextView mLongitudeText;
protected Boolean mRequestingLocationUpdates;
protected String mLastUpdateTime;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_information, container, false);
Spinner spinner = (Spinner) view.findViewById(R.id.spinner1);
Spinner spinner2 = (Spinner) view.findViewById(R.id.spinner2);
//Creating an array adapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getContext(), R.array.hall_type, simple_spinner_item);
ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource(getContext(), R.array.hall_size, simple_spinner_item);
//Layout to choose the dropdown list
adapter.setDropDownViewResource(simple_spinner_dropdown_item);
adapter1.setDropDownViewResource(simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner2.setAdapter(adapter1);
spinner.setOnItemSelectedListener(this);
spinner2.setOnItemSelectedListener(this);
radioGroup = (RadioGroup) view.findViewById(R.id.food_facility);
musicRadioGroup = (RadioGroup) view.findViewById(R.id.music_facility);
decorRadioGroup = (RadioGroup) view.findViewById(R.id.decor_facility);
mLatitudeText = (TextView) view.findViewById(R.id.myLatitude);
mLongitudeText = (TextView) view.findViewById(R.id.myLongitude);
mRequestingLocationUpdates = false;
mLastUpdateTime = "";
updateValuesFromBundle(savedInstanceState);
//Start the process of building GoogleApiClient, LocationRequest and LocationSettingRequest
buildGoogleApiClient();
createLocationRequest();
buildLocationSettingsRequest();
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
switch (checkedId) {
case R.id.yes:
Toast.makeText(getContext(), "Yes", Toast.LENGTH_SHORT).show();
break;
case R.id.may:
Toast.makeText(getContext(), "May be", Toast.LENGTH_SHORT).show();
break;
case R.id.no:
Toast.makeText(getContext(), "No", Toast.LENGTH_SHORT).show();
break;
}
}
});
musicRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (i) {
case R.id.yesMusic:
Toast.makeText(getContext(), "Yes", Toast.LENGTH_SHORT).show();
break;
case R.id.mayMusic:
Toast.makeText(getContext(), "May be", Toast.LENGTH_SHORT).show();
break;
case R.id.noMusic:
Toast.makeText(getContext(), "No", Toast.LENGTH_SHORT).show();
break;
}
}
});
decorRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (i) {
case R.id.yesDecor:
Toast.makeText(getContext(), "Yes", Toast.LENGTH_SHORT).show();
break;
case R.id.mayDecor:
Toast.makeText(getContext(), "May be", Toast.LENGTH_SHORT).show();
break;
case R.id.noDecor:
Toast.makeText(getContext(), "No", Toast.LENGTH_SHORT).show();
break;
}
}
});
return view;
}
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(adapterView.getContext(), "" + adapterView.getItemAtPosition(i).toString(), Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
private void updateValuesFromBundle(Bundle savedInstanceState) {
if (savedInstanceState != null) {
// Update the value of mRequestingLocationUpdates from the Bundle, and make sure that
// the Start Updates and Stop Updates buttons are correctly enabled or disabled.
if (savedInstanceState.keySet().contains(KEY_REQUESTING_LOCATION_UPDATES)) {
mRequestingLocationUpdates = savedInstanceState.getBoolean(
KEY_REQUESTING_LOCATION_UPDATES);
}
// Update the value of mCurrentLocation from the Bundle and update the UI to show the
// correct latitude and longitude.
if (savedInstanceState.keySet().contains(KEY_LOCATION)) {
// Since KEY_LOCATION was found in the Bundle, we can be sure that mCurrentLocation
// is not null.
mCurrentLocation = savedInstanceState.getParcelable(KEY_LOCATION);
}
// Update the value of mLastUpdateTime from the Bundle and update the UI.
if (savedInstanceState.keySet().contains(KEY_LAST_UPDATED_TIME_STRING)) {
mLastUpdateTime = savedInstanceState.getString(KEY_LAST_UPDATED_TIME_STRING);
}
updateUI();
}
}
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(getContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
protected void buildLocationSettingsRequest() {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
mLocationSettingsRequest = builder.build();
}
protected void checkLocationSettings() {
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(
mGoogleApiClient,
mLocationSettingsRequest
);
result.setResultCallback(this);
}
#Override
public void onResult(LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
Log.i(TAG, "All location settings are satisfied.");
startLocationUpdates();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to" +
"upgrade location settings ");
try {
// Show the dialog by calling startResolutionForResult(), and check the result
// in onActivityResult().
status.startResolutionForResult(getActivity(), REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
Log.i(TAG, "PendingIntent unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog " +
"not created.");
break;
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
case REQUEST_CHECK_SETTINGS:
switch (resultCode) {
case Activity.RESULT_OK:
Log.i(TAG, "User agreed to make required location settings changes.");
startLocationUpdates();
break;
case Activity.RESULT_CANCELED:
Log.i(TAG, "User chose not to make required location settings changes.");
break;
}
break;
}
}
public void startUpdatesButtonHandler(View view) {
checkLocationSettings();
}
public void stopUpdatesButtonHandler(View view) {
// It is a good practice to remove location requests when the activity is in a paused or
// stopped state. Doing so helps battery performance and is especially
// recommended in applications that request frequent location updates.
stopLocationUpdates();
}
protected void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_FINE_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;
}
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient,
mLocationRequest,
this
).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
mRequestingLocationUpdates = true;
}
});
}
private void updateUI() {
updateLocationUI();
}
private void updateLocationUI() {
if (mCurrentLocation != null) {
mLatitudeText.setText(String.valueOf(mCurrentLocation.getLatitude()));
mLongitudeText.setText(String.valueOf(mCurrentLocation.getLongitude()));
}
}
#Override
public void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
public void onResume() {
super.onResume();
// Within {#code onPause()}, we pause location updates, but leave the
// connection to GoogleApiClient intact. Here, we resume receiving
// location updates if the user has requested them.
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
}
}
#Override
public void onPause() {
super.onPause();
// Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
if (mGoogleApiClient.isConnected()) {
stopLocationUpdates();
}
}
protected void stopLocationUpdates() {
// It is a good practice to remove location requests when the activity is in a paused or
// stopped state. Doing so helps battery performance and is especially
// recommended in applications that request frequent location updates.
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient,
this
).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
mRequestingLocationUpdates = false;
}
});
}
#Override
public void onStop() {
super.onStop();
mGoogleApiClient.disconnect();
}
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.i(TAG, "Connected to GoogleApiClient");
// If the initial location was never previously requested, we use
// FusedLocationApi.getLastLocation() to get it. If it was previously requested, we store
// its value in the Bundle and check for it in onCreate(). We
// do not request it again unless the user specifically requests location updates by pressing
// the Start Updates button.
//
// Because we cache the value of the initial location in the Bundle, it means that if the
// user launches the activity,
// moves to a new location, and then changes the device orientation, the original location
// is displayed as the activity is re-created.
if (mCurrentLocation == null) {
if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_FINE_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;
}
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateLocationUI();
}
}
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_ACCESS_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
updateLocationUI();
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection suspended");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateLocationUI();
}
/**
* Stores activity data in the Bundle.
*/
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putBoolean(KEY_REQUESTING_LOCATION_UPDATES, mRequestingLocationUpdates);
savedInstanceState.putParcelable(KEY_LOCATION, mCurrentLocation);
savedInstanceState.putString(KEY_LAST_UPDATED_TIME_STRING, mLastUpdateTime);
super.onSaveInstanceState(savedInstanceState);
}
}
These are permissions which I have added in manifest file
<uses-permission android:name = "android.permission.INTERNET" />
<uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION" />
This is the xml code for latitude and longitude
<TextView
android:id="#+id/myLatitude"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="15sp"
android:textColor="#color/cordinates_color"
/>
<TextView
android:id="#+id/myLongitude"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="15sp"
android:textColor="#color/cordinates_color"
/>
I have added this line in build.gradle app level and sync the project compile 'com.google.android.gms:play-services:10.0.1'
I have been able to connect to GoogleApiClient but coordinates are not coming up. This is a glimpse of logcat
01-29 14:49:31.395 10560-10560/com.example.luke.xyz I/EditInformation: Building GoogleApiClient
01-29 14:49:31.675 10560-10560/com.example.luke.xyz D/ViewRootImpl: #1 mView = android.widget.LinearLayout{2782c80 V.E...... ......I. 0,0-0,0}
01-29 14:49:31.715 10560-10616/com.example.luke.xyz D/mali_winsys: new_window_surface returns 0x3000, [468x91]-format:1
01-29 14:49:31.755 10560-10560/com.example.luke.xyz I/EditInformation: Connected to GoogleApiClient
01-29 14:49:31.805 10560-10616/com.example.luke.xyz V/RenderScript: 0xdc179000 Launching thread(s), CPUs 8
I am testing it on Android Marshmallow. Still unable to figure it out.
Can you help me out ?
Thank you
Ask run time permissions like this:
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.ACCESS_COURSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.ACCESS_COURSE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.ACCESS_COURSE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
// MY_PERMISSIONS_REQUEST_LOCATION is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
Then:
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
more details you can find it out here: https://developer.android.com/training/permissions/requesting.html
Use both the location Permission - ACCESS_COARSE_LOCATION , ACCESS_FINE_LOCATION, same time use Double for LatLng:
#Override
public void onConnected(#Nullable Bundle connectionHint) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission
(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&&
ActivityCompat.checkSelfPermission
(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
requestPermissions(new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
}, 1);
return;
}
}
else{
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation!=null){
mLatitudeText.setText(Double.parseDouble(mLastLocation.getLatitude()));
mLongitudeText.setText(Double.parseDouble(mLastLocation.getLongitude()));
}else {
Toast.makeText(getContext(),"LOcation is null",Toast.LENGTH_SHORT).show();
}
}
}
Handle requested Permission:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults[0] != PackageManager.PERMISSION_GRANTED){
Toast.makeText(getContext(),"PERMISSION_GRANTED",Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(getContext(),"PERMISSION_GRANTED",Toast.LENGTH_SHORT).show();
}
break;
}
}
Go to Settings > Apps > Your_app, and in the Permissions tab, enable Location for instantly getting the output on Marshmallow.
Your coding is fine you just need to add few more permission to your manifest file
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.LOCATION_HARDWARE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Make sure your gps is enabled. Let me know if this fix your problem.
You are currently only asking for the last known location in onConnected. If there is no cached location, this will do nothing.
You should override onLocationChanged to receive the current location once your Google API client is connected. https://developer.android.com/training/location/receive-location-updates.html#callback
The GoogleApiClient.connect method is asynchronous. In the documentation I linked above, the request for location updates is made after the GoogleApiClient connects. You are making this request in onResume, but you are not guaranteed that the GoogleApiClient is connected until onConnected. Make the request in onConnected, as the example in the documentation shows.
I'm building a friend tracking android app. While my friend activated the app and goes away along with his GPS and cellular data on, I need to track him on my device. That's the concept.
I've implemented LocationListener class and now I can get the last updated location either from Gps or Network but is not updated unless I launch Google Maps and return to my application. After googling, I learned that location cache is updated only by GMaps.!
Is there an alternate way to continuously update location?
What if when I need to get continues location after the device locked without making use of Wakelock?
This is my location listener class:
package com.amazinginside;
/** AMAZING LOCATION SUPPORT CLASS, Devoloped By SANGEETH NANDAKUMAR */
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
public class AmazingLocation extends Service implements LocationListener
{
private final Context mContext;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location;
double latitude=0.0;
double longitude=0.0;
//MINIMUM DISTANCE FOR UPDATE (meters)
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 0 Meters
//MINIMUM TIME BETWEEN UPDATES
private static final long MIN_TIME_BW_UPDATES = 1000 * 0; // 0 Seconds
//LOCATION MANAGER
protected LocationManager locationManager;
//CONSTRUCTOR
public AmazingLocation(Context context)
{
this.mContext = context;
getLocation();
}
//LOCATION PROVISION
public Location getLocation()
{
try
{
//GET LOCATION MANAGER
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
//CHECK GPS STATE
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
//CHECK NETWORK STATE
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled)
{
//NO LOCATION PROVIDERS
}
else
{
this.canGetLocation = true;
/** GET LOCATION FROM NETWORK */
//FIRST GET LOCATION FROM NETWORK
if (isNetworkEnabled)
{
//REQUEST LOCATION
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null)
{
//START WITH LAST KNOWN LOCATION
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//EXTRACT LOCATION
if (location != null)
{
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
/** GET LOCATION FROM GPS SENSOR */
//THEN GET LOCATION FROM GPS
if (isGPSEnabled)
{
if (location == null)
{
//REQUEST GPS LOCATION
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null)
{
//EXTRACT LAST KNOWN LOCATION
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//RETURN LOCATION
if (location != null)
{
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return location;
}
//STOP GPS SENSOR
public void stopUsingGPS()
{
if(locationManager != null)
{
locationManager.removeUpdates(AmazingLocation.this);
}
}
//EXTRACT LATTITUDE
public double getLatitude()
{
if(location != null)
{
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
//EXTACT LONGITUDE
public double getLongitude()
{
if(location != null)
{
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
//CAN I GET THE LOCATION.?
public AmazingStatus canGetLocation()
{
AmazingStatus status=new AmazingStatus();
if(this.canGetLocation)
{
status.setStatus(true);
status.setErrorcode(0);
status.setErrormsg("Task completed");
}
else
{
status.setStatus(false);
status.setErrorcode(145);
status.setErrormsg("Please turn on GPS access manually");
}
return status;
}
//SHOW LOCATION SETTINGS
public AmazingStatus showSettingsAlert()
{
final AmazingStatus status=new AmazingStatus();
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
alertDialog.setTitle("REQUIRES LOCATION ACCESS");
alertDialog.setMessage("Please allow GPS access to this app");
//POSSITIVE REPLY
alertDialog.setPositiveButton("Allow", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog,int which)
{
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
status.setStatus(true);
status.setErrorcode(0);
status.setErrormsg("Task completed");
}
});
//NEGATIVE REPLY
alertDialog.setNegativeButton("Deny", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
status.setStatus(false);
status.setErrorcode(408);
status.setErrormsg("User denied permission");
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
return status;
}
//UNUSED OVERRIDE METHORDS...
#Override
public void onLocationChanged(Location location)
{
getLocation();
}
#Override
public void onProviderDisabled(String provider)
{
}
#Override
public void onProviderEnabled(String provider)
{
getLocation();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
getLocation();
}
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
}
This my onCreate() method:
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//CREATE A BUTTON HANDLER
Button start_btn=(Button)findViewById(R.id.start_location_streaming);
//ON BUTTON CLICK EVENT
start_btn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//REPEAT A METHORD AT SPECIFIC INTERVALS
Timer myTimer = new Timer();
myTimer.schedule(new TimerTask()
{
#Override
public void run()
{
TimerMethod();
}
}, 0, 8000);
}
}); }
These are other methods:
private void TimerMethod()
{
//START METHORD
this.runOnUiThread(Timer_Tick);
}
//LOCATION REPORTING METHORD
private Runnable Timer_Tick = new Runnable()
{
public void run()
{
Toast.makeText(MainActivity.this, "Current latitude : "+Double.toString(getLocation().latitude), Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this, "Current longitude : "+Double.toString(getLocation().longitude), Toast.LENGTH_SHORT).show();
}
};
private LatLng getLocation()
{
//CREATE A LOCATION CLASS INSTANCE
AmazingLocation gps = new AmazingLocation(this);
//RETRIVE LOCATION
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
//RETURN LOCATION
LatLng loc=new LatLng(latitude,longitude);
return loc;
}
Now the problem is, the toast just shows previously known the location and not updating unless I opened Google Maps and returned.
Any help will be great for me.
Use Fused location provider in Android set your interval in that:
For an example create your activity like this:
public class LocationActivity extends Activity implements
LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "LocationActivity";
private static final long INTERVAL = 1000 * 10;
private static final long FASTEST_INTERVAL = 1000 * 5;
Button btnFusedLocation;
TextView tvLocation;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mCurrentLocation;
String mLastUpdateTime;
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate ...............................");
//show error dialog if GoolglePlayServices not available
if (!isGooglePlayServicesAvailable()) {
finish();
}
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
setContentView(R.layout.activity_main);
tvLocation = (TextView) findViewById(R.id.tvLocation);
btnFusedLocation = (Button) findViewById(R.id.btnShowLocation);
btnFusedLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
updateUI();
}
});
}
#Override
public void onStart() {
super.onStart();
if (mGoogleApiClient.isConnected()) {
startLocationUpdates();
Log.d(TAG, "Location update resumed .....................");
}
}
#Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop fired ..............");
mGoogleApiClient.disconnect();
Log.d(TAG, "isConnected ...............: " + mGoogleApiClient.isConnected());
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
#Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
startLocationUpdates();
}
protected void startLocationUpdates() {
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.d(TAG, "Location update started ..............: ");
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "Connection failed: " + connectionResult.toString());
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Firing onLocationChanged..............................................");
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateUI();
}
private void updateUI() {
Log.d(TAG, "UI update initiated .............");
if (null != mCurrentLocation) {
String lat = String.valueOf(mCurrentLocation.getLatitude());
String lng = String.valueOf(mCurrentLocation.getLongitude());
tvLocation.setText("At Time: " + mLastUpdateTime + "\n" +
"Latitude: " + lat + "\n" +
"Longitude: " + lng + "\n" +
"Accuracy: " + mCurrentLocation.getAccuracy() + "\n" +
"Provider: " + mCurrentLocation.getProvider());
} else {
Log.d(TAG, "location is null ...............");
}
}
#Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
Log.d(TAG, "Location update stopped .......................");
}
#Override
public void onResume() {
super.onResume();
if (mGoogleApiClient.isConnected()) {
startLocationUpdates();
Log.d(TAG, "Location update resumed .....................");
}
}
}
Google play services required:
To get continiuos location update, you can refer to the above provided answers .
But You can also make use of LocationServices which is faster than other approaches and much easy and efficient to get location.
This approach is quit long but kindly follow all the provided steps
So let me provide a brief working :
Add these two dependencies in your gradle app file
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'com.google.android.gms:play-services-location:17.0.0'
Add these permissions in the manifest file outside applicationtag
Declare variable outside onCreate
private FusedLocationProviderClient fusedLocationClient;
private LocationRequest mLocationRequest;
private LocationCallback mlocationCallback;
private LocationSettingsRequest.Builder builder;
private static final int REQUEST_CHECK_SETTINGS = 102;
Now inside onCreate :
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
fetchLastLocation();
mlocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
// Update UI with location data
// ...
Log.e("CONTINIOUSLOC: ", location.toString());
}
};
};
mLocationRequest = createLocationRequest();
builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
checkLocationSetting(builder);
No define fetchLastLocation method
private void fetchLastLocation() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// Activity#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 Activity#requestPermissions for more details.
// Toast.makeText(MainActivity.this, "Permission not granted, Kindly allow permission", Toast.LENGTH_LONG).show();
showPermissionAlert();
return;
}
}
fusedLocationClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener() {
#Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
// Logic to handle location object
Log.e("LAST LOCATION: ", location.toString()); // You will get your last location here
}
}
});
}
Now define other two method for permission request
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 123: {
// If request is cancelled, the result arrays are empty.
if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
// permission was denied, show alert to explain permission
showPermissionAlert();
}else{
//permission is granted now start a background service
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
fetchLastLocation();
}
}
}
}
}
private void showPermissionAlert(){
if (ActivityCompat.checkSelfPermission(MainHomeActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(MainHomeActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainHomeActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 123);
}
}
now define createLocationRequest method and checkLocationSetting method :
protected LocationRequest createLocationRequest() {
LocationRequest mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(30000);
mLocationRequest.setFastestInterval(10000);
mLocationRequest.setSmallestDisplacement(30);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
return mLocationRequest;
}
private void checkLocationSetting(LocationSettingsRequest.Builder builder) {
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.
// ...
startLocationUpdates();
return;
}
});
task.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull final Exception e) {
if (e instanceof ResolvableApiException) {
// Location settings are not satisfied, but this can be fixed
AlertDialog.Builder builder1 = new AlertDialog.Builder(mContext);
builder1.setTitle("Continious Location Request");
builder1.setMessage("This request is essential to get location update continiously");
builder1.create();
builder1.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ResolvableApiException resolvable = (ResolvableApiException) e;
try {
resolvable.startResolutionForResult(MainHomeActivity.this,
REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e1) {
e1.printStackTrace();
}
}
});
builder1.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(mContext, "Location update permission not granted", Toast.LENGTH_LONG).show();
}
});
builder1.show();
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
if (requestCode == REQUEST_CHECK_SETTINGS) {
if (resultCode == RESULT_OK) {
// All location settings are satisfied. The client can initialize
// location requests here.
startLocationUpdates();
}
else {
checkLocationSetting(builder);
}
}
}
now atlast define startLocationUpdates and stopLocationUpdates method :
public void startLocationUpdates() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// Activity#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 Activity#requestPermissions for more details.
return;
}
}
fusedLocationClient.requestLocationUpdates(mLocationRequest,
mlocationCallback,
null /* Looper */);
}
private void stopLocationUpdates() {
fusedLocationClient.removeLocationUpdates(mlocationCallback);
}
Note : Replace context with your class context and call stopLocationUpdates() inside onDestroy method of your class
Note : For any futher information or doubt you can refer to :
https://developer.android.com/training/location/retrieve-current
https://developer.android.com/training/location/change-location-settings
https://developer.android.com/training/location/receive-location-updates
You will get your location in Logcat.
Hope this will hope you or somebody else !
I believe rather than reinventing the wheel, you can use one of the third party libraries that are easy to implement and in this case, battery efficient. One of the library I found is SmartLocation. You can add the following dependency in your build.gradle (app) to start using the library.
compile 'io.nlopez.smartlocation:library:3.2.9'
After adding the dependency, you should rebuild the project to get the references.
As an example you can try the following code in your Activity.
Button start_btn=(Button)findViewById(R.id.start_location_streaming);
Context context = start_btn.getContext();
Handler handler = new Handler();
start_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SmartLocation.with(context).location().start(locationListener);
}
});
OnLocationUpdatedListener locationListener = new OnLocationUpdatedListener({
#Override
public void onLocationUpdated(Location location) {
double lat = location.getLatitude();
double lng = location.getLongitude();
handler.postDelayed(locationRunnable,8000);
}
});
Runnable locationRunnable = new Runnable({
#Override
public void run() {
SmartLocation.with(context).location().start(locationListener);
}
});
You can stop location tracking in onStop() method
#Override
public void onStop() {
SmartLocation.with(context).location().stop();
super.onStop();
}
SmartLocation library will give you more than what is expected, just try that once.
Note: Make sure your application does have ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION (both) to have accurate results. Don't forget to ask for permissions at runtime for Android 6.0 and above.
You should use android services, rather than the app itself. This way you will achieve to run code continuously in the background and you will receive the location even if the app closes.
https://www.tutorialspoint.com/android/android_services.htm