I want to get current (or last known) device location and move the camera to it on map when the app starts. I have tried so many ways, but nothing works on Fragment.
Here is my current code with whom the app turns off immediately.
MapFragment.java
public class MapFragment extends Fragment implements OnMapReadyCallback
{
private GoogleMap mGoogleMap;
private FusedLocationProviderClient mFusedLocationProviderClient;
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
private boolean mLocationPermissionGranted;
private Location mLastKnownLocation;
private final LatLng mDefaultLocation = new LatLng(-33.8523341, 151.2106085);
private static final int DEFAULT_ZOOM = 15;
public MapFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this.getActivity());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mView = inflater.inflate(R.layout.fragment_map, container, false);
return mView;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
MapsInitializer.initialize(getContext());
mGoogleMap = googleMap;
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// Turn on the My Location layer and the related control on the map.
updateLocationUI();
// Get the current location of the device and set the position of the map.
getDeviceLocation();
}
private void getLocationPermission() {
/*
* Request location permission, so that we can get the location of the
* device. The result of the permission request is handled by a callback,
* onRequestPermissionsResult.
*/
if (ContextCompat.checkSelfPermission(this.getActivity(),
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
} else {
ActivityCompat.requestPermissions(this.getActivity(),
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
mLocationPermissionGranted = false;
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
}
}
}
updateLocationUI();
}
private void updateLocationUI() {
if (mGoogleMap == null) {
return;
}
try {
if (mLocationPermissionGranted) {
mGoogleMap.setMyLocationEnabled(true);
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
} else {
mGoogleMap.setMyLocationEnabled(false);
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(false);
mLastKnownLocation = null;
getLocationPermission();
}
} catch (SecurityException e) {
Log.e("Exception: %s", e.getMessage());
}
}
private void getDeviceLocation() {
/*
* Get the best and most recent location of the device, which may be null in rare
* cases when a location is not available.
*/
try {
if (mLocationPermissionGranted) {
Task locationResult = mFusedLocationProviderClient.getLastLocation();
locationResult.addOnCompleteListener((Executor) this, new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
if (task.isSuccessful()) {
// Set the map's camera position to the current location of the device.
mLastKnownLocation = (Location) task.getResult();
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(mLastKnownLocation.getLatitude(),
mLastKnownLocation.getLongitude()), DEFAULT_ZOOM));
} else {
Log.d(TAG, "Current location is null. Using defaults.");
Log.e(TAG, "Exception: %s", task.getException());
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM));
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(false);
}
}
});
}
} catch(SecurityException e) {
Log.e("Exception: %s", e.getMessage());
}
}
This way works on FragmentActivity, but not on Fragment.
I've also given ACCESS_FINE_LOCATION permission in AndroindManifest.xml.
Related
I need to loads some KMZ/KML (I tryed both) in my Google Map MapView instance.
But they load really slow, they are 8 KMZ of around 300KB each and for each one it takes more than 3/4 seconds to get loaded.
How can I solve this?
Surfing in search of a solution I found they suggest to use the V3 version because it fix a polyline creation cycle really time consuming in V2.
This is the library:
implementation 'com.google.maps.android:android-maps-utils-v3:1.3.1'
The problem is that when I use this library the constructors of KmlLayer stop working because inside the class KmlLayer it doesn't found the following package of the GoogleMap class, so because all the constructors require a GoogleMap instance they stop working:
import com.google.android.libraries.maps.GoogleMap;
How can I solve this? Is using the V3 version a solution to my problem? If no how can I solve this?
I found other people having the same problem but when they load KML of 10MB or more and not of just 300KB...
This is the class where there is the MapView instance:
public class MappaNuovoGuastoFragment extends Fragment
implements OnMapReadyCallback,
GetLocationManager.OnLocationUpdateCallback,
GoogleMap.OnMapClickListener,
GoogleMap.OnMapLongClickListener,
BaseRetrofitHelper.INetworkResponseCallback {
private static final String TAG = MappaNuovoGuastoFragment.class.getSimpleName();
// Requests Codes - Permission
private static final int REQ_PERMISSION_LOCATION = 0xB01;
// Requests Codes - Networking
private static final int REQ_CODE_PLACES_AUTOCOMPLETE = 0x1;
private static final int REQ_CODE_GET_PLACE_DETAIL = 0x2;
#BindView(R.id.ll_search)
protected LinearLayout mllSearch;
#BindView(R.id.actv_search_field)
protected AutoCompleteTextView mactvSearchField;
#BindView(R.id.map_view)
protected MapView mMapView;
private GoogleMap mGoogleMap;
private GetLocationManager mGetLocationManager;
private LatLng mMyLocation;
private LatLng mClickedLocation;
private Marker mMarker;
private List<GoogleMapPlace> mPlaces;
public static MappaNuovoGuastoFragment newInstance(){
return new MappaNuovoGuastoFragment();
}
//region [#] Override Lifecycle Methods
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mappa_nuovo_guasto, container, false);
ButterKnife.bind(this, view);
initOnCreateView(savedInstanceState);
return view;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQ_PERMISSION_LOCATION) {
if (grantResults.length > 0x0) {
for (int res : grantResults) {
if (res == PackageManager.PERMISSION_GRANTED) {
mMapView.getMapAsync(this);
break;
}
}
}
}
}
#Override
public void onResume() {
super.onResume();
mMapView.onResume();
mGetLocationManager.startLocationUpdates();
}
#Override
public void onPause() {
mGetLocationManager.stopLocationUpdates();
mMapView.onPause();
super.onPause();
}
#Override
public void onDestroy() {
if(mMapView != null){
mMapView.onDestroy();
}
super.onDestroy();
}
#Override
public void onLowMemory() {
mMapView.onLowMemory();
super.onLowMemory();
}
//endregion
//region [#] Actions Methods
#OnClick(R.id.ib_search)
void onClickSearch(View view){
GoogleMapPlace place = null;
if(mPlaces != null && !mPlaces.isEmpty()){
for(GoogleMapPlace p : mPlaces){
if(p.getDescription().equals(mactvSearchField.getText().toString())){
place = p;
break;
}
}
}
if(place != null){
requestPlaceDetails(place.getPlaceId());
} else {
showSnackbarLocationNotFound();
}
}
#OnClick(R.id.b_make)
void onClickMake(View view){
if(mClickedLocation != null || mMyLocation != null){
startActivityGeneraGuasto();
}
}
#OnClick(R.id.b_map_type)
void onClickMapType(View view){
if(mGoogleMap != null){
switch (mGoogleMap.getMapType()){
case GoogleMap.MAP_TYPE_NONE:
case GoogleMap.MAP_TYPE_HYBRID:
case GoogleMap.MAP_TYPE_SATELLITE:
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
break;
case GoogleMap.MAP_TYPE_NORMAL:
case GoogleMap.MAP_TYPE_TERRAIN:
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
break;
}
}
}
//endregion
//region [#] Override OnMapReadyCallback Methods
#Override
public void onMapReady(#NonNull GoogleMap googleMap) {
mGoogleMap = googleMap;
initGoogleMap();
loadKmz();
}
//endregion
//region [#] Override GetLocationManager.OnLocationUpdateCallback Methods
#Override
public void onLocationUpdated(#Nullable Location location) {
if(mMyLocation == null){
mMyLocation = location != null ? new LatLng(location.getLatitude(), location.getLongitude()) : null;
if(mMyLocation != null){
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mMyLocation, 16.0f));
}
} else {
mMyLocation = location != null ? new LatLng(location.getLatitude(), location.getLongitude()) : null;
}
}
//endregion
//region [#] Override GoogleMap.OnMapClickListener Methods
#Override
public void onMapClick(#NonNull LatLng latLng) {
mClickedLocation = latLng;
initMark();
}
//endregion
//region [#] Override GoogleMap.OnMapLongClickListener Methods
#Override
public void onMapLongClick(#NonNull LatLng latLng) {
if(mClickedLocation != null && PositionUtils.distanceBetween(mClickedLocation.latitude, mClickedLocation.longitude, latLng.latitude, latLng.longitude) <= 100){
mClickedLocation = null;
mMarker.remove();
mMarker = null;
}
}
//endregion
//region [#] Override BaseRetrofitHelper.INetworkResponseCallback Methods
#Override
public void onNetworkResponseSuccess(int requestCode, Object answer) {
switch (requestCode){
case REQ_CODE_PLACES_AUTOCOMPLETE:
if(answer != null){
mPlaces = ((GoogleApiPlaceAutocompleteResponse)answer).getPlaces();
List<String> strings = new ArrayList<>();
for(GoogleMapPlace place : mPlaces){
strings.add(place.getDescription());
}
((ArrayAdapter<String>)mactvSearchField.getAdapter()).clear();
((ArrayAdapter<String>)mactvSearchField.getAdapter()).addAll(strings);
}
break;
case REQ_CODE_GET_PLACE_DETAIL:
if(answer != null){
LatLng latlng = ((GoogleApiPlaceDetailsResponse)answer).getResult().getLatLng();
onMapClick(latlng);
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latlng, 15));
} else {
showSnackbarLocationNotFound();
}
break;
}
}
#Override
public void onNetworkResponseError(int requestCode, Throwable t) {
switch (requestCode){
case REQ_CODE_GET_PLACE_DETAIL:
showSnackbarLocationNotFound();
break;
}
}
//endregion
//region [#] Private Methods
private void initOnCreateView(Bundle savedInstanceState){
mMapView.onCreate(savedInstanceState);
mMapView.onResume();
try {
MapsInitializer.initialize(requireActivity().getApplicationContext());
} catch (Exception e){
EMaxLogger.onException(TAG, e);
e.printStackTrace();
}
mMapView.getMapAsync(this);
mGetLocationManager = GetLocationManager.initInstance(requireActivity()).setCallback(this);
initAutocompleteTextView();
mllSearch.bringToFront();
}
private void initGoogleMap(){
if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(requireActivity(), new String[]{ Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }, REQ_PERMISSION_LOCATION);
} else {
mGoogleMap.setMyLocationEnabled(true);
}
mGoogleMap.setOnMapClickListener(this);
mGoogleMap.setOnMapLongClickListener(this);
}
private void initMark(){
if(mMarker != null){
mMarker.remove();
}
LatLng pos = new LatLng(mClickedLocation.latitude, mClickedLocation.longitude);
MarkerOptions opt = new MarkerOptions().position(pos).title(getString(R.string.label_nuovo_guasto));
opt.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_mark_work));
mMarker = mGoogleMap.addMarker(opt);
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(pos, 16.0f));
if (mMarker != null) {
mMarker.showInfoWindow();
}
}
private void initAutocompleteTextView(){
ArrayAdapter<String> adapter = new ArrayAdapter<String>(requireContext(), android.R.layout.select_dialog_item, new ArrayList<>());
mactvSearchField.setThreshold(0x4);
mactvSearchField.setAdapter(adapter);
mactvSearchField.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
if(s.toString().length() >= 0x4){
requestPlaceAutocomplete(s.toString());
}
}
});
}
private void startActivityGeneraGuasto(){
startActivity(GeneraGuastoActivity.getIntent(requireContext(), mClickedLocation != null ? mClickedLocation.latitude : mMyLocation.latitude, mClickedLocation != null ? mClickedLocation.longitude : mMyLocation.longitude));
}
private void showSnackbarLocationNotFound(){
DesignUtils.showSnackbar(mactvSearchField, getString(R.string.error_location_not_found), Snackbar.LENGTH_SHORT);
}
//region [#] Requests Methods
private void requestPlaceAutocomplete(String input){
String key = getString(R.string.google_maps_key);
String components = String.format("country:%1$s", ((TelephonyManager)getActivity().getSystemService(Context.TELEPHONY_SERVICE)).getNetworkCountryIso());
TicketRetrofitHelper.getInstance().requestAsyncGetPlaceAutocomplete(TicketConstants.URL_GOOGLE_API_PLACE_AUTOCOMPLETE, key, input, components, REQ_CODE_PLACES_AUTOCOMPLETE, this);
}
private void requestPlaceDetails(String idPlace){
String key = getString(R.string.google_maps_key);
TicketRetrofitHelper.getInstance().requestAsyncGetPlaceDetails(TicketConstants.URL_GOOGLE_API_PLACE_DETAILS, key, idPlace, REQ_CODE_GET_PLACE_DETAIL, this);
}
//endregion
private void loadKmz(){
try {
KmlLayer kmz1 = new KmlLayer(mGoogleMap, R.raw.centri_abitati_1, requireContext());
KmlLayer kmz2 = new KmlLayer(mGoogleMap, R.raw.centri_abitati_2, requireContext());
KmlLayer kmz3 = new KmlLayer(mGoogleMap, R.raw.confini_comuni_1, requireContext());
KmlLayer kmz4 = new KmlLayer(mGoogleMap, R.raw.confini_comuni_2, requireContext());
KmlLayer kmz5 = new KmlLayer(mGoogleMap, R.raw.viabilita_1, requireContext());
KmlLayer kmz6 = new KmlLayer(mGoogleMap, R.raw.viabilita_2, requireContext());
KmlLayer kmz7 = new KmlLayer(mGoogleMap, R.raw.viabilita_3, requireContext());
KmlLayer kmz8 = new KmlLayer(mGoogleMap, R.raw.viabilita_4, requireContext());
kmz1.addLayerToMap();
kmz2.addLayerToMap();
kmz3.addLayerToMap();
kmz4.addLayerToMap();
kmz5.addLayerToMap();
kmz6.addLayerToMap();
kmz7.addLayerToMap();
kmz8.addLayerToMap();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//endregion
}
I don't know why my map doesn't call to onLocationChanged when I press my button. These are my permissions:
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
This is my class:
public class NuevaCarreraFragment extends Fragment implements OnMapReadyCallback, LocationListener, View.OnClickListener {
private View view;
private LiveButton btnIniciarCarrera;
private LiveButton btnFinalizarCarrera;
private SupportMapFragment mapFragment;
private GoogleMap mGoogleMap;
private LocationManager locationManager;
public static NuevaCarreraFragment newInstance() {
Bundle args = new Bundle();
NuevaCarreraFragment fragment = new NuevaCarreraFragment();
fragment.setArguments(args);
return fragment;
}
/** Ciclo de vida **/
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
// Comprobamos si la vista ya ha sido inflada previamente
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {// Si no ha sido inflada previamente...
view = inflater.inflate(R.layout.fragment_nueva_carrera, container, false);
// Instanciamos los componentes
btnIniciarCarrera = (LiveButton) view.findViewById(R.id.button_iniciar_carrera);
btnFinalizarCarrera = (LiveButton) view.findViewById(R.id.button_finalizar_carrera);
mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
// Escuchamos a nuestros componentes
btnIniciarCarrera.setOnClickListener(this);
btnFinalizarCarrera.setOnClickListener(this);
// Sincronizamos nuestro mapa
mapFragment.onCreate(savedInstanceState);
mapFragment.getMapAsync(this);
} catch (InflateException e) {
e.printStackTrace();
}
return view;
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onResume() {
super.onResume();
if (mapFragment != null) {
mapFragment.onResume();
}
}
#Override
public void onPause() {
if (mapFragment != null) {
locationManager.removeUpdates(this);
mapFragment.onPause();
}
super.onPause();
}
#Override
public void onStop() {
super.onStop();
}
#Override
public void onDestroy() {
Fragment fragment = getFragmentManager().findFragmentById(R.id.map);
if (fragment != null) {
getFragmentManager().beginTransaction()
.remove(fragment)
.commit();
}
super.onDestroy();
}
#Override
public void onDestroyView() {
super.onDestroyView();
Fragment fragment = getFragmentManager().findFragmentById(R.id.map);
if (fragment != null) {
getFragmentManager().beginTransaction()
.remove(fragment)
.commit();
}
}
#Override
public void onLowMemory() {
super.onLowMemory();
if (mapFragment != null) {
mapFragment.onLowMemory();
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mapFragment != null) {
mapFragment.onSaveInstanceState(outState);
}
}
/** OnClickListener **/
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_iniciar_carrera:
// Inicializamos el localizador
locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
} else if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
break;
case R.id.button_finalizar_carrera:
locationManager.removeUpdates(this);
break;
}
}
/** OnMapReadyCallback and LocationListener interface methods **/
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
LatLng sydney = new LatLng(-33.867, 151.206);
mGoogleMap.addMarker(new MarkerOptions()
.title("Sydney")
.snippet("The most populous city in Australia.")
.position(sydney));
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 13));
}
/** LocationListener interface methods **/
#Override
public void onLocationChanged(Location location) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
LatLng misCoordenadas = new LatLng(latitude, longitude);
Geocoder geocoder = new Geocoder(getContext());
try {
List<Address> addressList = geocoder.getFromLocation(latitude, longitude, 1);
String direccion = addressList.get(0).getAddressLine(0);
direccion += "," + addressList.get(0).getLocality();
direccion += "," + addressList.get(0).getCountryName();
mGoogleMap.addMarker(new MarkerOptions()
.position(misCoordenadas)
.title(direccion)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE)));
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(misCoordenadas, 17));
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
The map is properly displayed, but it does not get my location :(.
Any idea ?
UPDATE
Finally I was able to solve de problem implementing Google API Client and Fused Location Api.
Does the app has permission ? Did you handle the not granted case ?
And those provider(s) the app requests are enabled ?
Did you debug the app, and reach the any of locationManager.requestLocationUpdates line ?
Seems like the app is not requesting due to lacking of 1 and 2
I'm a beginner in android programming and I'm currently working on google maps. What I want to do is to get the current location of the user and then put a marker on that location.
I'm practicing on this but I really can't get it to work. This only shows the current location of the user. But what I want to do is to display a marker on it as well. Any suggestions how to do it?
public class MapsActivity extends AppCompatActivity implements GoogleMap.OnMyLocationButtonClickListener,
OnMapReadyCallback,
ActivityCompat.OnRequestPermissionsResultCallback {
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1;
private boolean mPermissionDenied = false;
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setOnMyLocationButtonClickListener(this);
enableMyLocation();
}
private void enableMyLocation() {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
PermissionUtils.requestPermission(this, LOCATION_PERMISSION_REQUEST_CODE,
android.Manifest.permission.ACCESS_FINE_LOCATION, true);
} else if (mMap != null) {
mMap.setMyLocationEnabled(true);
}
}
#Override
public boolean onMyLocationButtonClick() {
Toast.makeText(this, "Showing current location", Toast.LENGTH_SHORT).show();
return false;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode != LOCATION_PERMISSION_REQUEST_CODE) {
return;
}
if (PermissionUtils.isPermissionGranted(permissions, grantResults,
Manifest.permission.ACCESS_FINE_LOCATION)) {
enableMyLocation();
} else {
mPermissionDenied = true;
}
}
Get you last location-
LatLng location = getLatLngFromLastLocation();
Then use this code block to put marker on map:
MarkerOptions markerOptions = new MarkerOptions()
.position(location)
.icon(getMarkerIcon(mProfileTheme.getColorCodeLight()));
public BitmapDescriptor getMarkerIcon(int color) {
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
return BitmapDescriptorFactory.defaultMarker(hsv[0]);
}
In my app I've a MapFragment with the classic "MyLocationButton".
On older APIs I don't have any kind of issue, but since Google asked developers to use Runtime Permissions, I'm facing this problem: when the user clicks ALLOW, the already said button is not appearing, at least not until the user refreshes this fragment. Is there a way to catch the user's press to make the fragment refresh as soon as he's given permissions?
EDIT:
I'm using nested fragments, and I've found out my problem is the same you can see at this page of the AOSP Issue Tracker. I've solved it using the last version of Android APIs (v24).
I'll post my MapFragment:
public class MapFragment extends Fragment implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, PetrolStationsArray.PetrolStationsListener {
private GoogleMap mGoogleMap;
private int mMapType;
private static LatLng mPosition;
private static float mZoom;
private CoordinatorLayout mCoordinatorLayout;
private View mLocationButton;
private AppCompatImageButton mTurnGPSOn;
private FragmentManager mFragmentManager;
private FragmentTransaction mFragmentTransaction;
private SupportMapFragment mSupportMapFragment;
private SupportPlaceAutocompleteFragment mSupportPlaceAutocompleteFragment;
private LocalBroadcastManager mLocalBroadcastManager;
private PetrolStationsArray mPetrolStationsArray;
protected LocationRequest mLocationRequest;
protected GoogleApiClient mGoogleApiClient;
Marker mCurrLocationMarker;
private CountDownTimer mDragTimer;
private boolean mTimerIsRunning = false;
// Design pattern to instantiate a new fragment.
public static MapFragment newInstance() {
MapFragment fragment = new MapFragment();
return fragment;
}
/********************************************************/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Since API 23, Android requests you check for Location Permissions.
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}
mMapType = Integer.parseInt(loadPreferences(SETTINGS_PREFERENCES, MAP_KEY));
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_map, container, false);
mLocalBroadcastManager = LocalBroadcastManager.getInstance(getContext());
mPetrolStationsArray = PetrolStationsArray.get();
mDragTimer = new CountDownTimer(DRAG_TIMER_INTERVAL, DRAG_TIMER_INTERVAL + 1) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
mTimerIsRunning = false;
mPetrolStationsArray.setPosition(mPosition);
}
};
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Initialise a new fragment inside of this one.
mFragmentManager = getChildFragmentManager();
mSupportMapFragment = (SupportMapFragment) mFragmentManager.findFragmentByTag(MAP_FRAGMENT_TAG);
mSupportPlaceAutocompleteFragment = (SupportPlaceAutocompleteFragment) mFragmentManager.findFragmentByTag(AUTOCOMPLETE_FRAGMENT_TAG);
mCoordinatorLayout = (CoordinatorLayout) view.findViewById(R.id.coordinator_layout);
/*
** Never inflate fragments inside other fragments in a layout.xml!
** Do it programmatically.
** See here for reference: http://stackoverflow.com/a/19815266/4938112.
*/
if (mSupportMapFragment == null) {
mSupportMapFragment = new SupportMapFragment();
fragmentTransaction(mFragmentManager, mSupportMapFragment, R.id.map_fragment_container, MAP_FRAGMENT_TAG);
}
// Asynchronous thread to load map.
mSupportMapFragment.getMapAsync(this);
if (mSupportPlaceAutocompleteFragment == null) {
mSupportPlaceAutocompleteFragment = new SupportPlaceAutocompleteFragment();
fragmentTransaction(mFragmentManager, mSupportPlaceAutocompleteFragment, R.id.card_view, AUTOCOMPLETE_FRAGMENT_TAG);
}
// Filter for a specific place type.
AutocompleteFilter typeFilter = new AutocompleteFilter.Builder()
.setTypeFilter(AutocompleteFilter.TYPE_FILTER_CITIES | AutocompleteFilter.TYPE_FILTER_ADDRESS)
.build();
mSupportPlaceAutocompleteFragment.setFilter(typeFilter);
mSupportPlaceAutocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
LatLng position = place.getLatLng();
CameraUpdate centre = CameraUpdateFactory.newLatLng(position);
CameraUpdate zoom = CameraUpdateFactory.zoomTo(ZOOM_LEVEL);
mGoogleMap.moveCamera(centre);
mGoogleMap.animateCamera(zoom);
}
#Override
public void onError(Status status) {
Log.d("PLACE_ERROR", "An error occurred: " + status);
}
});
mTurnGPSOn = ((AppCompatImageButton) view.findViewById(R.id.turn_gps_on));
mTurnGPSOn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Ask if the user wants to open the GPS - settings.
displayPromptToEnableGPS(getActivity());
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onMapReady(GoogleMap googleMap) {
this.mGoogleMap = googleMap;
mGoogleMap.setMapType(mMapType);
if (mPosition != null) {
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(mPosition, mZoom);
mGoogleMap.moveCamera(cameraUpdate);
}
mGoogleMap.setTrafficEnabled(true);
mGoogleMap.getUiSettings().setMapToolbarEnabled(false);
mGoogleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition cameraPosition) {
mPosition = cameraPosition.target;
mZoom = cameraPosition.zoom;
if (mTimerIsRunning) {
mDragTimer.cancel();
}
mDragTimer.start();
mTimerIsRunning = true;
}
});
// Get the "My Position" button.
mLocationButton = ((View) mSupportMapFragment.getView().findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) mLocationButton.getLayoutParams();
Resources r = getActivity().getResources();
int px = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
10,
r.getDisplayMetrics()
);
// Position on right bottom.
rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
rlp.setMargins(0, 0, px, px);
turnOnMyLocation();
}
#Override
public void onPause() {
super.onPause();
// Stop location updates when Activity is no longer active.
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
mPetrolStationsArray.removePetrolStationListener(this);
}
#Override
public void onResume() {
super.onResume();
mPetrolStationsArray.setPetrolStationsListener(this);
}
#Override
public void onListUpdated() {
// Cleaning all the markers.
if (mGoogleMap != null) {
mGoogleMap.clear();
}
List<PetrolStation> petrolStationList = mPetrolStationsArray.getList();
for (PetrolStation petrolStation : petrolStationList) {
double lat = petrolStation.getLat();
double lon = petrolStation.getLon();
String name = petrolStation.getName();
if (mGoogleMap != null) {
mGoogleMap.addMarker(new MarkerOptions()
.position(new LatLng(lat, lon))
.title(name));
}
}
}
#Override
public void onServerRequest() {
}
#Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
#Override
public void onConnectionSuspended(int i) {
// TODO
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// TODO
}
#Override
public void onLocationChanged(Location location) {
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
// Just a check to overtake the
// 'java.lang.IllegalStateException: Fragment MapFragment{42f519d0} not attached to Activity'
// exception I've encountered.
if (!isAdded()) {
return;
}
// Stop location updates.
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
// Start the transaction between different fragments.
private void fragmentTransaction(FragmentManager mFragmentManager, Fragment fragment, int id, String tag) {
mFragmentTransaction = mFragmentManager.beginTransaction();
mFragmentTransaction.add(id, fragment, tag);
mFragmentTransaction.commit();
mFragmentManager.executePendingTransactions();
}
/*********************************************
************ LOCATION PERMISSIONS ************
*********************************************/
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
turnOnMyLocation();
} else {
// Permission denied, boo! Disable the functionality that depends on this permission.
String message = getResources().getString(R.string.permission_denied);
Snackbar snackbar = Snackbar
.make(mCoordinatorLayout, message, Snackbar.LENGTH_LONG)
.setAction(R.string.close_snack_bar, new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
snackbar.show();
}
}
}
}
// Ask for permission (START DIALOG) in Android APIs >= 23.
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
// Prompt the user once explanation has been shown.
requestPermissions(new String[] {
Manifest.permission.ACCESS_FINE_LOCATION
}, MY_PERMISSIONS_REQUEST_LOCATION);
} else {
// No explanation needed, we can request the permission.
requestPermissions(new String[] {
Manifest.permission.ACCESS_FINE_LOCATION
}, MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
public void turnOnMyLocation() {
// Initialise Google Play Services.
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mGoogleMap.setMyLocationEnabled(true);
}
} else {
mGoogleMap.setMyLocationEnabled(true);
}
}
// Let's build our Location Services API Client.
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient
.Builder(getContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
public static void displayPromptToEnableGPS(final Activity activity) {
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
final String action = Settings.ACTION_LOCATION_SOURCE_SETTINGS;
final String message = MyFuelApp.getAppContext().getResources().getString(R.string.open_gps_settings);
builder.setMessage(message)
.setPositiveButton(MyFuelApp.getAppContext().getResources().getString(R.string.confirm_ok),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int id) {
activity.startActivity(new Intent(action));
d.dismiss();
}
})
.setNegativeButton(MyFuelApp.getAppContext().getResources().getString(R.string.deny_no),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int id) {
d.cancel();
}
});
builder.create().show();
}
}
One way to solve is to ask before open your MapFragment. This way you only have to check if you have the permission or not at your fragment to load one view or another.
The other way, is to add the button at your method turnOnMyLocation().
You can use
onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
within this callback you should check the equality of the request code that you passed while requesting permission with the one in the parameter. If it matches, you can get the user result.
If user allow the permission, then you can simply detach and attach your fragment as follow:
Fragment currentFragment = getFragmentManager().findFragmentByTag("FRAGMENT");
FragmentTransaction fragTransaction = getFragmentManager().beginTransaction();
fragTransaction.detach(currentFragment);
fragTransaction.attach(currentFragment);
fragTransaction.commit();
This is how your fragment will be reloaded and also your views gets refreshed. I hope by this you can address your problem.
I'm trying to set a listener to catch camera moves but it doesn't work. The method onCameraChange, implemented by the Fragment that host the SupportMapFragment, is never called also if I set up all right. This similar question didn't help me.
Here's the code of the Fragment:
public class MapFragment extends Fragment implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
OnMapReadyCallback, GoogleMap.OnCameraChangeListener {
private static final String TAG = MapFragment.class.getSimpleName();
private static final int MY_LOCATION_REQUEST_PERMISSION = 100;
private static final int ENABLE_LOCATION_REQUEST_PERMISSION = 200;
private int mShortAnimationDuration;
private ImageButton checkin;
private LinearLayout big_checkin;
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
private double mLatitude, mLongitude;
private SupportPlaceAutocompleteFragment autocompleteFragment;
public MapFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "onCreate");
}
super.onCreate(savedInstanceState);
buildGoogleApiClient();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "onCreateView");
}
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_map, container, false);
final SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
final DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
final Toolbar toolbar = (Toolbar) view.findViewById(R.id.map_toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
getActivity(), drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
autocompleteFragment = (SupportPlaceAutocompleteFragment)
getChildFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
return view;
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(getContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
private void getMyLocation() {
if (ContextCompat.checkSelfPermission(getContext(),
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
PermissionUtils.requestPermission((AppCompatActivity) getActivity(), MY_LOCATION_REQUEST_PERMISSION, Manifest.permission.ACCESS_FINE_LOCATION, false);
} else {
final Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (lastLocation != null) {
mLatitude = lastLocation.getLatitude();
mLongitude = lastLocation.getLongitude();
LatLng latLng = new LatLng(mLatitude, mLongitude);
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 17);
if (mMap != null) {
mMap.animateCamera(cameraUpdate);
mClusterManager.clearItems();
addItems();
}
} else {
if (mMap != null) {
mMap.setMyLocationEnabled(false);
}
final ImageButton myLocation = (ImageButton) getView().findViewById(R.id.my_location); //TODO migliorare
myLocation.setVisibility(View.GONE);
}
}
}
#Override
public void onDestroy() {
if (BuildConfig.DEBUG) {
Log.d(TAG, "onDestroy");
}
super.onDestroy();
}
#Override
public void onDestroyView() {
if (BuildConfig.DEBUG) {
Log.d(TAG, "onDestroyView");
}
super.onDestroyView();
mMap = null;
mGoogleApiClient = null;
autocompleteFragment = null;
}
#Override
public void onStart() {
if (BuildConfig.DEBUG) {
Log.d(TAG, "onStart");
}
super.onStart();
if (mGoogleApiClient != null)
mGoogleApiClient.connect();
}
#Override
public void onStop() {
if (BuildConfig.DEBUG) {
Log.d(TAG, "onStop");
}
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == MY_LOCATION_REQUEST_PERMISSION) {
if (PermissionUtils.isPermissionGranted(permissions, grantResults,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Enable the my location layer if the permission has been granted.
getMyLocation();
} else {
//TODO avvisare che si devono dare i permessi?
// Display the missing permission error dialog when the fragments resume.
}
} else if (requestCode == ENABLE_LOCATION_REQUEST_PERMISSION) {
if (PermissionUtils.isPermissionGranted(permissions, grantResults,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Enable the my location layer if the permission has been granted.
enableMyLocation();
} else {
//TODO avvisare che si devono dare i permessi?
// Display the missing permission error dialog when the fragments resume.
}
}
}
private void enableMyLocation() {
if (ContextCompat.checkSelfPermission(getContext(),
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
PermissionUtils.requestPermission((AppCompatActivity) getActivity(), ENABLE_LOCATION_REQUEST_PERMISSION, Manifest.permission.ACCESS_FINE_LOCATION, false);
} else {
if (mMap != null) {
// Access to the location has been granted to the app.
mMap.setMyLocationEnabled(true);
//getMyLocation();
}
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "mapReady");
}
mMap = googleMap;
mMap.setOnCameraChangeListener(this);
enableMyLocation();
setUpClusterer();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "onConnected");
}
if (ContextCompat.checkSelfPermission(getContext(),
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
PermissionUtils.requestPermission((AppCompatActivity) getActivity(), MY_LOCATION_REQUEST_PERMISSION, Manifest.permission.ACCESS_FINE_LOCATION, false);
} else {
final Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (lastLocation != null) {
mLatitude = lastLocation.getLatitude();
mLongitude = lastLocation.getLongitude();
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(mLatitude, mLongitude), 17);
if (mMap != null) {
mMap.moveCamera(cameraUpdate);
mClusterManager.clearItems();
addItems();
}
} else {
if (mMap != null) {
mMap.setMyLocationEnabled(false);
}
final ImageButton myLocation = (ImageButton) getView().findViewById(R.id.my_location); //TODO migliorare
myLocation.setVisibility(View.GONE);
}
}
}
#Override
public void onConnectionSuspended(int i) {
Log.i("GOOGLE API CLIENT", "Connection suspended");
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onCameraChange(CameraPosition cameraPosition) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "onCameraChange");
}
LatLng center = cameraPosition.target;
Snackbar.make(getView(), center.latitude + " - " + center.longitude, Snackbar.LENGTH_SHORT);
}
}
Here's the layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="me.grinworld.grinpark.MapFragment">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.v7.widget.Toolbar
android:id="#+id/map_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_margin="8dp"
android:background="#drawable/map_bar"
android:elevation="3dp"
android:padding="3dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="#drawable/map_bar_search">
<ImageView
android:id="#+id/fav_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:src="#drawable/ic_favorite_idle"/>
<fragment
android:id="#+id/place_autocomplete_fragment"
android:name="com.google.android.gms.location.places.ui.SupportPlaceAutocompleteFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toStartOf="#id/fav_icon"
android:layout_gravity="center" />
</RelativeLayout>
</android.support.v7.widget.Toolbar>
RESOLVED.
I just noticed that, since I was using ClusterManager, I set up as onCameraChangeListener this manager, that obviously overrode my custom method.