You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,步骤如下:

  1. 在Google Cloud Console启用Places API,并获取API密钥(和你的Maps API密钥可以共用)
  2. 在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密钥" />
  1. 添加附近地点查询方法,比如查询附近的餐厅:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 03:32:30