如何使用Google API客户端在Google Map Android中显示我当前的位置

我想在地图上显示我的位置并放大它。 我想使用GoolgeAPIClient。 地图呈现并创建指针,但位置错误。 我觉得即使在调用GoogleAPIClient的onConnected方法之前,也会先执行onMapReady。 请帮助这是我的代码。

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 

针对api-23及更高版本:

请在此处查看答案。

针对api-22及更低版本:

这是完整的活动代码,可以满足您的需求,这是我的其他答案的修改版本。 它在Activity加载时注册一个位置监听器,然后当每个位置发生更改事件时,它将添加一个Marker并为地图设置animation以居中在当前位置。

这里的关键是在请求位置更新之前等待onMapReady()回调发生。

这是完整的活动代码:

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

这会有用吗?

请访问此链接: 获取错误:找不到类’android.app.AppOpsManager’,从方法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(); } }