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

如何修改MapsActivity实现位置随用户移动自动更新?

实现位置自动更新的修改方案

看起来你已经搭建好了基础的位置获取框架,但目前需要手动点击图标触发更新。要实现位置随用户移动自动更新,我们需要让应用持续监听位置变化,而不是仅在手动触发时获取一次位置。下面是具体的修改步骤和完整代码:

核心修改点

  • 在GoogleApiClient连接成功后,主动发起持续位置更新请求
  • 完善LocationRequest配置,确保位置变化能被及时捕获
  • 修复原代码中onLocationChanged方法的未完成错误
  • 优化生命周期管理,避免不必要的耗电

步骤1:配置LocationRequest参数

添加一个方法来初始化位置请求的规则,比如更新间隔、精度优先级等,平衡更新频率和耗电:

private void createLocationRequest() {
    locationRequest = LocationRequest.create();
    // 设置位置更新的间隔(毫秒),这里设为5秒
    locationRequest.setInterval(5000);
    // 设置最快更新间隔,避免系统频繁唤醒设备
    locationRequest.setFastestInterval(2000);
    // 设置高精度优先级,确保获取准确的位置数据
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

步骤2:在连接成功后启动位置监听

当GoogleApiClient连接完成时,调用requestLocationUpdates开始持续监听位置变化,同时初始化当前位置标记:

@Override
public void onConnected(@Nullable Bundle bundle) {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        // 先获取一次当前位置作为初始值
        lastLocation = LocationServices.FusedLocationApi.getLastLocation(client);
        if (lastLocation != null) {
            updateLocationMarker(lastLocation);
            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude()), 15));
        }
        // 启动持续位置更新监听
        LocationServices.FusedLocationApi.requestLocationUpdates(client, locationRequest, this);
    }
}

步骤3:修复并优化onLocationChanged方法

移除原代码中未完成的语句,提取标记更新逻辑为复用方法,避免重复代码:

@Override
public void onLocationChanged(Location location) {
    lastLocation = location;
    // 更新当前位置标记
    updateLocationMarker(location);
    // 可选:让地图跟随位置移动,不需要的话可以注释掉
    mMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude())));
}

// 单独提取标记更新方法,代码更整洁
private void updateLocationMarker(Location location) {
    if(currentLocationMarker != null){
        currentLocationMarker.remove();
    }
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
    MarkerOptions markerOptions = new MarkerOptions();
    markerOptions.position(latLng);
    markerOptions.title("Current Location");
    markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
    currentLocationMarker = mMap.addMarker(markerOptions);
}

步骤4:优化生命周期管理(推荐)

在Activity暂停时停止位置更新,恢复时重新启动,减少后台耗电:

@Override
protected void onPause() {
    super.onPause();
    if (client != null) {
        LocationServices.FusedLocationApi.removeLocationUpdates(client, this);
    }
}

@Override
protected void onResume() {
    super.onResume();
    if (client != null && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        LocationServices.FusedLocationApi.requestLocationUpdates(client, locationRequest, this);
    }
}

步骤5:在构建GoogleApiClient时初始化请求

确保在创建GoogleApiClient实例前初始化LocationRequest:

protected synchronized void buildGoogleApiClient(){
    createLocationRequest(); // 新增这行,初始化位置请求
    client = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    client.connect();
}

完整修改后的代码

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
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;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
    private GoogleMap mMap;
    private GoogleApiClient client;
    private LocationRequest locationRequest;
    private Location lastLocation;
    private Marker currentLocationMarker;
    public static final int REQUEST_LOCATION_CODE = 99;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            checkLocationPermission();
        }
        // 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);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch(requestCode) {
            case REQUEST_LOCATION_CODE:
                if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //permission is granted
                    if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        if(client == null){
                            buildGoogleApiClient();
                        }
                        mMap.setMyLocationEnabled(true);
                    }
                } else {
                    Toast.makeText(this, "Permission Denied!", Toast.LENGTH_LONG).show();
                    //Permission is denied
                }
                return;
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        Toast.makeText(this, "位置将自动跟随更新", Toast.LENGTH_LONG).show();
        mMap = googleMap;
        LatLng Phoenix = new LatLng(33.6056711, -112.4052378);
        mMap.addMarker(new MarkerOptions().position(Phoenix).title("Default Location: Phoenix, AZ"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(Phoenix));

        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            buildGoogleApiClient();
            mMap.setMyLocationEnabled(true);
        }
    }

    protected synchronized void buildGoogleApiClient(){
        createLocationRequest();
        client = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        client.connect();
    }

    private void createLocationRequest() {
        locationRequest = LocationRequest.create();
        locationRequest.setInterval(5000); // 5秒更新一次
        locationRequest.setFastestInterval(2000); // 最快2秒更新一次
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            lastLocation = LocationServices.FusedLocationApi.getLastLocation(client);
            if (lastLocation != null) {
                updateLocationMarker(lastLocation);
                mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude()), 15));
            }
            LocationServices.FusedLocationApi.requestLocationUpdates(client, locationRequest, this);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        // 连接暂停时重新尝试连接
        client.connect();
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Toast.makeText(this, "Google Play Services连接失败", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLocationChanged(Location location) {
        lastLocation = location;
        updateLocationMarker(location);
        // 可选:取消注释可以让地图跟随位置移动
        mMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude())));
    }

    private void updateLocationMarker(Location location) {
        if(currentLocationMarker != null){
            currentLocationMarker.remove();
        }
        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
        markerOptions.title("Current Location");
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
        currentLocationMarker = mMap.addMarker(markerOptions);
    }

    public boolean checkLocationPermission(){
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_CODE);
            return false;
        }
        return true;
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (client != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(client, this);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (client != null && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(client, locationRequest, this);
        }
    }
}

额外说明

  • 现在应用启动后会自动连接GoogleApiClient,并持续监听位置变化,新位置获取后标记会自动更新
  • 你可以调整locationRequest.setInterval和setFastestInterval的数值,根据需求平衡更新频率与耗电
  • 如果不需要地图自动跟随移动,注释掉onLocationChanged中的mMap.moveCamera语句即可

内容的提问来源于stack exchange,提问作者Tanner Tattini

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:24:44