我正在尝试让Google地图显示用户的当前位置,并且每15秒左右更新一次。我使用新的FusedLocationProviderClient实现了API,但摄像头不以用户位置为中心,也不响应纬度和经度的变化。
我已经设置了Android Manifest和Gradle依赖项。我知道FusedLocationProviderClient.getLastLocation()为null,因为以前没有提供过任何位置。所以我尝试实现LocationCallback和requestLocationUpdates来尝试更新位置,但这也不起作用。
我曾经想过,整个问题可能是由于Android Virtual Emulator无法模拟用户位置,但我不知道如何使用它。
我正在使用Nexus 5x API 26仿真器。 代码如下。
由于
public class ExploreActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
FusedLocationProviderClient fusedLocationClient;
LocationRequest locationRequest;
LocationCallback locationCallback;
static final int LOCATION_PERMISSION_REQUEST = 101;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_explore);
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Log.i("onCreate", "requesting permission");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_REQUEST);
} else {
initMap();
}
}
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
locationRequest = new LocationRequest();
locationRequest.setInterval(15000); //interval between updates
locationRequest.setFastestInterval(5000); //if there is another app updating more often, then simply take that location
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
//setup location call back
locationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
Log.i("callback", "working");
for (Location location : locationResult.getLocations()) {
LatLng userLocation = new LatLng(location.getLatitude(), location.getLongitude());
Log.i("lat", Double.toString(userLocation.latitude));
Log.i("long", Double.toString(userLocation.longitude));
}
}
};
}
private void initMap() {
// 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) {
Toast.makeText(this, "Map is ready", Toast.LENGTH_SHORT).show();
mMap = googleMap;
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Log.i("onMapReady", "permission has been granted");
mMap.setMyLocationEnabled(true);
fusedLocationClient.getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
if (location != null) {
Log.i("onSuccess", "success");
LatLng userLocation = new LatLng(location.getLatitude(), location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 13));
} else {
Log.i("onSuccess", "failed");
//location is null possibly due last location not being initialized
}
}
});
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case LOCATION_PERMISSION_REQUEST:
if (grantResults.length > 0) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "This app requires location permissions for the map to show!", Toast.LENGTH_SHORT).show();
return;
}
}
initMap();
} else {
Toast.makeText(this, "This app requires location permissions for the map to show!", Toast.LENGTH_SHORT).show();
}
}
}
//run after onCreate method
@Override
protected void onResume() {
super.onResume();
startLocationUpdates();
}
@Override
protected void onPause() {
super.onPause();
stopLocationUpdate();
}
private void stopLocationUpdate() {
fusedLocationClient.removeLocationUpdates(locationCallback);
}
private void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null);
Log.i("startLocationUpdates", "started");
//looper at null ensures it calls on this thread
} else{
//request permissions again (for safety)
if (Build.VERSION.SDK_INT >= 23) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
}
}
}