Location Updates to Firebase are too fast, lags application - java

My current goal is to send the LatLng to Firebase. I did achieve this but the problem I have now is that after a couple of updates to Firebase, my location field starts to receive updates super fast which in turn lags my application and also increases my phones temperature.
How would I go about sending location updates to firebase twice every minute without having the application lag?
I send the location updates to Firebase under the onLocationChanged(Location) method.
Here is my Mapfragment class.
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.mycompany.neighbors.MainActivity;
import com.mycompany.neighbors.R;
import com.mycompany.neighbors.User;
/**
* Created by joshua on 5/25/2016.
*/
public class MapFragment extends Fragment implements OnMapReadyCallback,LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{
private GoogleApiClient mGoogleApiClient;
private final String FIREBASE_URL = "MY_URL";
private static final int MY_PERMISSIONS_REQUEST_FINE_LOCATION = 101;
SupportMapFragment mSupportMapFragment;
private GoogleMap maps;
private boolean permissionIsGranted = false;
private LatLng mLatLng;
private User mApplicationUser;
private static String mApplicationUserUID;
public static MapFragment newInstance(int index){
MapFragment mapFragment = new MapFragment();
Bundle args = new Bundle();
args.putInt("index",index);
mapFragment.setArguments(args);
return mapFragment;
}
private void createMap(){
mSupportMapFragment = SupportMapFragment.newInstance();
FragmentManager fm = getFragmentManager();
mSupportMapFragment.getMapAsync(this);
if(!mSupportMapFragment.isAdded())
fm.beginTransaction().add(R.id.map_frag,mSupportMapFragment).commit();
else if(mSupportMapFragment.isAdded())
fm.beginTransaction().hide(mSupportMapFragment).commit();
else
fm.beginTransaction().show(mSupportMapFragment).commit();
}
private void requestLocationUpdates() {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(60000);
if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_FINE_LOCATION);
}
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
/////////////////////////////////////////OVERRIDE METHODS////////////////////////////////////////////////////////////
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.fragment_map,container,false);
mApplicationUserUID = MainActivity.getUID();
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
createMap();
return v;
}
////////////////////////////////////////LIFECYCLE METHODS///////////////////////////////////////////////////////////
#Override
public void onStart(){
super.onStart();
mGoogleApiClient.connect();
}
#Override
public void onResume(){
super.onResume();
if(permissionIsGranted){
if(mGoogleApiClient.isConnected()){
requestLocationUpdates();
}
}
}
#Override
public void onStop(){
if(permissionIsGranted){
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this);
mGoogleApiClient.disconnect();
}
super.onStop();
}
///////////////////////LIFECYCLE METHODS//////////////////////////////////////////////
#Override
public void onMapReady(GoogleMap googleMap) {
maps = googleMap;
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d("TAG_JOSH", "onConnected");
requestLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
Log.d("TAG_JOSH", "Connection suspended");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.d("TAG_JOSH", "Connection failed");
}
#Override
public void onLocationChanged(final Location location) {
Log.d("TAG_JOSH","Latitude: " +Double.toString(location.getLatitude()));
final LatLng coordinates = new LatLng(location.getLatitude(),location.getLongitude());
final Firebase userRef = new Firebase("MY_URL");
userRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
userRef.setValue(coordinates);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults){
super.onRequestPermissionsResult(requestCode,permissions,grantResults);
switch(requestCode){
case MY_PERMISSIONS_REQUEST_FINE_LOCATION:
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
//Permission granted
permissionIsGranted = true;
} else{
//Permission denied
permissionIsGranted = false;
Toast.makeText(getContext(),"This app requires location permissions", Toast.LENGTH_SHORT).show();
}
break;
}
}
/////////////////////////////////////////OVERRIDE METHODS////////////////////////////////////////////////////////////
}

