LocationServices.FusedLocationApi.getLastLocation Always gets null - android

I'm trying to mark current user location in a maps activity but the call of LocationServices.FusedLocationApi.getLastLocation always returns null
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback,GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener {
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
protected void onStart() {
if(mGoogleApiClient.isConnected())
Toast.makeText(this,"Client Connect",Toast.LENGTH_SHORT).show();
else
mGoogleApiClient.connect();
super.onStart();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
LatLng myLocation = null;
if(mLastLocation!=null) {
myLocation = new LatLng(mLastLocation.getLatitude(),
mLastLocation.getLongitude());
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myLocation,
mMap.getMaxZoomLevel() - 5));
}
} else {
// Show rationale and request permission.
}
}
}
Also i have added the permission in manifest file
when checking for mGoogleApiClient for connectivity it's always not connected

You need to register a listener to the location events, and start listening for a short period of time to several locations received, and compare their accuracy , source, etc, to determine which is the best one, and use that one.
Read Location strategies google documentation, which is pretty useful and has code examples of what you need to do to get accurate locations.
Also add this permission to the manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Related

Google maps v2 not initializing in fragment

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

access location with google maps

I want to access my location using google maps and I don't know why it doesn't work.
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
}
that is what appears when I rule the emulator:
Now I try to learn sth about maps, but in final I want to press on a button and to apear in google maps the location of a restaurant or sth else. How can I do this?
This is the Complete Code for accessing device location (not including the maps key part which i think you have already done)
public class MapsActivity extends FragmentActivity implements
OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener
{
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
public Location mLocation;
#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);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
}
#Override
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
public void onConnected( Bundle bundle) {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
}
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLocation != null && mMap != null) {
LatLng tun = new LatLng(mLocation.getLatitude(), mLocation.getLongitude());
mMap.addMarker(new MarkerOptions().position(tun).title("Marker in Sydney"));
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
}
you have to write this code in the manifest.xml as well
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
this will allow app to be able to use device's location
The only thing that remains is that you MUST do GRANT the access of the Location by going to the settings of the app in the permissions menu Allow App for GPS location in other case it will not show the location
'com.google.android.gms:play-services:11.0.2'
you have to compile play services in order to access LocationListener
Did you add the acces location permissions in the manifest

getLastLocation() always null in GoogleApiClient

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)));
}
});
}
}

Change zoom level Google Maps Api v2 on app start

Is it possible to change the zoom level as soon as the map is ready? When I open the app it shows the map and the blue dot for my location. However, the zoom level is the default 3. How can I change this? I know how to do it when the 'MyLocationButton'is clicked but not when the app starts.
This is my class
public class MainPhoneActivity extends FragmentActivity implements ConnectionCallbacks, OnConnectionFailedListener, LocationSource, LocationListener, OnMyLocationButtonClickListener, OnMapReadyCallback{
private GoogleApiClient mGoogleApiClient;
private OnLocationChangedListener mMapLocationListener = null;
// location accuracy settings
private static final LocationRequest REQUEST = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_phone);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.mapView);
mapFragment.getMapAsync(this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
protected void onResume() {
super.onResume();
mGoogleApiClient.connect();
}
#Override
public void onPause() {
super.onPause();
mGoogleApiClient.disconnect();
}
#Override
public void onMapReady(GoogleMap map) {
map.setLocationSource(this);
map.setMyLocationEnabled(true);
map.setOnMyLocationButtonClickListener(this);
}
public void showMyLocation(View view) {
if (mGoogleApiClient.isConnected()) {
String msg = "Location = "
+ LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onLocationChanged(Location location) {
if (mMapLocationListener != null) {
mMapLocationListener.onLocationChanged(location);
}
}
#Override
public void onConnected(Bundle connectionHint) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, REQUEST,this);
}
#Override
public void onConnectionSuspended(int cause) {
// Do nothing
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Do nothing
}
#Override
public boolean onMyLocationButtonClick() {
return false;
}
#Override
public void activate(OnLocationChangedListener onLocationChangedListener) {
mMapLocationListener = onLocationChangedListener;
}
#Override
public void deactivate() {
mMapLocationListener = null;
}
}
You can set zoom level like following:
map.animateCamera(CameraUpdateFactory.newLatLngZoom(point,15));
Where point is your LatLng position. In this way you can center the map in that point with given zoom level.
Complete method:
#Override
public void onMapReady(GoogleMap map) {
map.setLocationSource(this);
map.setMyLocationEnabled(true);
map.setOnMyLocationButtonClickListener(this);
//newLatLngZoom(LatLng , ZoomLevel) -> choose your zoom level
// and change my 'point' with yours
map.animateCamera(CameraUpdateFactory.newLatLngZoom(point,15));
}
EDIT:
If you want to get the dot coords, you can try this:
Location loc = map.getMyLocation();
LatLng point = new LatLng(loc.getlatitude() , loc.getLongitude());
and use that point as center.
Complete method:
#Override
public void onMapReady(GoogleMap map) {
map.setLocationSource(this);
map.setMyLocationEnabled(true);
map.setOnMyLocationButtonClickListener(this);
Location loc = map.getMyLocation();
if(loc != null){
LatLng point = new LatLng(loc.getLatitude() , loc.getLongitude());
map.animateCamera(CameraUpdateFactory.newLatLngZoom(point,15));
}
}
This could cause a NullPointerException beacuse loc could be null.
OTHER SOLUTION
If you want to get only first time the coordinates, you should work in onLocationChanged, using a boolean variable to set first call.
Declare it CRDS_CALL = false;
#Override
public void onLocationChanged(Location location) {
if (mMapLocationListener != null) {
mMapLocationListener.onLocationChanged(location);
if(!CRDS_CALL){
LatLng point = new LatLng(location.getLatitude(), location.getLognitude());
map.animateCamera(CameraUpdateFactory.newLatLngZoom(point,15));
CRDS_CALL = true;
}
}
}
In this answer i use map, but you have to use your mapFragment, but if you want to use it in other methods over onCreate, you have to declare outside of it.
Add this just before the onCreate
SupportMapFragment mapFragment;
And inside it, use it like follwing:
mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.mapView);
mapFragment.getMapAsync(this);
In that way, you can use mapFragment in other methods
Solution
The solution was to do everything #MikeKeepsOnShine said but remove the
Location loc = map.getMyLocation();
LatLng point = new LatLng(loc.getLatitude() , loc.getLongitude());
map.animateCamera(CameraUpdateFactory.newLatLngZoom(point,15));
part from onMapReady. Works absolutely perfectly now!
You should use this. And you should put this request in onMapReady() callback. Something like this:
#Override
public void onMapReady(GoogleMap map) {
map.setLocationSource(this);
map.setMyLocationEnabled(true);
map.setOnMyLocationButtonClickListener(this);
map.animateCamera(CameraUpdateFactory.zoomTo(14), 2000, null);
}
you have already done the new "MapAsync" way so you are one step forward to the result.
In order to zoom, you can use the animateCamera method for googleMap object to zoom to a specific location:
https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap.html#animateCamera(com.google.android.gms.maps.CameraUpdate)
for example, a zoomin:
map.animateCamera(CameraUpdateFactory.zoomIn());
or if you already know "where":
map.animateCamera(CameraUpdateFactory.newLatLngZoom(knownlocation,17));
and you will be very close to the location.
If you need to do at the first "locationUpdate" you should keep a flag to false and set to true the first time you receive a location, at that time you perform the zoom to location.
EDIT: If you want to zoom only the first time, where you receive location updates (which is not really clear from your code), you can do, assuming you have a class variable like:
private boolean FIRST_TIME = true;
the following code:
if(FIRST_TIME){
myMap.animateCamera(CameraUpdateFactory.newLatLngZoom(location,17));
FIRST_TIME = false;
}
The best option is to remove the listener but it seems you use location updates as "blue dot" updates.
What worked for me was:
mMap.setMinZoomPreference(6.0f);
mMap.setMaxZoomPreference(20.0f);
You can modify the zoom preference values to your taste.

