I have tried many sources but I am not getting what should be used for my fragment to get the current location.
This is my fragment:
public class GMapFragment extends Fragment implements OnMapReadyCallback {
private GoogleMap googleMap;
MapFragment fragment;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_gmap, container, false);
initilizeMap();
return rootView;
}
private void initilizeMap()
{
MapFragment fragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
if (fragment != null){
fragment.getMapAsync(this);
}
}
#Override
public void onMapReady(final GoogleMap googleMap) {
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
}
#Override
public void onPause() {
final FragmentManager fragManager = this.getFragmentManager();
final Fragment fragment = fragManager.findFragmentById(R.id.map);
if(fragment!=null){
fragManager.beginTransaction().remove(fragment).commit();
super.onPause();
}
}
#Override
public void onDestroy() {
super.onDestroy();
final FragmentManager fragManager = this.getFragmentManager();
final Fragment fragment = fragManager.findFragmentById(R.id.map);
if(fragment!=null){
fragManager.beginTransaction().remove(fragment).commit();
}
}
}
If anyone can help? I need a source or sample that can be used with this fragment. please help, I'm stuck here for days
from documentation
While enabled and the location is available
Do you have available location ?
Did you have ACCESS_FINE_LOCATION in your Manifest file?
Also, know that if your app is running on >= API 23 device, you have to request the permission grant from the users.
Follow the official GUIDE
EDIT:
Do you have initialized Google Play Services?
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(getActivity()).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
Connect the above google api client in onStart and disconnect in onstop
#Override
public void onStart() {
super.onStart();
if (mGoogleApiClient != null)
mGoogleApiClient.connect();
}
Override the methods.
public void onConnected(#Nullable Bundle bundle) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
}
myLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (myLocation != null) {
showCurrentLocation(myLocation);
return;
}
if (!NetworkHelper.isGpsEnabled(getActivity()))
PopUp.showAlertDialog(act, "Enable GPS",
"Help us to get your current location");
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, locationRequest, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
if (location == null)
return;
myLocation = location;
showCurrentLocation(location);
}
});
}
Related
I'm using Google maps to show my Office location inside Fragment. When I compile and run the application, It shows the maps but doesn't mark my location.
and on fragment java file, map.setMyLocationEnabled(true);
is been underlined by red color and I don't know how to solve it.
Below is my code from Fragment maps.
public class maps extends Fragment implements OnMapReadyCallback {
private Context mContext;
private SupportMapFragment supportMapFragment;
private GoogleMap map;
private MarkerOptions currentPositionMarker = null;
private Marker currentLocationMarker;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mContext = getActivity();
return inflater.inflate(R.layout.fragment_maps, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mContext = getActivity();
FragmentManager fm = getActivity().getSupportFragmentManager();/// getChildFragmentManager();
supportMapFragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
if (supportMapFragment == null) {
supportMapFragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map_container, supportMapFragment).commit();
}
supportMapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
if (ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
map.setMyLocationEnabled(true);
map.animateCamera(CameraUpdateFactory.zoomTo(15));
/*map.setOnMapLongClickListener(MapyFragment.this);
map.setOnMapClickListener(MapFragment.this);*/
}
public void updateCurrentLocationMarker(Location currentLatLng){
if(map != null){
LatLng latLng = new LatLng(currentLatLng.getLatitude(),currentLatLng.getLongitude());
if(currentPositionMarker == null){
currentPositionMarker = new MarkerOptions();
currentPositionMarker.position(latLng)
.title("My Location").
icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_facebook_3));
currentLocationMarker = map.addMarker(currentPositionMarker);
}
if(currentLocationMarker != null)
currentLocationMarker.setPosition(latLng);
///currentPositionMarker.position(latLng);
map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}
}
}
Thanks in advance.
For the current location, you find the best solution with the proper example you find below google official document. Try it your self it will explore you.
https://developers.google.com/maps/documentation/android-api/current-places-tutorial?hl=pt-br
I want to show my current location using Google maps v2 from a fragment however the Google maps is not initializing on start up. When i run the application, it is nor crashing but the map is not showing my current location neither is it displaying anything. I have used this code on my activity and it is fully functional.
Below is my java code:
public class MapFragment extends Fragment implements LocationListener,GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,OnMapReadyCallback {
SupportMapFragment mSupportMapFragment;
MapView mMapView;
Location mLastLocation;
Marker mCurrLocationMarker;
private MarkerOptions markerOptions;
protected GoogleApiClient mGoogleApiClient;
private LatLng latLng;
public GoogleMap mMap;
private Marker marker;
LocationRequest mLocationRequest;
private GoogleMap googleMap;
private TextView lastTrip, lastDeliveryText, lastDelivery, lastAmountText, lastAmount, kes,
todayTotal, totalDeliveryText, totalDelivery, totalAmount, totalAmountText;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
buildGoogleApiClient();
// inflat and return the layout
View v = inflater.inflate(R.layout.map_fragment, container,
false);
mSupportMapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.mapwhere);
if (mSupportMapFragment == null) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
mSupportMapFragment = SupportMapFragment.newInstance();
fragmentTransaction.replace(R.id.mapwhere, mSupportMapFragment).commit();
}
if (mSupportMapFragment != null) {
mSupportMapFragment.getMapAsync(this);
}
return v;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
Log.d("one","one");
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//mMap.getUiSettings().setZoomControlsEnabled(true);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
Log.d("two","two");
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
} else {
Log.d("three","three");
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
protected synchronized void buildGoogleApiClient() {
Log.d("four","four");
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.build();
mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
Log.d("five","five");
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//mMap.getUiSettings().setZoomControlsEnabled(true);
final Double lat = location.getLatitude();
final Double lng = location.getLongitude();
Log.d("LATLANGz", lat + "|" + lng);
latLng = new LatLng(lat, lng);
markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Positionn");
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;
}
mMap.setMyLocationEnabled(false);
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.user_location));
marker = mMap.addMarker(markerOptions);
//move map camera_main
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(12));
}
#Override
public void onResume() {
super.onResume();
Log.d("hey2","hey2");
// mMapView.onResume();
mSupportMapFragment.onResume();
}
#Override
public void onPause() {
super.onPause();
Log.d("hey1","hey1");
// mMapView.onPause();
mSupportMapFragment.onPause();
}
/* #Override
public void onDestroy() {
super.onDestroy();
// mMapView.onDestroy();
mSupportMapFragment.onDestroy();
}*/
#Override
public void onLowMemory() {
super.onLowMemory();
// mMapView.onLowMemory();
mSupportMapFragment.onLowMemory();
}
#Override
public void onDetach() {
Log.d("detach", "detach");
super.onDetach();
mSupportMapFragment.onDetach();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d("six","six");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (mGoogleApiClient.isConnected()){
Log.d("seven","six");
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
first of all Chaeck permission in manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
then check method for current location
private GoogleMap.OnMyLocationChangeListener myLocationChangeListener = new GoogleMap.OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location location) {
LatLng loc = new LatLng(location.getLatitude(), location.getLongitude());
marker = map.addMarker(new MarkerOptions().position(loc));
if(map != null){
map.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f));
}
}
};
then use
mMap.setOnMyLocationChangeListener(myLocationChangeListener);
and be patience map take laoding time depend on you network speed
comment if any query
First check your permissions and your google api key in your manifest
Your xml layout must be something like this without any thing else:
. <fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.isg_biz.isg_tracking.MainActivity" />
You have to implement OnMapReadyCallback, then
your code should be something like this in onCreate() :
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
Do not to copy and past the same xml code literally you have to change (tools : .....) to same that exist in your xml
for documentation, java code & more Please read :
https://developers.google.com/maps/documentation/android-api/map-with-marker
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 trying to put this class in a fragment , how can I make it into a fragment class?
public class MapsActivity extends FragmentActivity {
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
I need these methods working in my fragment . But I'm not able to drive through the button
public void onSearch(View view) {
EditText location_tf = (EditText) findViewById(R.id.TFaddress);
String location = location_tf.getText().toString();
List<Address> addressList = null;
if (location != null || !location.equals("")) {
Geocoder geocoder = new Geocoder(this);
try {
addressList = geocoder.getFromLocationName(location, 1);
} catch (IOException e) {
e.printStackTrace();
}
Address address = addressList.get(0);
LatLng latLng = new LatLng(address.getLatitude(), address.getLongitude());
mMap.addMarker(new MarkerOptions().position(latLng).title("Marker"));
mMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
}
}
public void onZoom(View view) {
if (view.getId() == R.id.Bzoomin) {
mMap.animateCamera(CameraUpdateFactory.zoomIn());
}
if (view.getId() == R.id.Bzoomout) {
mMap.animateCamera(CameraUpdateFactory.zoomOut());
}
}
public void changeType(View view) {
if (mMap.getMapType() == GoogleMap.MAP_TYPE_NORMAL) {
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
} else
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
All these actions are connected to the layout through " onClick "
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
mMap.setMyLocationEnabled(true);
}
}
what works for me is this
childFragmentManager.fragments[0] as SupportMapFragment?
Let me explain : I have a fragment : Map Fragment and inside it there is an other fragmenr with the map so it is his only child. Be aware that i it is not the best practice but i works for now
class MapFragment : Fragment(), OnMapReadyCallback {
private lateinit var mMap: GoogleMap
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val rootView: View = inflater.inflate(R.layout.fragment_map, container, false)
val mapFragment =
childFragmentManager.fragments[0] as SupportMapFragment?
mapFragment!!.getMapAsync(this)
return rootView
}
override fun onMapReady(googleMap: GoogleMap?) {
mMap = googleMap!!
// Add a marker in Sydney and move the camera
val sydney = LatLng(-34.0, 151.0)
mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
}
}
my xml of my fragment is
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.MainActivity">
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
</FrameLayout>
Fragment Class should like this...
public MyMapFragment extends Fragment{
private GoogleMap map;
public GoogleApiClient mGoogleApiClient;
private LocationRequest locationRequest;
private Location myLocation;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGoogleApiClient = new GoogleApiClient.Builder(getActivity()).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
}
#Override
public void onActivityCreated(Bundle savedInstance) {
super.onActivityCreated(savedInstance);
map = ((MapFragment) act.getFragmentManager()
.findFragmentById(R.id.map)).getMap();
map.getUiSettings().setRotateGesturesEnabled(false);
map.getUiSettings().setZoomControlsEnabled(false);
map.setTrafficEnabled(true);
map.setOnMarkerDragListener(dragListener);
map.setOnMapLongClickListener(longClickListener);
}
#Override
public void onStart() {
super.onStart();
if (mGoogleApiClient != null)
mGoogleApiClient.connect();
}
private void showCurrentLocation(Location location) {
if (map.getCameraPosition().zoom < MAP_ZOOM_LEVEl) {
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(
location.getLatitude(), location.getLongitude()), 12));
}
CameraPosition cameraPosition = new CameraPosition(new LatLng(
location.getLatitude(), location.getLongitude()),
map.getCameraPosition().zoom, 45, 360);
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
}
myLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (myLocation != null) {
showCurrentLocation(myLocation);
return;
}
if ("Check for GPS Status")
Show the error if not enabled
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, locationRequest, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
if (location == null)
return;
myLocation = location;
showCurrentLocation(location);
}
});
}
protected void createLocationRequest() {
locationRequest = new LocationRequest();
locationRequest.setFastestInterval(FASTEST_INTERVAL);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public void onStop() {
super.onStop();
if (mGoogleApiClient != null && mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
}
#Override
public void onDestroyView() {
super.onDestroyView();
MapFragment mapFragment = (MapFragment) getActivity()
.getFragmentManager().findFragmentById(R.id.map);
if (mapFragment != null)
getActivity().getFragmentManager().beginTransaction()
.remove(mapFragment).commit();
}
}
Layout for that fragment
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
In my project, Maps was implemented in the following way:
No meu projeto em implementei o Maps da seguindo maneira:
public class MainFragment extends Fragment implements OnMapReadyCallback {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
MapFragment fragment = (MapFragment) getChildFragmentManager().findFragmentById(R.id.map);
fragment.getMapAsync(this);
} }
Am trying to build an application that requests the current location using the GoogleClientApi and LocationServices, but the Location is always null even that I enabled the WiFi,Mobile Data and GPS , tested it on several devices all the same
the permissions from the manifest.xml :
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Activity:
public class FindStation extends Fragment implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener,com.google.android.gms.location.LocationListener
{
public static FragmentManager fragmentManager;
Button goButton;
Spinner spinner;
SupportMapFragment mapFragment;
GoogleMap map;
List<Stations> stationsList;
ArrayList<String> stationsAddresses;
private static View view;
ArrayList<MarkerOptions> markers;
GoogleApiClient mGoogleApiClient;
LocationServices locationServices;
Location location;
private static String TAG="FIND_STATION";
Context context;
LocationRequest mLocationRequest;
LocationListener locationListener;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
context= getActivity();
locationListener=this;
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(10);
/*mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();*/
buildGoogleApiClient();
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {
view = inflater.inflate(R.layout.activity_find_station, container, false);
} catch (InflateException e) {
}
inflater.inflate(R.layout.activity_find_station,container,false);
stationsAddresses = new ArrayList<>();
goButton= (Button) view.findViewById(R.id.button);
//goButton.setVisibility(View.INVISIBLE);
spinner= (Spinner) view.findViewById(R.id.spinner);
stationsList = Stations.listAll(Stations.class);
markers = new ArrayList<>();
for (int i = 0; i <stationsList.size() ; i++) {
stationsAddresses.add(stationsList.get(i).getStationLocation());
markers.add(new MarkerOptions().position(new LatLng(stationsList.get(i).getStationLat(), stationsList.get(i).getStationLong())).title(stationsList.get(i).getStationName()));
}
goButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//location= LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}
});
try {
initialize();
} catch (Exception e) {
e.printStackTrace();
}
try {
// map.setMyLocationEnabled(true);
} catch (Exception e) {
e.printStackTrace();
}
/*thread = new Thread(new MyThread());
thread.start();*/
return view;
}
private void initialize() {
if (map==null) {
Fragment fragment= getChildFragmentManager().findFragmentById(R.id.map);
mapFragment= (SupportMapFragment) fragment;
map=mapFragment.getMap();
for (int i = 0; i <markers.size() ; i++) {
map.addMarker(markers.get(i));
}
// check if map is created successfully or not
if (map==null) {
Toast.makeText(super.getActivity(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
}
public void onDestroyView() {
super.onDestroyView();
android.support.v4.app.FragmentManager fm = getActivity().getSupportFragmentManager();
SupportMapFragment fragment = (SupportMapFragment) fm.findFragmentById(R.id.map);
if (fragment!=null) {
android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
ft.remove(fragment);
ft.commit();
}
}
#Override
public void onConnected(Bundle bundle) {
location= LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location!=null){
Log.d(TAG,location.toString());
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(),location.getLongitude()),3f);
map.animateCamera(update);
}
Log.d(TAG,"connected");
}
#Override
public void onConnectionSuspended(int i) {
Log.d(TAG,"connection suspended "+String.valueOf(i));
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG,"connection failed");
}
#Override
public void onLocationChanged(Location location) {`enter code here`
Log.d(TAG,location.toString());
this.location=location;
if (location!=null) {
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 3f);
map.animateCamera(update);
Log.d(TAG, "camera updated to new position");
goButton.setVisibility(View.VISIBLE);
}
}
#Override
public void onStart() {
super.onStart();
mGoogleApiClient.connect();
Log.d(TAG,"connect() was called");
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
the strange thing is that the onConnect() method is called but after that the Location is always null and onLocationChanged() is never called
using the maps, i tried the enabling my location and it works when you have the button on the right top corner it returns the location and animates the camera.
UPDATE 1
updated the onConnected() method and made it request locations updates,
public void onConnected(Bundle bundle) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, locationListener);
if (location!=null){
Log.d(TAG,location.toString());
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(),location.getLongitude()),3f);
map.animateCamera(update);
}
Log.d(TAG,"connected");}
then with a button i call lastKnownLocation() since the onLocationChanged() is not called still, and still the returned Location is null
UPDATE 2 :
The very same code worked on Android 5.0.1 and worked perfectly
all the other devices was on android 2.3.7,4.0.1 none of them worked,
Any idea about what difference in the Android APIs regarding the location?
You need to call requestLocationUpdates() in order to register the listener and have onLocationChanged() invoked.
Be sure to un-register the listener as soon as possible to avoid excessive battery drain.
Also note that the getLastLocation() method can and will return null. The main problem is that it doesn't prompt a request to the OS for a new location lock, instead it just checks if there was a last known location from some other app's location request. If no other app had recently made a location request, then you get a null location returned to you.
The only way to guarantee that you actually get a location is to request one, and this is done with a call to requestLocationUpdates().
Here is a working example for reference:
public class MainActivity extends FragmentActivity
implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private GoogleMap map;
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
private Marker marker;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
buildGoogleApiClient();
mGoogleApiClient.connect();
if (map == null) {
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
}
#Override
public void onMapReady(GoogleMap retMap) {
map = retMap;
setUpMap();
}
public void setUpMap(){
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
map.setMyLocationEnabled(true);
}
#Override
protected void onPause(){
super.onPause();
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
protected synchronized void buildGoogleApiClient() {
Toast.makeText(this, "buildGoogleApiClient", Toast.LENGTH_SHORT).show();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onConnected(Bundle bundle) {
Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show();
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;
//remove previous current location Marker
if (marker != null){
marker.remove();
}
double dLatitude = mLastLocation.getLatitude();
double dLongitude = mLastLocation.getLongitude();
marker = map.addMarker(new MarkerOptions().position(new LatLng(dLatitude, dLongitude))
.title("My Location").icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(dLatitude, dLongitude), 8));
}
}
One more thing, if your map is in a Fragment, there is no need to have a nested SupportMapFragment. You can just have your Fragment extend SupportMapFragment. This removes the need of having a nested Fragment, and you don't even need to inflate any layout xml, here is a simple example:
public class MapTabFragment extends SupportMapFragment
implements OnMapReadyCallback {
private GoogleMap mMap;
private Marker marker;
public MapTabFragment() {
}
#Override
public void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (mMap == null) {
getMapAsync(this);
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
setUpMap();
}
private void setUpMap() {
mMap.setMyLocationEnabled(true);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.getUiSettings().setMapToolbarEnabled(false);
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
//remove previously placed Marker
if (marker != null) {
marker.remove();
}
//place marker where user just clicked
marker = mMap.addMarker(new MarkerOptions().position(point).title("Marker")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)));
}
});
}
}