If you're trying to send your location twice a minute, you need to remove the part of sending location updates in Firebase inside onLocationChanged.
Add a CountDownTimer and trigger to send a location update after each 30 seconds have passed.
So you need to do something like this.
Take two global variables
private Location currentLocation;
private Location previousLocation;
Now inside your onCreateView declare a timer like this.
new CountDownTimer(30000, 1000) { // 30 seconds timer
public void onTick(long millisUntilFinished) {
// Do nothing
}
public void onFinish() {
// Send location update to firebase here if the previous location sent to server and the current location is not the same.
final LatLng coordinates = new LatLng(currentLocation.getLatitude(),currentLocation.getLongitude());
if(currentLocation == previousLocation) return; // Pseudo code
final Firebase userRef = new Firebase("MY_URL");
userRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
userRef.setValue(coordinates);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
// Now start the timer from here again.
this.start(); // Pseudo code.
}
}.start();
Inside your onLocationChanged function, just update the currentLocation like this
#Override
public void onLocationChanged(final Location location) {
currentLocation = location; // Update the current location here
}

Related

How can I show navigation route to a fixed location from current location?

This is my code which shows route to some point from curent location of user to that point....
My code works fine...
My current code shows route when marker is added after onclick event occurs but what I want to achieve is if I have a predefined marker at fixed longitude and latitude which is defined as p1 variable in below code, then it should show the route from the current location...
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.google.android.material.navigation.NavigationView;
import com.mapbox.android.core.permissions.PermissionsListener;
import com.mapbox.android.core.permissions.PermissionsManager;
import com.mapbox.api.directions.v5.models.DirectionsResponse;
import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.LocationComponent;
import com.mapbox.mapboxsdk.location.modes.CameraMode;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
import com.mapbox.services.android.navigation.ui.v5.NavigationLauncher;
import com.mapbox.services.android.navigation.ui.v5.NavigationLauncherOptions;
import com.mapbox.services.android.navigation.ui.v5.route.NavigationMapRoute;
import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconIgnorePlacement;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
public class ViewMapActivity extends AppCompatActivity implements OnMapReadyCallback, MapboxMap.OnMapClickListener, PermissionsListener {
private DrawerLayout drawerLayout;
private ActionBarDrawerToggle actionBarDrawerToggle;
private NavigationView navigationView;
Toolbar toolbar;
MapView mapView;
MapboxMap mapboxMap;
LocationComponent locationComponent;
private PermissionsManager permissionmanager;
DirectionsRoute currentRoute;
NavigationMapRoute navigationMapRoute;
LatLng p1=new LatLng(72.843214,19.018335);//this is the fixed marker cordinates which I want to use
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapbox.getInstance(this,getString(R.string.mapbox_access_token) );
setContentView(R.layout.activity_view_map);
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
toolbar=findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Navigation");
Toolbar toolbar=findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
drawerLayout=findViewById(R.id.drawer_layout);
actionBarDrawerToggle = new ActionBarDrawerToggle(ViewMapActivity.this,drawerLayout,R.string.drawer_open,R.string.drawer_close);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
navigationView = findViewById(R.id.naivgation_view);
View navView = navigationView.inflateHeaderView(R.layout.navigation_header);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
// UserMenuSelected(menuItem);
return false;
}
});
}
#Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
}
#Override
public void onPermissionResult(boolean granted) {
if (granted) {
enableLocationComponent(mapboxMap.getStyle());
} else {
Toast.makeText(this, "Permission not granted", Toast.LENGTH_SHORT).show();
finish();
}
}
#Override
public boolean onMapClick(#NonNull LatLng point) {
Point destinationPoint = Point.fromLngLat(point.getLongitude(), point.getLatitude());
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
}
Point originPoint = Point.fromLngLat(locationComponent.getLastKnownLocation().getLongitude(), locationComponent.getLastKnownLocation().getLatitude());
GeoJsonSource source = mapboxMap.getStyle().getSourceAs("destination-source-id");
if (source != null) {
source.setGeoJson(Feature.fromGeometry(destinationPoint));
}
getRoute(originPoint, destinationPoint);
return true;
}
private void getRoute(Point originPoint, Point destinationPoint) {
NavigationRoute.builder(this)
.accessToken(Mapbox.getAccessToken())
.origin(originPoint)
.destination(destinationPoint)
.build()
.getRoute(new Callback<DirectionsResponse>() {
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
Log.d("response inside fun", String.valueOf(response.body().routes().size()));
if (response.body() != null && response.body().routes().size() >= 1) {
currentRoute = response.body().routes().get(0);
Log.d("current route", String.valueOf(currentRoute));
if (navigationMapRoute != null) {
navigationMapRoute.removeRoute();
} else {
navigationMapRoute = new NavigationMapRoute(null, mapView, mapboxMap, R.style.NavigationMapRoute);
}
navigationMapRoute.addRoute(currentRoute);
}
}
#Override
public void onFailure(Call<DirectionsResponse> call, Throwable t) {
}
});
}
#Override
public void onMapReady(#NonNull MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
this.mapboxMap.setMinZoomPreference(15);
mapboxMap.setStyle(getString(R.string.navigation_guidance_day), new Style.OnStyleLoaded() {
#Override
public void onStyleLoaded(#NonNull Style style) {
enableLocationComponent(style);
addDestinationIconLayer(style);
mapboxMap.addOnMapClickListener(ViewMapActivity.this);
}
});
}
private void addDestinationIconLayer(Style style) {
style.addImage("destination-icon-id",
BitmapFactory.decodeResource(this.getResources(), R.drawable.mapbox_marker_icon_default));
GeoJsonSource geoJsonSource = new GeoJsonSource("destination-source-id");
style.addSource(geoJsonSource);
SymbolLayer destinationSymbolLayer = new SymbolLayer("destination-symbol-layer-id", "destination-source-id");
destinationSymbolLayer.withProperties(iconImage("destination-icon-id"), iconAllowOverlap(true), iconIgnorePlacement(true));
style.addLayer(destinationSymbolLayer);
}
public void startNavigationBtnClick(View v) {
boolean simulateRoute = true;
NavigationLauncherOptions options = NavigationLauncherOptions.builder()
.directionsRoute(currentRoute)
.shouldSimulateRoute(false)
.build();
NavigationLauncher.startNavigation(ViewMapActivity.this, options);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
permissionmanager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
private void enableLocationComponent(#NonNull Style style) {
if (PermissionsManager.areLocationPermissionsGranted(this)) {
locationComponent = mapboxMap.getLocationComponent();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationComponent.activateLocationComponent(this, style);
locationComponent.setLocationComponentEnabled(true);
locationComponent.setCameraMode(CameraMode.TRACKING);
} else {
permissionmanager = new PermissionsManager(this);
permissionmanager.requestLocationPermissions(this);
}
}
// Add the mapView lifecycle to the activity's lifecycle methods
#Override
public void onResume() {
super.onResume();
mapView.onResume();
}
#Override
protected void onStart() {
super.onStart();
mapView.onStart();
}
#Override
protected void onStop() {
super.onStop();
mapView.onStop();
}
#Override
public void onPause() {
super.onPause();
mapView.onPause();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
#Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
}
How can I achieve this?
In onStyleLoaded(), instead of calling mapboxMap.addOnMapClickListener, you should just put the code you have in the onClick() method, like this:
Point destinationPoint = Point.fromLngLat(p1.getLongitude(), p1.getLatitude());
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
}
Point originPoint = Point.fromLngLat(locationComponent.getLastKnownLocation().getLongitude(), locationComponent.getLastKnownLocation().getLatitude());
GeoJsonSource source = mapboxMap.getStyle().getSourceAs("destination-source-id");
if (source != null) {
source.setGeoJson(Feature.fromGeometry(destinationPoint));
}
getRoute(originPoint, destinationPoint);

