I have this Activity want to get current location but didn't now how to complete it in right way..also what is REQUEST_CODE_ASK_PERMISSIONS??
do I have to generate one?
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private double longitude;
private double latitude;
private TextView latitudeText, longitudeText;
private FusedLocationProviderClient fusedLocationProviderClient;
private GoogleApiClient googleApiClient;
private LocationManager locationManager;
private LocationListener locationListener;
private LocationRequest locationRequest;
private LocationCallback locationCallback;
final private int REQUEST_CODE_ASK_PERMISSIONS = 123;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
latitudeText = findViewById(R.id.latitudeText);
longitudeText = findViewById(R.id.longitudeText);
getLocation();
}
private void getLocation() {
locationRequest = new LocationRequest()
.setInterval(2000).setFastestInterval(2000).setPriority(1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
SettingsClient client = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
for (Location location : locationResult.getLocations()) {
latitude = location.getLatitude();
longitude = location.getLongitude();
latitudeText.setText(String.valueOf(latitude));
longitudeText.setText(String.valueOf(longitude));
}
}
};
task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
#Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
}
});
}
#Override
protected void onResume() {
super.onResume();
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest
.permission.ACCESS_FINE_LOCATION},REQUEST_CODE_ASK_PERMISSIONS);
} else if(){
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
}
.....................................................................................................................................................
Add dependency in build.gradle (Module:app)
implementation 'com.google.android.gms:play-services-location:16.0.0'
Declare Necessary Permission in Manifest
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
EasyLocationProvider.java
import android.annotation.SuppressLint;
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
import android.content.Context;
import android.content.IntentSender;
import android.os.Bundle;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.location.SettingsClient;
import com.google.android.gms.tasks.OnCanceledListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
public class EasyLocationProvider implements LifecycleObserver {
private EasyLocationCallback callback;
private Context context;
private FusedLocationProviderClient mFusedLocationClient;
private SettingsClient mSettingsClient;
private LocationCallback mLocationCallback;
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private LocationSettingsRequest mLocationSettingsRequest;
private long interval;
private long fastestInterval;
private int priority;
private double Latitude = 0.0, Longitude = 0.0;
private EasyLocationProvider(final Builder builder) {
context = builder.context;
callback = builder.callback;
interval = builder.interval;
fastestInterval = builder.fastestInterval;
priority = builder.priority;
}
#SuppressLint("MissingPermission")
public void requestLocationUpdate() {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}
private void connectGoogleClient() {
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
int resultCode = googleAPI.isGooglePlayServicesAvailable(context);
if (resultCode == ConnectionResult.SUCCESS) {
mGoogleApiClient.connect();
} else {
int REQUEST_GOOGLE_PLAY_SERVICE = 988;
googleAPI.getErrorDialog((AppCompatActivity) context, resultCode, REQUEST_GOOGLE_PLAY_SERVICE);
}
}
#OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
private void onCreateLocationProvider() {
}
#OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private void onLocationResume() {
buildGoogleApiClient();
}
#SuppressLint("MissingPermission")
private synchronized void buildGoogleApiClient() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
mSettingsClient = LocationServices.getSettingsClient(context);
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(#Nullable Bundle bundle) {
callback.onGoogleAPIClient(mGoogleApiClient, "Connected");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(interval);
mLocationRequest.setFastestInterval(fastestInterval);
mLocationRequest.setPriority(priority);
mLocationRequest.setSmallestDisplacement(0);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
mLocationSettingsRequest = builder.build();
mSettingsClient
.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
#Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
showLog("GPS is Enabled Requested Location Update");
requestLocationUpdate();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
int statusCode = ((ApiException) e).getStatusCode();
switch (statusCode) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
int REQUEST_CHECK_SETTINGS = 214;
ResolvableApiException rae = (ResolvableApiException) e;
rae.startResolutionForResult((AppCompatActivity) context, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sie) {
showLog("Unable to Execute Request");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
showLog("Location Settings are Inadequate, and Cannot be fixed here. Fix in Settings");
}
}
}).addOnCanceledListener(new OnCanceledListener() {
#Override
public void onCanceled() {
showLog("onCanceled");
}
});
}
#Override
public void onConnectionSuspended(int i) {
connectGoogleClient();
callback.onGoogleAPIClient(mGoogleApiClient, "Connection Suspended");
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
callback.onGoogleAPIClient(mGoogleApiClient, "" + connectionResult.getErrorCode() + " " + connectionResult.getErrorMessage());
}
})
.addApi(LocationServices.API)
.build();
connectGoogleClient();
mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(final LocationResult locationResult) {
super.onLocationResult(locationResult);
Latitude = locationResult.getLastLocation().getLatitude();
Longitude = locationResult.getLastLocation().getLongitude();
if (Latitude == 0.0 && Longitude == 0.0) {
showLog("New Location Requested");
requestLocationUpdate();
} else {
callback.onLocationUpdated(Latitude, Longitude);
}
}
};
}
#SuppressLint("MissingPermission")
public void removeUpdates() {
try {
callback.onLocationUpdateRemoved();
} catch (Exception e) {
e.printStackTrace();
}
}
private void showLog(String message) {
Log.e("EasyLocationProvider", "" + message);
}
public interface EasyLocationCallback {
void onGoogleAPIClient(GoogleApiClient googleApiClient, String message);
void onLocationUpdated(double latitude, double longitude);
void onLocationUpdateRemoved();
}
public static class Builder {
private Context context;
private EasyLocationCallback callback;
private long interval = 10 * 1000;
private long fastestInterval = 5 * 1000;
private int priority = LocationRequest.PRIORITY_HIGH_ACCURACY;
public Builder(Context context) {
this.context = context;
}
public EasyLocationProvider build() {
if (callback == null) {
Toast.makeText(context, "EasyLocationCallback listener can not be null", Toast.LENGTH_SHORT).show();
}
return new EasyLocationProvider(this);
}
public Builder setListener(EasyLocationCallback callback) {
this.callback = callback;
return this;
}
public Builder setInterval(long interval) {
this.interval = interval;
return this;
}
public Builder setFastestInterval(int fastestInterval) {
this.fastestInterval = fastestInterval;
return this;
}
public Builder setPriority(int priority) {
this.priority = priority;
return this;
}
}
}
Use:
EasyLocationProvider easyLocationProvider; //Declare Global Variable
easyLocationProvider = new EasyLocationProvider.Builder(BottomNavigationActivity.this)
.setInterval(5000)
.setFastestInterval(2000)
//.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setListener(new EasyLocationProvider.EasyLocationCallback() {
#Override
public void onGoogleAPIClient(GoogleApiClient googleApiClient, String message) {
Log.e("EasyLocationProvider","onGoogleAPIClient: "+message);
}
#Override
public void onLocationUpdated(double latitude, double longitude) {
Log.e("EasyLocationProvider","onLocationUpdated:: "+ "Latitude: "+latitude+" Longitude: "+longitude);
}
#Override
public void onLocationUpdateRemoved() {
Log.e("EasyLocationProvider","onLocationUpdateRemoved");
}
}).build();
getLifecycle().addObserver(easyLocationProvider);
Remove Location Update Callback
#Override
protected void onDestroy() {
easyLocationProvider.removeUpdates();
getLifecycle().removeObserver(easyLocationProvider);
super.onDestroy();
}
NOTE: Grant Permissions for Marshmallow and Above Version Devices
You should override onRequestPermissionsResult
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLocation();
}
}
}
}
So it's up to you to define REQUEST_CODE_ASK_PERMISSIONS and it's role is to handle the callback, especially if you ask for more than on permission.
And I think your getLocation() uses a deprecated API. Have a look here on how to get the location.
Ketan Ramani's answer helped me and all credits to him. I made a little adjustment to be able to set the number of updates especially in the event one is only required.
public class LocationProvider implements LifecycleObserver {
private EasyLocationCallback callback;
private Context context;
private FusedLocationProviderClient mFusedLocationClient;
private SettingsClient mSettingsClient;
private LocationCallback mLocationCallback;
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private LocationSettingsRequest mLocationSettingsRequest;
private long interval;
private long fastestInterval;
private int priority;
private int numberOfUpdates;
private double Latitude = 0.0, Longitude = 0.0;
private LocationProvider(final Builder builder) {
context = builder.context;
callback = builder.callback;
interval = builder.interval;
fastestInterval = builder.fastestInterval;
priority = builder.priority;
numberOfUpdates = builder.numberOfUpdates;
}
#SuppressLint("MissingPermission")
public void requestLocationUpdate() {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}
private void connectGoogleClient() {
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
int resultCode = googleAPI.isGooglePlayServicesAvailable(context);
if (resultCode == ConnectionResult.SUCCESS) {
mGoogleApiClient.connect();
} else {
int REQUEST_GOOGLE_PLAY_SERVICE = 988;
googleAPI.getErrorDialog((AppCompatActivity) context, resultCode, REQUEST_GOOGLE_PLAY_SERVICE);
}
}
#OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
private void onCreateLocationProvider() {
}
#OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private void onLocationResume() {
buildGoogleApiClient();
}
#SuppressLint("MissingPermission")
private synchronized void buildGoogleApiClient() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
mSettingsClient = LocationServices.getSettingsClient(context);
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(#Nullable Bundle bundle) {
callback.onGoogleAPIClient(mGoogleApiClient, "Connected");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(interval);
mLocationRequest.setFastestInterval(fastestInterval);
mLocationRequest.setPriority(priority);
mLocationRequest.setSmallestDisplacement(0);
if (numberOfUpdates > 0) mLocationRequest.setNumUpdates(numberOfUpdates);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
mLocationSettingsRequest = builder.build();
mSettingsClient
.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(locationSettingsResponse -> {
showLog("GPS is Enabled Requested Location Update");
requestLocationUpdate();
}).addOnFailureListener(e -> {
int statusCode = ((ApiException) e).getStatusCode();
switch (statusCode) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
int REQUEST_CHECK_SETTINGS = 214;
ResolvableApiException rae = (ResolvableApiException) e;
rae.startResolutionForResult((AppCompatActivity) context, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sie) {
showLog("Unable to Execute Request");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
showLog("Location Settings are Inadequate, and Cannot be fixed here. Fix in Settings");
}
}).addOnCanceledListener(new OnCanceledListener() {
#Override
public void onCanceled() {
showLog("onCanceled");
}
});
}
#Override
public void onConnectionSuspended(int i) {
connectGoogleClient();
callback.onGoogleAPIClient(mGoogleApiClient, "Connection Suspended");
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
callback.onGoogleAPIClient(mGoogleApiClient, "" + connectionResult.getErrorCode() + " " + connectionResult.getErrorMessage());
}
})
.addApi(LocationServices.API)
.build();
connectGoogleClient();
mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(final LocationResult locationResult) {
super.onLocationResult(locationResult);
Latitude = locationResult.getLastLocation().getLatitude();
Longitude = locationResult.getLastLocation().getLongitude();
if (Latitude == 0.0 && Longitude == 0.0) {
showLog("New Location Requested");
requestLocationUpdate();
} else {
callback.onLocationUpdated(Latitude, Longitude);
}
}
};
}
public LatLng getLastLocation() {
if ( ContextCompat.checkSelfPermission( context, android.Manifest.permission.ACCESS_COARSE_LOCATION ) == PackageManager.PERMISSION_GRANTED ) {
Location location = mFusedLocationClient.getLastLocation().getResult();
return new LatLng(location.getLatitude(), location.getLongitude());
}
return null;
}
#SuppressLint("MissingPermission")
public void removeUpdates() {
try {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
callback.onLocationUpdateRemoved();
} catch (Exception e) {
e.printStackTrace();
}
}
private void showLog(String message) {
Log.e("LocationProvider", "" + message);
}
public interface EasyLocationCallback {
void onGoogleAPIClient(GoogleApiClient googleApiClient, String message);
void onLocationUpdated(double latitude, double longitude);
void onLocationUpdateRemoved();
}
public static class Builder {
private Context context;
private EasyLocationCallback callback;
private long interval = 10 * 1000;
private long fastestInterval = 5 * 1000;
private int priority = LocationRequest.PRIORITY_HIGH_ACCURACY;
private int numberOfUpdates = 0;
public Builder(Context context) {
this.context = context;
}
public LocationProvider build() {
if (callback == null) {
Toast.makeText(context, "EasyLocationCallback listener can not be null", Toast.LENGTH_SHORT).show();
}
return new LocationProvider(this);
}
public Builder setListener(EasyLocationCallback callback) {
this.callback = callback;
return this;
}
public Builder setInterval(long interval) {
this.interval = interval;
return this;
}
public Builder setFastestInterval(int fastestInterval) {
this.fastestInterval = fastestInterval;
return this;
}
public Builder setPriority(int priority) {
this.priority = priority;
return this;
}
public Builder setNumberOfUpdates(int numberOfUpdates) {
this.numberOfUpdates = numberOfUpdates;
return this;
}
}
}
Setting the locationProvider
locationProvider = new LocationProvider.Builder(MainActivity.this)
.setInterval(10000)
.setFastestInterval(5000)
.setNumberOfUpdates(1) // If you want infinite updates, remove this line entirely
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
.setListener(new LocationProvider.EasyLocationCallback() {
#Override
public void onGoogleAPIClient(GoogleApiClient googleApiClient, String message) {
Log.e("LocationProvider", "onGoogleAPIClient: " + message);
}
#Override
public void onLocationUpdated(double updateLatitude, double updateLongitude) {
// You could also add some intelligence to remove the location listener once counter == numberOfUpdates
}
#Override
public void onLocationUpdateRemoved() {
Log.e("LocationProvider", "onLocationUpdateRemoved");
}
}).build();
getLifecycle().addObserver(locationProvider);
Just in case if someone is finding the solution for this. You can now use FusedLocationClient.getCurrentLocation in play-services-location library version 17.1.0
Please try the below way to get the location using the FusedLocationProviderClient
public class LocationTrackerClient{
public static String TAG = LocationTrackerClient.class.getName();
private Location mLastLocation;
LocationRequest mLocationRequest;
private FusedLocationProviderClient mFusedLocationClient;
static Context mcontext;
private static int UPDATE_INTERVAL = 1000;
private static int FATEST_INTERVAL = 1000;
private static int DISPLACEMENT = 5;
private static LocationTrackerClient instance;
private boolean isConnected = false;
public static synchronized LocationTrackerClient getInstance(Context ctx) {
mcontext = ctx;
if (instance == null) {
instance = new LocationTrackerClient();
}
return instance;
}
public void getLocationclient() {
try {
mFusedLocationClient = null;
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(mcontext);
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
} catch (Exception e) {
ExceptionHandler.printStackTrace(e);
}
}
public void connectToLocation() {
stopLocationUpdates();
getLocationclient();
displayLocation();
}
public void stopLocationUpdates() {
removeFusedLocationUpdate();
}
public void removeFusedLocationUpdate() {
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(mcontext,Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mcontext, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
}else{
return;
}
}
try {
if (mFusedLocationClient != null) {
mFusedLocationClient
.removeLocationUpdates(mLocationCallback)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Logger.d(TAG, "Location updates stopped at removeFusedLocationUpdate! == ");
// Toast.makeText(getApplicationContext(), "Location updates stopped!", Toast.LENGTH_SHORT).show();
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void displayLocation() {
try {
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
} catch (SecurityException e) {
ExceptionHandler.printStackTrace(e);
} catch (Exception e) {
ExceptionHandler.printStackTrace(e);
}
}
private LocationCallback mLocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
Logger.e(TAG, "locationResult ==== " + locationResult);
if (locationResult != null) {
mLastLocation = locationResult.getLastLocation();
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
updateLattitudeLongitude(latitude, longitude);
}
}
}
};
public void updateLattitudeLongitude(double latitude, double longitude) {
Logger.i(TAG, "updated Lat == " + latitude + " updated long == " + longitude);
SharedPreferenceManager sharedPreferenceManager = SharedPreferenceManager.getInstance();
sharedPreferenceManager.updateUserDeviceLatLong(latitude, longitude);
}
}
Related
When I tested it the first couple of times it was showing perfectly well, then I added some code and it just stopped. It still shows the Mapbox logo on the left bottom screen but it's not loading the map. Here's the code on the MapActivity:
public class MapActivity extends AppCompatActivity implements OnMapReadyCallback, LocationEngineListener, PermissionsListener {
private MapView mapView;
private Button startButton;
private MapboxMap map;
private PermissionsManager permissionsManager;
private LocationEngine locationEngine;
private Location originLocation;
private LocationLayerPlugin locationLayerPlugin;
private Locash customerLocash;
private Point destinationPosition;
private Point originPosition;
private Marker destinationMarker;
private NavigationMapRoute navigationMapRoute;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapbox.getInstance(this, getString(R.string.access_token));
setContentView(R.layout.activity_map);
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
startButton = findViewById(R.id.startButton);
Intent activityIntent = getIntent();
String locationJson = activityIntent.getStringExtra("location");
Gson gson = new Gson();
customerLocash = gson.fromJson(locationJson,Locash.class);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Launch Navigation
NavigationLauncherOptions options = NavigationLauncherOptions.builder()
.origin(originPosition)
.destination(destinationPosition)
.shouldSimulateRoute(true)
.build();
NavigationLauncher.startNavigation(MapActivity.this, options);
}
});
}
#Override
public void onMapReady(MapboxMap mapboxMap) {
map = mapboxMap;
enableLocation();
LatLng point = new LatLng(customerLocash.getLongitude(),customerLocash.getLatitude());
destinationMarker = map.addMarker(new MarkerOptions().position(point));
destinationPosition = Point.fromLngLat(point.getLongitude(),point.getLatitude());
originPosition = Point.fromLngLat(originLocation.getLongitude(), originLocation.getLatitude());
getRoute(originPosition, destinationPosition);
startButton.setEnabled(true);
}
private void enableLocation() {
if (PermissionsManager.areLocationPermissionsGranted(this)){
initializeLocationEngine();
initializeLocationLayer();
} else {
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
}
}
#SuppressWarnings("MissingPermission")
private void initializeLocationEngine() {
locationEngine = new LocationEngineProvider(this)
.obtainBestLocationEngineAvailable();
locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
locationEngine.activate();
Location lastLocation = locationEngine.getLastLocation();
if (lastLocation != null){
originLocation = lastLocation;
setCameraPosition(lastLocation);
} else {
locationEngine.addLocationEngineListener(this);
}
}
#SuppressWarnings("MissingPermission")
private void initializeLocationLayer() {
locationLayerPlugin = new LocationLayerPlugin(mapView, map, locationEngine);
locationLayerPlugin.setLocationLayerEnabled(true);
locationLayerPlugin.setCameraMode(CameraMode.TRACKING);
locationLayerPlugin.setRenderMode(RenderMode.NORMAL);
}
private void setCameraPosition(Location location){
map.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(),
location.getLongitude()),13.0));
}
private void getRoute(Point origin, Point destination){
NavigationRoute.builder()
.accessToken(Mapbox.getAccessToken())
.origin(origin)
.destination(destination)
.build()
.getRoute(new Callback<DirectionsResponse>() {
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
if (response.body() == null){
Toast.makeText(MapActivity.this, "No Routes Found", Toast.LENGTH_SHORT).show();
return;
} else if (response.body().routes().size() == 0){
Toast.makeText(MapActivity.this, "No Routes Found", Toast.LENGTH_SHORT).show();
return;
}
DirectionsRoute currentRoute = response.body().routes().get(0);
navigationMapRoute = new NavigationMapRoute(null, mapView,map);
navigationMapRoute.addRoute(currentRoute);
}
#Override
public void onFailure(Call<DirectionsResponse> call, Throwable t) {
Toast.makeText(MapActivity.this, "Error:" + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
#SuppressWarnings("MissingPermission")
#Override
public void onConnected() {
locationEngine.requestLocationUpdates();
}
#Override
public void onLocationChanged(Location location) {
if (location != null){
originLocation = location;
setCameraPosition(location);
}
}
#Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
Toast.makeText(this, "Location Required", Toast.LENGTH_SHORT).show();
}
#Override
public void onPermissionResult(boolean granted) {
if (granted){
enableLocation();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
#Override
#SuppressWarnings("MissingPermission")
protected void onStart() {
super.onStart();
if (locationEngine != null){
locationEngine.requestLocationUpdates();
}
if (locationLayerPlugin != null){
locationLayerPlugin.onStart();
}
mapView.onStart();
}
#Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
#Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
#Override
protected void onStop() {
super.onStop();
if (locationEngine != null){
locationEngine.removeLocationUpdates();
}
if (locationLayerPlugin != null){
locationLayerPlugin.onStop();
}
mapView.onStop();
}
#Override
public void onSaveInstanceState(#NonNull Bundle outState, #NonNull PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
mapView.onSaveInstanceState(outState);
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (locationEngine != null){
locationEngine.deactivate();
}
mapView.onDestroy();
}
}
Oh and the Locash object is a class I use to store user location on firebase and the likes.
Looks like a problem I had. Not sure if this is the same, but in my case setting the textureView option to true solved it.
This is how I did it in code:
val resourceOptions = ResourceOptions.Builder()
.accessToken(context.getString(R.string.mapbox_access_token))
.build()
mapView = MapView(context, MapInitOptions(context, resourceOptions).apply { textureView = true })
I am not sure how to do it in XML.
I know there are a lot of examples on the internet about this subject but my problem isn't the code, is the part where I get the location. The FusedLocationProviderClient.getLastLocation() always returns null when I don't open Google Maps before. To get my current location I have to open google maps to get my current location and after that my app can know the location. My question is: is there a way to track my current location without opening google maps before? Here is what I tried:
package com.example.gps;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;
import java.io.IOException;
import java.util.List;
public class MainActivity extends AppCompatActivity {
public static final int DEFAULT_UPDATE_INTERVAL = 30;
public static final int FAST_UPDATE_INTERVAL = 5;
public static final int PERMISSIONS_FINE_LOCATION = 99;
TextView tv_lat, tv_lon, tv_altitude,
tv_accuracy, tv_speed, tv_sensor, tv_updates, tv_address;
Switch sw_locationupdates, sw_gps;
// Google API for location services.
FusedLocationProviderClient fusedLocationProviderClient;
// Location request config file for all settings related to FusedLocationProviderClient
LocationRequest locationRequest;
LocationCallback locationCallBack;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_lat = findViewById(R.id.tv_lat);
tv_lon = findViewById(R.id.tv_lon);
tv_altitude = findViewById(R.id.tv_altitude);
tv_accuracy = findViewById(R.id.tv_accuracy);
tv_speed = findViewById(R.id.tv_speed);
tv_sensor = findViewById(R.id.tv_sensor);
tv_updates = findViewById(R.id.tv_updates);
tv_address = findViewById(R.id.tv_address);
sw_gps = findViewById(R.id.sw_gps);
sw_locationupdates = findViewById(R.id.sw_locationsupdates);
locationRequest = new LocationRequest();
locationRequest.setInterval(1000 * DEFAULT_UPDATE_INTERVAL);
locationRequest.setFastestInterval(1000 * FAST_UPDATE_INTERVAL);
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
locationCallBack = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
updateUIValues(locationResult.getLastLocation());
}
};
sw_locationupdates.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (sw_locationupdates.isChecked()) {
startLocationUpdates();
} else {
stopLocationUpdates();
}
}
});
sw_gps.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (sw_gps.isChecked()) {
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
String text = "Using GPS sensors";
tv_sensor.setText(text);
} else {
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
String text = "Using Towers + WIFi";
tv_sensor.setText(text);
}
}
});
updateGPS();
}// end onCreate
private void stopLocationUpdates() {
String text = "Location is NOT being tracked";
tv_updates.setText(text);
Toast.makeText(this, "done", Toast.LENGTH_SHORT).show();
fusedLocationProviderClient.removeLocationUpdates(locationCallBack);
}
private void startLocationUpdates() {
String text = "Location is being tracked";
tv_updates.setText(text);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "a", Toast.LENGTH_SHORT).show();
// 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.
// requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
// Manifest.permission.ACCESS_COARSE_LOCATION},
PERMISSIONS_FINE_LOCATION);
// return;
}
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallBack, null);
updateGPS();
Toast.makeText(this, "tracking again", Toast.LENGTH_SHORT).show();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSIONS_FINE_LOCATION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
updateGPS();
} else {
Toast.makeText(this, "This app requires permission to be granted in order to work properly", Toast.LENGTH_SHORT).show();
finish();
}
}
}
private void updateGPS() {
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(MainActivity.this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
fusedLocationProviderClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
updateUIValues(location);
}
});
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSIONS_FINE_LOCATION);
}
}
}
private void updateUIValues(Location location) {
if (location != null) {
tv_lat.setText(String.valueOf(location.getLatitude()));
tv_lon.setText(String.valueOf(location.getLongitude()));
tv_accuracy.setText(String.valueOf(location.getAccuracy()));
if (location.hasAltitude()) {
tv_altitude.setText(String.valueOf(location.getAltitude()));
} else {
String text = "Not available- altitude";
tv_altitude.setText(text);
}
if (location.hasSpeed()) {
tv_speed.setText(String.valueOf(location.getSpeed()));
} else {
String text = "Not available- speed";
tv_speed.setText(text);
}
Geocoder geocoder = new Geocoder(MainActivity.this);
try {
List<Address> addressList = geocoder.getFromLocation(location.getLatitude(),
location.getLongitude(), 1);
tv_address.setText(addressList.get(0).getAddressLine(0));
} catch (IOException e) {
String text = "geocode didnt work";
tv_address.setText(text);
e.printStackTrace();
}
} else {
Toast.makeText(this, "the gps doesnt work", Toast.LENGTH_SHORT).show();
}
}
}
This code will retrieve my current location and update the name of the location but it will only work if I open google maps, close google maps and launch my app, it will work. Maybe this is the only way to make it work? But I wonder how other apps can track my location without opening google maps before.
yes, you can do it using its fused location provider also...without a map...
These code work without map I Hope You have apply runtime permission code
also apply for permission in the android manifest check it...
follow these URL - https://javapapers.com/android/android-location-fused-provider/
public class HomeFragment extends Fragment implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
GoogleApiClient googleApiClient;
LocationRequest locationRequest;
Location mCurrentLocation;
private static final long INTERVAL = 1000;
private static final long FASTEST_INTERVAL = 1000;
private int Play_SERVICES_RESOLUTION_REQUEST = 11;
FragmentHomeBinding binding;
AddressListDialogBinding dialogBinding;
AddressInterface anInterface;
FirebaseFirestore firebaseFirestore;
BottomSheetDialog dialog;
public HomeFragment() {
}
protected void createLocationRequest() {
locationRequest = new LocationRequest();
locationRequest.setInterval(INTERVAL);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
LayoutInflater layoutInflater = getLayoutInflater();
binding = FragmentHomeBinding.inflate(layoutInflater);
View view = binding.getRoot();
setHasOptionsMenu(true);
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
init();
}
private void init() {
if (!isGooglePlayServicesAvailable()) {
}
createLocationRequest();
anInterface = this;
// setAddress();
googleApiClient = new GoogleApiClient.Builder(getActivity())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
#Override
public void onStart() {
super.onStart();
googleApiClient.connect();
}
#Override
public void onStop() {
super.onStop();
googleApiClient.disconnect();
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, getActivity(), 0).show();
return false;
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
startLocationUpdates();
}
protected void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
googleApiClient, locationRequest, this);
Log.d("LocationUpdate", "Location update started ..............: ");
}
#Override
public void onConnectionSuspended(#NonNull int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
updateUI();
}
private void updateUI() {
if (mCurrentLocation != null) {
Log.e("getLocation", "updateUI: " + mCurrentLocation.getLatitude() + ":" + mCurrentLocation.getLongitude());
Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
try {
List<Address> addresses = geocoder.getFromLocation(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude(), 1);
String address = addresses.get(0).getAddressLine(0);
binding.tvCurrentLocation.setText(address);
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void onPause() {
super.onPause();
stopLocationUpdate();
}
protected void stopLocationUpdate() {
try {
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
} catch (Exception e) {
Log.e("error", "stopLocationUpdate: " + e.toString());
}
}
#Override
public void onResume() {
super.onResume();
if (googleApiClient.isConnected()) {
startLocationUpdates();
}
}
}
I want to place a marker on a specific location. At first, I thought this would be simple to do but somehow I'm getting confused and I haven't found something that actually gives me what I need. I've tried to base my activity on whats it's done in this video https://www.youtube.com/watch?v=HD48FBwY9U0
My activity starts by receiving an object information on a getIntent() which I then extract the information. In that object (in this case, a car), there is a lot of properties and 2 of them, are the latitude and longitude. The previous are in Double values.
The problem that I am facing is that I don't know how to input the information that I got from the object into the program. I'm placing the code below. Any suggestions?
public class Geolocalizcao extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleMap mMap;
private GoogleApiClient client;
private LocationRequest locationRequest;
private Location lastLocation;
private Marker currentLocationMarker;
public static final int REQUEST_LOCATION_CODE = 99;
public static int REQUEST_ERROR_CODE;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_geolocalizcao);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
Intent i = getIntent();
CarDataset cardata = (CarDataset) i.getExtras().getParcelable("select");
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
buildGoogleApiClient();
return;
}
}
protected synchronized void buildGoogleApiClient()
{
client = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
client.connect();
}
#Override
public void onLocationChanged(Location location) {
LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Here!");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker());
currentLocationMarker = mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomBy(3));
if(client != null)
{
LocationServices.FusedLocationApi.removeLocationUpdates(client, this);
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
locationRequest = new LocationRequest();
locationRequest.setInterval(1000);
locationRequest.setFastestInterval(1000);
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}
public boolean checkLocationPermission()
{
if(ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION))
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_LOCATION_CODE);
}
else
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_LOCATION_CODE);
}
return false;
}
else
return false;
}
#Override
// When connection is lost...
public void onConnectionSuspended(int i)
{
Toast.makeText(this, "Lost connection. Trying to reconnect...", Toast.LENGTH_SHORT);
client.connect();
}
#Override
// Called when the API client doesnt sucessufly connect
public void onConnectionFailed(#NonNull ConnectionResult connectionResult)
{
if (!connectionResult.hasResolution())
{
GoogleApiAvailability.getInstance().getErrorDialog(this, connectionResult.getErrorCode(), 0).show();
return;
}
try
{
connectionResult.startResolutionForResult(this, REQUEST_ERROR_CODE );
} catch (IntentSender.SendIntentException e)
{
Log.e("LOG", "Exception:", e);
}
}
Here's the class CarDataset that I use:
public class CarDataset implements Parcelable
{
int vehicleID;
String model;
String licencePlate;
String brand;
Double latitude;
Double longitude;
public CarDataset(Integer nVehicleID, String nModel, String nLicencePlate, String nBrand, Double nLatitude, Double nLongitude)
{
this.vehicleID = nVehicleID;
this.model = nModel;
this.licencePlate = nLicencePlate;
this.brand = nBrand;
this.latitude = nLatitude;
this.longitude = nLongitude;
}
public int getVehicleID() {
return vehicleID;
}
public void setVehicleID(int vehicleID) {
this.vehicleID = vehicleID;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getLicencePlate() {
return licencePlate;
}
public void setLicencePlate(String licencePlate) {
this.licencePlate = licencePlate;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Double getLatitude() {
return latitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
#Override
public int describeContents()
{
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(vehicleID);
dest.writeString(model);
dest.writeString(licencePlate);
dest.writeString(brand);
dest.writeDouble(latitude);
dest.writeDouble(longitude);
}
public static final Parcelable.Creator<CarDataset> CREATOR
= new Parcelable.Creator<CarDataset>()
{
public CarDataset createFromParcel(Parcel input)
{
return new CarDataset(input);
}
public CarDataset[] newArray(int size)
{
return new CarDataset[size];
}
};
private CarDataset(Parcel input)
{
vehicleID = input.readInt();
model = input.readString();
licencePlate = input.readString();
brand = input.readString();
latitude = input.readDouble();
longitude = input.readDouble();
}
}
All you need to do is create a LatLng object with the latitude and longitude from the CarDataset object that you get from the Intent.
Marker carMarker;
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (cardata != null) {
LatLng latLngCar = new LatLng(cardata.latitude, cardata.longitude);
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLngCar);
markerOptions.title("Car");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker());
carMarker = mMap.addMarker(markerOptions);
}
//.............
}
You will also need to modify onCreate() so that cardata is an instance variable:
CarDataset cardata;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_geolocalizcao);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
Intent i = getIntent();
//use instance variable:
cardata = (CarDataset) i.getExtras().getParcelable("select");
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomBy(3));
mMap.addMarker(new MarkerOptions()
.title("Here!")
.icon(BitmapDescriptorFactory.defaultMarker())
.position(latlng_object));
I have an app that can capture fotos and send to the server.
I need to get location(lat,lon,alt) everytime i take a foto.
After a lot of research i understood that taking this data requires some time, the gps triangulation must run asyncronous, so i tried to figure out the best way to do this.
After some time, i had the idea, to start a service, everytime i run the aplication, this service will grab the last location everytime, and when i send a foto i will get the last location values.
So i did something like this(Service):
package com.example.afcosta.inesctec.pt.android.services;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private static final String TAG = "BOOMBOOMTESTGPS";
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 1000;
private static final float LOCATION_DISTANCE = 10f;
private class LocationListener implements android.location.LocationListener
{
Location mLastLocation;
public LocationListener(String provider)
{
Log.e(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location)
{
Log.e("asd", "onLocationChanged: " + location);
mLastLocation.set(location);
}
#Override
public void onProviderDisabled(String provider)
{
Log.e(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider)
{
Log.e(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
Log.e(TAG, "onStatusChanged: " + provider);
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onCreate()
{
Log.e(TAG, "onCreate");
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[1]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "network provider does not exist, " + ex.getMessage());
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "gps provider does not exist " + ex.getMessage());
}
}
#Override
public void onDestroy()
{
Log.e(TAG, "onDestroy");
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
Log.i(TAG, "fail to remove location listners, ignore", ex);
}
}
}
}
private void initializeLocationManager() {
Log.e(TAG, "initializeLocationManager");
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(this.LOCATION_SERVICE);
}
}
}
and then i call the service when my app runs(at the moment i am testing this just with login(onCreate))
startService(new Intent(this, MyService.class));
i get this logTrace(with red):
`05-22 20:35:39.652 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: LocationListener gps
05-22 20:35:39.652 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: LocationListener network
05-22 20:35:39.652 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: onCreate
05-22 20:35:39.652 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: initializeLocationManager
05-22 20:35:39.657 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: onStartCommand
CHANGES
that was what i tried to do before:
`
public class GoogleLocation implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private double lat;
private double lon;
private double alt;
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
public double getLon() {
return lon;
}
public void setLon(double lon) {
this.lon = lon;
}
public double getAlt() {
return alt;
}
public void setAlt(double alt) {
this.alt = alt;
}
boolean gps_enabled = false;
boolean network_enabled = false;
private Context context;
LocationManager lm;
LocationListener listener;
final int MY_PERMISSION_ACCESS_COURSE_LOCATION = 1;
public GoogleLocation(Context context) {
this.context = context;
}
public void getPosition() {
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
listener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
setLat(location.getLatitude());
setLon(location.getLongitude());
setAlt(location.getAltitude());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
location();
}
#Override
public void onProviderDisabled(String provider) {
}
};
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions((Activity) context, new String[] { android.Manifest.permission.ACCESS_COARSE_LOCATION },
MY_PERMISSION_ACCESS_COURSE_LOCATION);
}
}
lm.requestLocationUpdates("gps", 5000, 0, listener);
}
public void location(){
GoogleApiClient googleApiClient = null;
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(30 * 1000);
locationRequest.setFastestInterval(1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
//**************************
builder.setAlwaysShow(true); //this is the key ingredient
//**************************
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(googleApiClient, 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) context, 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;
}
}
});
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
}
`
i don't get any location, i don't know why, the onlocationchanged never runs, if the location doesn't change i want to get the last.
How can i accomplish that?
Thanks
Best regards
`
You don't need service class as you can get location in activity in which you are taking photos.
So first of all add permissions in manifest file
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
and dependencies in gradle
compile 'com.google.android.gms:play-services:10.2.6'
Then in activity in which you are taking photos
Implement listeners
public class Activity extends AppCompatActivity implements ConnectionCallbacks, OnConnectionFailedListener{
protected Location mLastLocation;
private double Latitude;
private double Longitude;
in onCreate method ask user for location permission and call
buildGoogleApiClient();
and then define buildGoogleApiClient() method
/**
* Builds a GoogleApiClient. Uses the addApi() method to request the LocationServices API.
*/
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
after that implements listener interfaces methods
#Override
public void onConnected(Bundle connectionHint) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
Latitude = mLastLocation.getLatitude();
Longitude = mLastLocation.getLongitude();
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Refer to the javadoc for ConnectionResult to see what error codes might be returned in
// onConnectionFailed.
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
#Override
public void onConnectionSuspended(int cause) {
// The connection to Google Play services was lost for some reason. We call connect() to
// attempt to re-establish the connection.
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
then at the end
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
let me know if you don't understand anything
I have followed this guide https://developer.android.com/training/location/retrieve-current.html#permissions, and I'm not able to receive the last location.
I need the location just one time.
Here my code:
public class MainActivity extends ActionBarActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
public static final String TAG = MainActivity.class.getSimpleName();
public static final String DAILY_FORECAST = "DAILY_FORECAST";
public static final String HOURLY_FORECAST = "HOURLY_FORECAST";
private Forecast mForecast;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
private double mLatitude;
private double mLongitude;
#Bind(R.id.timeLabel) TextView mTimeLabel;
#Bind(R.id.temperatureLabel) TextView mTemperatureLabel;
#Bind(R.id.humidityValue) TextView mHumidityValue;
#Bind(R.id.precipValue) TextView mPrecipValue;
#Bind(R.id.summaryLabel) TextView mSummaryLabel;
#Bind(R.id.iconImageView) ImageView mIconImageView;
#Bind(R.id.refreshImageView) ImageView mRefreshImageView;
#Bind(R.id.progressBar) ProgressBar mProgressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mProgressBar.setVisibility(View.INVISIBLE);
buildGoogleApiClient();
//mLatitude = 37.8267;
//mLongitude = -122.423;
mRefreshImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getForecast(mLatitude, mLongitude);
}
});
getForecast(mLatitude, mLongitude);
}
private void getForecast(double latitude, double longitude) {
String apiKey = "48fb6c0ca3567d0b17bf99b400ef5606";
String forecastUrl = "https://api.forecast.io/forecast/" + apiKey +
"/" + latitude + "," + longitude;
if (isNetworkAvailable()) {
toggleRefresh();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(forecastUrl)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
toggleRefresh();
}
});
alertUserAboutError();
}
#Override
public void onResponse(Response response) throws IOException {
runOnUiThread(new Runnable() {
#Override
public void run() {
toggleRefresh();
}
});
try {
String jsonData = response.body().string();
Log.v(TAG, jsonData);
if (response.isSuccessful()) {
mForecast = parseForecastDetails(jsonData);
runOnUiThread(new Runnable() {
#Override
public void run() {
updateDisplay();
}
});
} else {
alertUserAboutError();
}
} catch (IOException e) {
Log.e(TAG, "Exception caught: ", e);
} catch (JSONException e) {
Log.e(TAG, "Exception caught: ", e);
}
}
});
}
else {
Toast.makeText(this, getString(R.string.network_unavailable_message),
Toast.LENGTH_LONG).show();
}
}
private void toggleRefresh() {
if (mProgressBar.getVisibility() == View.INVISIBLE) {
mProgressBar.setVisibility(View.VISIBLE);
mRefreshImageView.setVisibility(View.INVISIBLE);
}
else {
mProgressBar.setVisibility(View.INVISIBLE);
mRefreshImageView.setVisibility(View.VISIBLE);
}
}
private void updateDisplay() {
Current current = mForecast.getCurrent();
mTemperatureLabel.setText(current.getTemperature() + "");
mTimeLabel.setText("At " + current.getFormattedTime() + " it will be");
mHumidityValue.setText(current.getHumidity() + "");
mPrecipValue.setText(current.getPrecipChance() + "%");
mSummaryLabel.setText(current.getSummary());
Drawable drawable = getResources().getDrawable(current.getIconId());
mIconImageView.setImageDrawable(drawable);
}
private Forecast parseForecastDetails(String jsonData) throws JSONException {
Forecast forecast = new Forecast();
forecast.setCurrent(getCurrentDetails(jsonData));
forecast.setHourlyForecast(getHourlyForecast(jsonData));
forecast.setDailyForecast(getDailyForecast(jsonData));
return forecast;
}
private Day[] getDailyForecast(String jsonData) throws JSONException {JSONObject forecast = new JSONObject(jsonData);
String timezone = forecast.getString("timezone");
JSONObject daily = forecast.getJSONObject("daily");
JSONArray data = daily.getJSONArray("data");
Day[] days = new Day[data.length()];
for (int i = 0; i < data.length(); i++) {
JSONObject jsonDay = data.getJSONObject(i);
Day day = new Day();
day.setSummary(jsonDay.getString("summary"));
day.setIcon(jsonDay.getString("icon"));
day.setTime(jsonDay.getLong("time"));
day.setTemperatureMax(jsonDay.getDouble("temperatureMax"));
day.setTimezone(timezone);
days[i] = day;
}
return days;
}
private Hour[] getHourlyForecast(String jsonData) throws JSONException {
JSONObject forecast = new JSONObject(jsonData);
String timezone = forecast.getString("timezone");
JSONObject hourly = forecast.getJSONObject("hourly");
JSONArray data = hourly.getJSONArray("data");
Hour[] hours = new Hour[data.length()];
for (int i = 0; i < data.length(); i++) {
JSONObject jsonHour = data.getJSONObject(i);
Hour hour = new Hour();
hour.setSummary(jsonHour.getString("summary"));
hour.setTemperature(jsonHour.getDouble("temperature"));
hour.setIcon(jsonHour.getString("icon"));
hour.setTime(jsonHour.getLong("time"));
hour.setTimezone(timezone);
hours[i] = hour;
}
return hours;
}
private Current getCurrentDetails(String jsonData) throws JSONException {
JSONObject forecast = new JSONObject(jsonData);
String timezone = forecast.getString("timezone");
Log.i(TAG, "From JSON: " + timezone);
JSONObject currently = forecast.getJSONObject("currently");
Current current = new Current();
current.setHumidity(currently.getDouble("humidity"));
current.setTime(currently.getInt("time"));
current.setSummary(currently.getString("summary"));
current.setTemperature(currently.getInt("temperature"));
current.setIcon(currently.getString("icon"));
current.setPrecipChance(currently.getDouble("precipProbability"));
current.setTimeZone(timezone);
Log.d(TAG, current.getFormattedTime());
return current;
}
private boolean isNetworkAvailable() {
ConnectivityManager manager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if (networkInfo != null && networkInfo.isConnected()) {
isAvailable = true;
}
return isAvailable;
}
private void alertUserAboutError() {
AlertDialogFragment dialog = new AlertDialogFragment();
dialog.show(getFragmentManager(), "error_dialog");
}
#OnClick (R.id.dailyButton)
public void startDailyActivity(View view) {
Intent intent = new Intent(this, DailyForecastActivity.class);
intent.putExtra(DAILY_FORECAST, mForecast.getDailyForecast());
startActivity(intent);
}
#OnClick(R.id.hourlyButton)
public void startHourlyActivity(View view) {
Intent intent = new Intent(this, HourlyForecastActivity.class);
intent.putExtra(HOURLY_FORECAST, mForecast.getHourlyForecast());
startActivity(intent);
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onConnected(Bundle bundle) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
mLatitude = mLastLocation.getLatitude();
mLongitude = mLastLocation.getLongitude();
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
`
getLastLocation() has a high tendency to return null. It also does not request a new location, so even if you get a location, it could be very old, and not reflect the current location. Better to register a listener, even if you just unregister after you get the first onLocationChanged() callback.
This question gets asked a lot, and usually is marked as a duplicate of questions like this one
However, in your case, it also looks like you just forgot to call connect():
buildGoogleApiClient();
mGoogleApiClient.connect(); //added
You can use the code in this answer as a reference for registering for location callbacks, which is suggested if you want to get an accurate current location.
Edit: Since you need only one location, here is a slightly modified version of that code, which requests location updates, and then un-registers for location updates after the first location comes in.
public class MainActivity extends Activity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
private double mLatitude;
private double mLongitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buildGoogleApiClient();
mGoogleApiClient.connect();
}
#Override
protected void onPause(){
super.onPause();
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
//mLocationRequest.setSmallestDisplacement(0.1F);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show();
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
//no need to do a null check here:
mLatitude = location.getLatitude();
mLongitude = location.getLongitude();
//remove location updates if you just need one location:
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
}