How to show my current location in Google Map Android using google API client
I want to show my location on a map and zoom in on it. I want to use the GoolgeAPIClient. The map renders and the the pointer is created but the location so wrong. I feel that the onMapReady is executed first even before the onConnected method of the GoogleAPIClient is called. Please help this is my code.
import android.location.Location;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
protected static final String TAG = "MainActivity";
/**
* Provides the entry point to Google Play services.
*/
protected GoogleApiClient mGoogleApiClient;
/**
* Represents a geographical location.
*/
protected Location mLastLocation;
protected String mLatitudeLabel;
protected String mLongitudeLabel;
protected TextView mLatitudeText;
protected TextView mLongitudeText;
protected double dLat;
protected double dLong;
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
buildGoogleApiClient();
// 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);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng myLocation = new LatLng(dLat, dLong);
mMap.addMarker(new MarkerOptions().position(myLocation).title("You are here"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(myLocation));
}
/**
* BEGIN
*/
/**
* Builds a GoogleApiClient. Uses the addApi() method to request the LocationServices API.
*/
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
/**
* Runs when a GoogleApiClient object successfully connects.
*/
@Override
public void onConnected(Bundle connectionHint) {
// Provides a simple way of getting a device's location and is well suited for
// applications that do not require a fine-grained location and that do not need location
// updates. Gets the best and most recent location currently available, which may be null
// in rare cases when a location is not available.
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
dLat = mLastLocation.getLatitude();
dLong = mLastLocation.getLongitude();
} else {
Toast.makeText(this, R.string.no_location_detected, Toast.LENGTH_LONG).show();
}
}
@Override
public void onConnectionFailed(ConnectionResult result) {
// Refer to the javadoc for ConnectionResult to see what error codes might be returned in
// onConnectionFailed.
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
@Override
public void onConnectionSuspended(int cause) {
// The connection to Google Play services was lost for some reason. We call connect() to
// attempt to re-establish the connection.
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
}
11-17 01:30:39.482 30546-30546/com.gioinout.giohanda E/dalvikvm: Could not find class 'android.app.AppOpsManager', referenced from method com.google.android.gms.common.GooglePlayServicesUtil.zzb
11-17 01:30:39.538 30546-30569/com.gioinout.giohanda E/GMPM: getGoogleAppId failed with status: 10
11-17 01:30:39.539 30546-30569/com.gioinout.giohanda E/GMPM: Uploading is not possible. App measurement disabled
11-17 01:30:39.579 30546-30546/com.gioinout.giohanda E/dalvikvm: Could not find class 'android.app.AppOpsManager', referenced from method com.google.android.gms.common.ma.a
11-17 01:30:39.684 30546-30546/com.gioinout.giohanda E/dalvikvm: Could not find class 'android.app.AppOpsManager', referenced from method com.google.android.gms.common.lt.a
11-17 01:30:40.226 30546-30577/com.gioinout.giohanda E/NativeCrypto: ssl=0x5d26beb8 cert_verify_callback x509_store_ctx=0x60700ab0 arg=0x0
11-17 01:30:40.227 30546-30577/com.gioinout.giohanda E/NativeCrypto: ssl=0x5d26beb8 cert_verify_callback calling verifyCertificateChain authMethod=ECDHE_ECDSA
11-17 01:30:42.982 30546-30579/com.gioinout.giohanda E/NativeCrypto: ssl=0x6151f770 cert_verify_callback x509_store_ctx=0x60910ab0 arg=0x0
11-17 01:30:42.983 30546-30579/com.gioinout.giohanda E/NativeCrypto: ssl=0x6151f770 cert_verify_callback calling verifyCertificateChain authMethod=ECDHE_ECDSA
Solution 1:
For targeting api-23 and higher:
See the answer here.
For targeting api-22 and lower:
Here is the full Activity code that does what you need, a modified version of my other answer here. It registers a location listener when the Activity loads, then when each location changed event occurs, it will add a Marker and also animate the map to center on the current location.
The key here is to wait until the onMapReady() callback has occurred before you request location updates.
Here is the full Activity code:
public class MainActivity extends AppCompatActivity implements
OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
LatLng latLng;
GoogleMap mGoogleMap;
SupportMapFragment mFragment;
Marker currLocationMarker;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap gMap) {
mGoogleMap = gMap;
mGoogleMap.setMyLocationEnabled(true);
buildGoogleApiClient();
mGoogleApiClient.connect();
}
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();
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
//place marker at current position
//mGoogleMap.clear();
latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
currLocationMarker = mGoogleMap.addMarker(markerOptions);
}
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000); //5 seconds
mLocationRequest.setFastestInterval(3000); //3 seconds
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
//mLocationRequest.setSmallestDisplacement(0.1F); //1/10 meter
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) {
//place marker at current position
//mGoogleMap.clear();
if (currLocationMarker != null) {
currLocationMarker.remove();
}
latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
currLocationMarker = mGoogleMap.addMarker(markerOptions);
Toast.makeText(this,"Location Changed",Toast.LENGTH_SHORT).show();
//zoom to current position:
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,11));
//If you only need one location, unregister the listener
//LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
Solution 2:
Would this work
Follow this link: Getting error: Could not find class 'android.app.AppOpsManager', referenced from method com.google.android.gms.common.GooglePlayServicesUtil.zza
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
@Override
protected void onStart() {
super.onStart();
if (mGoogleApiClient!= null && !mGoogleApiClient.isConnected())
mGoogleApiClient.connect();
}
@Override
public void onConnected(Bundle connectionHint) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
dLat = mLastLocation.getLatitude();
dLong = mLastLocation.getLongitude();
//Does this log?
Log.d(getClass().getSimpleName(), String.valueOf(dLat) + ", " + String.valueOf(dLong));
} else {
Toast.makeText(this, R.string.no_location_detected, Toast.LENGTH_LONG).show();
}
}