Getting current location on Android

I want to find out where my location is currently on the device connected to my computer, but since my location has not changed, it does not fall into the onLocationChanged function and therefore returns location = null. How do I enter the onLocationChanged function?
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setOnMapLongClickListener(this);
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
LatLng userLocation = new LatLng(location.getLatitude(), location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15));
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
};
Like Sai suggested, you can use the fused location provider to retrieve the device's last known location which will display your current location.
Check out the working code sample below:
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private FusedLocationProviderClient fusedLocationClient;
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
if (mapFragment != null) {
mapFragment.getMapAsync(this);
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (checkPermissions()) {
mMap.setMyLocationEnabled(true);
}
fusedLocationClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if (location != null) {
System.out.println("current location: " + location.toString());
} else {
System.out.println("current location is null");
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
System.out.println("error trying to get current location");
e.printStackTrace();
}
});
}
private boolean checkPermissions() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
requestPermissions();
return false;
}
}
private void requestPermissions() {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
1);
}
}
Hope it helps!

Location altitude always 0.0 for my service(fusedLocation)

I need to know if there is a way to get the location with fusedLocation Api, actually i am implementing a service this service has a method that returns the location, the location is refreshing each time on the service so i get it on my desired activity.
With lat and lon everything is correct, except for altitude, i always get 0.0 is there a way using fusedlocation to get the altitude?
here is my service code:
package com.example.afcosta.inesctec.pt.android.services;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class GoogleLocation extends Service implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private static final String TAG = "BOOMBOOMTESTGPS";
private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 0;
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 0;
private static final float LOCATION_DISTANCE = 0f;
private int updatePriority;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private final IBinder mBinder = new LocalBinder();
private Intent intent;
private String provider;
Context context;
Location mLastLocation;
public class LocalBinder extends Binder {
public GoogleLocation getServerInstance() {
return GoogleLocation.this;
}
}
public Location getLocation() {
Log.d("IMHERE", "HELLO");
return mLastLocation;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
context = getApplicationContext();
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public void onCreate() {
Log.e(TAG, "onCreate");
initializeLocationManager();
if (mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
this.updatePriority = LocationRequest.PRIORITY_HIGH_ACCURACY;
} else if (mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
this.updatePriority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY;
} else {
this.updatePriority = LocationRequest.PRIORITY_HIGH_ACCURACY;
}
this.buildGoogleApiClient();
this.createLocationRequest();
this.googleApiClient.connect();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
// Request location updates
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(this.googleApiClient, this.locationRequest,this);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
Log.d("localizacao",mLastLocation.toString());
}
#Override
public void onDestroy() {
Log.e(TAG, "onDestroy");
super.onDestroy();
this.googleApiClient.unregisterConnectionCallbacks(this);
this.googleApiClient.unregisterConnectionFailedListener(this);
this.googleApiClient.disconnect();
this.mLastLocation = null;
}
private void initializeLocationManager() {
Log.e(TAG, "initializeLocationManager");
mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
private synchronized void buildGoogleApiClient() {
this.googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
private void createLocationRequest() {
this.locationRequest = new LocationRequest();
this.locationRequest.setInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
this.locationRequest.setPriority(updatePriority);
}
thank you!

Permission error using GPS

I want to get back the position of my phone but I have a problem with this line:
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,10000,0,(LocationListener) this);
I know the problem is the permission check but I don't know to do this in my code:
package com.cmn.cmnvtc;
import android.app.Fragment;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MainPageFragment1 extends Fragment implements OnMapReadyCallback, LocationListener {
LocationManager locationManager;
public LatLng myLocation;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_main1, container, false);
locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,10000,0,(LocationListener) this);
return v;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
MapFragment fragment = (MapFragment) getChildFragmentManager().findFragmentById(R.id.map);
fragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
LatLng marker = new LatLng(48.9818555, 2.270541);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(marker, 15));
googleMap.addMarker(new MarkerOptions().title("Le garage").position(marker));
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
#Override
public void onLocationChanged(Location location) {
if(location != null){
Toast.makeText(getActivity(), "Latitude:" + location.getLatitude() + " - Longitude:" + location.getLongitude(), Toast.LENGTH_SHORT);
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
How can I do this , please?
My error is in the code : "Add permission check"
You need to check it for Marshmollow
private static final int GRANTED = PackageManager.PERMISSION_GRANTED;
if (checkCoarseLocationPermission(getActivity()) && checkFineLocationPermission(getActivity())) {
//permissions are granted
}else {
requestLocationPermission(getActivity());
}
}
public boolean checkCoarseLocationPermission(Activity mActivity){
int permissionCheck = ContextCompat.checkSelfPermission(mActivity,
Manifest.permission.ACCESS_COARSE_LOCATION);
return permissionCheck == GRANTED;
}
public boolean checkFineLocationPermission(Activity mActivity){
int permissionCheck = ContextCompat.checkSelfPermission(mActivity,
Manifest.permission.ACCESS_FINE_LOCATION);
return permissionCheck == GRANTED;
}
public void requestLocationPermission(Activity mActivity){
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
try this
public void onLocationChanged(Location location) {
if(location != null){
location = locationManager .getLastKnownLocation(LocationManager.GPS_PROVIDER);
Toast.makeText(getActivity(), "Latitude:" + location.getLatitude() + " - Longitude:" + location.getLongitude(), Toast.LENGTH_SHORT);
}
}
You need to add the permissions in the manifest of your app. Open your manifest.xml and put this two lines:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
ACCESS_FINE_LOCATION allows your app to track the user position using the actual GPS.
ACCESS_COARSE_LOCATION allows your app to track the user position using WiFi Networks, so you can omit this one if you are only using the GPS.

Fatal Exception : java.lang.IllegalArgumentException: GoogleApiClient parameter is required

I'm trying to create an Android Location API using Google Play Services.
But I keep on getting " java.lang.IllegalStateException: GoogleApiClient is required ".
Can anyone tell me what I am doing wrong?
Here's the code which I have been trying.
CODE:
package com.example.jamshi.locationapi;
import android.app.Activity;
import android.location.Location;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class MainActivity extends Activity implements ConnectionCallbacks,OnConnectionFailedListener {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private Location mLastLocation;
private GoogleApiClient mGoogleApiClient;
private TextView tvLocation;
private Button btnShowLocation,btnLocationUpdates;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvLocation = (TextView) findViewById(R.id.tvLocation);
btnShowLocation = (Button) findViewById(R.id.btnShowLocation);
btnLocationUpdates = (Button) findViewById(R.id.btnLocationUpdates);
boolean checkPlayServices = false;
if(checkPlayServices){
buildApiClient();
}
btnShowLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
displayLocation();
}
});
}
private void displayLocation() {
//buildApiClient();
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
tvLocation.setText(latitude + ", " + longitude);
} else {
tvLocation.setText("(Couldn't get the location. Make sure location is enabled on the device)");
}
}
private boolean checkPlayServices(){
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if(resultCode != ConnectionResult.SUCCESS){
if(GooglePlayServicesUtil.isUserRecoverableError(resultCode)){
GooglePlayServicesUtil.getErrorDialog(resultCode,this,PLAY_SERVICES_RESOLUTION_REQUEST).show();
}else{
Toast.makeText(getApplicationContext(),"This device is not supported",Toast.LENGTH_LONG).show();
finish();
}
return false;
}
return true;
}
protected synchronized void buildApiClient() {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
}
#Override
protected void onStart() {
super.onStart();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
#Override
protected void onResume() {
super.onResume();
checkPlayServices();
}
/**
* Google api callback methods
*/
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
#Override
public void onConnected(Bundle arg0) {
// Once connected with google api, get the location
displayLocation();
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
}
Because mGoogleApiClient is null.
buildApiClient() method is never called also, probably you made a mistake in onCreate
boolean checkPlayServices = false;
if(checkPlayServices){
buildApiClient();
}
Elaborated
This checkPlayServices variable here false, so it does not call buildApiClient() method, as a result mGoogleApiClient is null.
#Override
protected void onCreate(Bundle savedInstanceState) {
...
boolean checkPlayServices = false;
if(checkPlayServices){
buildApiClient();
}
}
connect method is not called, because mGoogleApiClient is null
#Override
protected void onStart() {
super.onStart();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
After the activity is created, and when you call displayLocation() method, it crashes due to mGoogleApiClient is null
private void displayLocation() {
//buildApiClient();
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
...
}

Categories