GoogleApiClient已废弃:Android地图项目中GoogleSignInOptions的正确实现方案求助
解决GoogleApiClient废弃问题并实现Android地图附近地点显示
嘿,我发现你混淆了一个关键概念——GoogleSignInOptions是用来处理Google账号登录的,和位置服务完全不相关!你之前的错误就是把它当成了GoogleApiClient的替代方案,这才引发了一堆问题。别担心,咱们一步步来修改代码,既替换掉废弃的位置服务API,又保留现有可运行的地图功能,还能为实现附近地点铺路。
核心替换方案:用FusedLocationProviderClient替代GoogleApiClient
Google早已废弃了GoogleApiClient用于位置服务的用法,现在推荐使用FusedLocationProviderClient——这是一个更简洁、更易维护的现代位置服务API,不需要手动管理连接状态。
第一步:添加必要的依赖
确保你的app/build.gradle(Module级别)里包含以下依赖:
implementation 'com.google.android.gms:play-services-location:21.0.1' implementation 'com.google.android.gms:play-services-maps:18.1.0' // 如果要实现附近地点,还需要添加Places API依赖 implementation 'com.google.android.libraries.places:places:3.3.0'
第二步:修改完整代码(保留原有地图功能)
下面是修改后的代码,我保留了你原来的地图初始化逻辑,只替换了废弃的位置服务部分:
import android.Manifest; import android.content.pm.PackageManager; import android.location.Location; import android.os.Bundle; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import com.google.android.gms.location.FusedLocationProviderClient; import com.google.android.gms.location.LocationCallback; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationResult; 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.LatLng; import com.google.android.gms.maps.model.MarkerOptions; import android.os.Looper; public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback { private GoogleMap mMap; private FusedLocationProviderClient fusedLocationClient; private LocationRequest locationRequest; private LocationCallback locationCallback; private double currentLatitude, currentLongitude; private Location myLocation; private final static int REQUEST_ID_MULTIPLE_PERMISSIONS = 0x2; @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); // 初始化现代位置服务客户端 fusedLocationClient = LocationServices.getFusedLocationProviderClient(this); setupLocationRequest(); setupLocationCallback(); checkPermissionsAndStartLocationUpdates(); } // 配置位置更新的参数(精度、更新间隔等) private void setupLocationRequest() { locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setInterval(10000); // 每10秒更新一次位置 locationRequest.setFastestInterval(5000); // 最快5秒更新一次 } // 定义位置更新的回调,获取到新位置时触发 private void setupLocationCallback() { locationCallback = new LocationCallback() { @Override public void onLocationResult(@NonNull LocationResult locationResult) { super.onLocationResult(locationResult); if (locationResult.getLastLocation() != null) { myLocation = locationResult.getLastLocation(); currentLatitude = myLocation.getLatitude(); currentLongitude = myLocation.getLongitude(); // 更新地图上的当前位置标记 updateCurrentLocationOnMap(); // 获取到位置后,就可以调用附近地点查询方法了 // fetchNearbyPlaces(currentLatitude, currentLongitude); } } }; } // 检查位置权限,通过后开始获取位置 private void checkPermissionsAndStartLocationUpdates() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { // 权限已授予,请求位置更新 fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()); // 同时获取一次最近的已知位置(避免首次启动等待更新) fusedLocationClient.getLastLocation().addOnSuccessListener(this, location -> { if (location != null) { myLocation = location; currentLatitude = location.getLatitude(); currentLongitude = location.getLongitude(); updateCurrentLocationOnMap(); } }); } else { // 请求位置权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_ID_MULTIPLE_PERMISSIONS); } } // 在地图上标记当前位置 private void updateCurrentLocationOnMap() { if (mMap != null) { LatLng currentLatLng = new LatLng(currentLatitude, currentLongitude); mMap.addMarker(new MarkerOptions().position(currentLatLng).title("我的位置")); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15)); } } @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; // 保留你原来的地图初始化逻辑(比如设置地图类型) mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); // 如果已经获取到位置,立即更新地图 if (myLocation != null) { updateCurrentLocationOnMap(); } } // 处理权限请求结果 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_ID_MULTIPLE_PERMISSIONS) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { checkPermissionsAndStartLocationUpdates(); } else { Toast.makeText(this, "需要位置权限才能获取附近地点", Toast.LENGTH_SHORT).show(); } } } // 页面暂停时停止位置更新,节省电量 @Override protected void onPause() { super.onPause(); fusedLocationClient.removeLocationUpdates(locationCallback); } // 页面恢复时重新开始位置更新 @Override protected void onResume() { super.onResume(); if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()); } } }
关键修改说明
- 移除了废弃的
GoogleApiClient及相关回调接口,替换为FusedLocationProviderClient - 用
LocationCallback接收位置更新,替代原来的ConnectionCallbacks - 修复了
if (mGoogleApiClient.isConnected())的错误:FusedLocationProviderClient不需要手动检查连接状态,只需确保权限通过即可请求位置 - 保留了所有原有地图相关代码,确保地图功能正常运行
第三步:实现附近地点显示
要显示附近地点,需要使用Google Places API,步骤如下:
- 在Google Cloud Console启用Places API,并获取API密钥(和你的Maps API密钥可以共用)
- 在
AndroidManifest.xml中添加API密钥和必要权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> <meta-data android:name="com.google.android.geo.API_KEY" android:value="你的API密钥" />
- 添加附近地点查询方法,比如查询附近的餐厅:
import com.google.android.libraries.places.api.Places; import com.google.android.libraries.places.api.model.Place; import com.google.android.libraries.places.api.model.PlaceTypes; import com.google.android.libraries.places.api.model.LatLngBounds; import com.google.android.libraries.places.api.net.SearchNearbyRequest; import com.google.android.libraries.places.api.net.PlacesClient; // ... 其他代码 ... private void fetchNearbyPlaces(double lat, double lng) { // 初始化Places客户端 if (!Places.isInitialized()) { Places.initialize(getApplicationContext(), "你的API密钥"); } PlacesClient placesClient = Places.createClient(this); // 定义查询范围(以当前位置为中心,0.01度约1公里) LatLngBounds bounds = new LatLngBounds( new LatLng(lat - 0.01, lng - 0.01), new LatLng(lat + 0.01, lng + 0.01) ); // 构建查询请求,比如查询附近的餐厅 SearchNearbyRequest request = SearchNearbyRequest.builder(bounds, PlaceTypes.RESTAURANT).build(); // 发起查询 placesClient.searchNearby(request).addOnSuccessListener(response -> { for (Place place : response.getPlaces()) { // 在地图上添加地点标记 LatLng placeLatLng = new LatLng(place.getLatLng().latitude(), place.getLatLng().longitude()); mMap.addMarker(new MarkerOptions() .position(placeLatLng) .title(place.getDisplayName()) .snippet(place.getAddress())); } }).addOnFailureListener(e -> { Toast.makeText(this, "获取附近地点失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); }); }
然后在updateCurrentLocationOnMap()方法中调用fetchNearbyPlaces(currentLatitude, currentLongitude)即可。
这样修改后,你既解决了废弃API的问题,保留了原有地图功能,又能正常获取当前位置并显示附近地点啦!如果还有细节问题,随时提问~
内容的提问来源于stack exchange,提问作者Caitlin
相关产品推荐
相关产品推荐

