我想在地图上显示我的位置并放大它。我想使用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
答案 0 :(得分:49)
用于定位api-23及更高版本:
请参阅答案here。
用于定位api-22及更低版本
以下是完整的活动代码,它可以满足您的需求,是my other answer here的修改版本。它在Activity加载时注册一个位置监听器,然后当每个位置发生更改事件时,它将添加一个Marker并为地图设置动画以居中当前位置。
这里的关键是在请求位置更新之前等待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);
}
}
答案 1 :(得分:1)
这会有效吗
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();
}
}
答案 2 :(得分:0)
非常简单,您只需要一种在MapLiveLocation
中很重要的方法,即OnLocationChanged
package abstractcode.sumasoft.com.mapdemo;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
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.LocationListener;
import com.google.android.gms.location.LocationRequest;
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.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.ArrayList;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private GoogleMap mMap;
ArrayList<LatLng> MarkerPoints;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
LocationRequest mLocationRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}
MarkerPoints = new ArrayList<>();
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
} else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
@SuppressLint("RestrictedApi")
@Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position" + location.getLatitude() + " " + location.getLongitude());
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(18));
//stop location updates
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
} else {
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
}
}
}