GPS tracker with GoogleApiClient

in the last update of google services, Google has depercated LocationClient api and now say use GoogleApiClient.
Now need create the App with GPS report any 30 seconds to my webserver but dont found (or dont understant) how work this new api.
If you have a example using GoogleApiClient please past the link to see or download.
And if have a Service with GoogleApiClient please past the link
Thanks for your help.
If you have installed android sdk then just checkout following directory \extras\google\google_play_services\samples\maps\src\com\example\mapdemo\.
It is having one example of showing current location in GoogleMap and it is using GoogleApiClient to retrieve current location on periodic interval of 5 seconds as described in following code. You can modify it according to your requirements.
MyLocationDemoActivity.java
public class MyLocationDemoActivity extends FragmentActivity
implements
ConnectionCallbacks,
OnConnectionFailedListener,
LocationListener,
OnMyLocationButtonClickListener {
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
private TextView mMessageView;
// These settings are the same as the settings for the map. They will in fact give you updates
// at the maximal rates currently possible.
private static final LocationRequest REQUEST = LocationRequest.create()
.setInterval(5000) // 5 seconds
.setFastestInterval(16) // 16ms = 60fps
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_location_demo);
mMessageView = (TextView) findViewById(R.id.message_text);
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
setUpGoogleApiClientIfNeeded();
mGoogleApiClient.connect();
}
#Override
public void onPause() {
super.onPause();
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
}
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) {
mMap.setMyLocationEnabled(true);
mMap.setOnMyLocationButtonClickListener(this);
}
}
}
private void setUpGoogleApiClientIfNeeded() {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
}
/**
* Button to get current Location. This demonstrates how to get the current Location as required
* without needing to register a LocationListener.
*/
public void showMyLocation(View view) {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
String msg = "Location = "
+ LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
}
/**
* Implementation of {#link LocationListener}.
*/
#Override
public void onLocationChanged(Location location) {
mMessageView.setText("Location = " + location);
}
/**
* Callback called when connected to GCore. Implementation of {#link ConnectionCallbacks}.
*/
#Override
public void onConnected(Bundle connectionHint) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient,
REQUEST,
this); // LocationListener
}
/**
* Callback called when disconnected from GCore. Implementation of {#link ConnectionCallbacks}.
*/
#Override
public void onConnectionSuspended(int cause) {
// Do nothing
}
/**
* Implementation of {#link OnConnectionFailedListener}.
*/
#Override
public void onConnectionFailed(ConnectionResult result) {
// Do nothing
}
#Override
public boolean onMyLocationButtonClick() {
Toast.makeText(this, "MyLocation button clicked", Toast.LENGTH_SHORT).show();
// Return false so that we don't consume the event and the default behavior still occurs
// (the camera animates to the user's current position).
return false;
}
}
I had exactly your same problem. You need to explicitely use GoogleMap.setLocationSource().
Here is an example: Android: Google Maps location with low battery usage

Categories

Resources