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

Android设备经纬度获取求助:已编写LocationListener及基站定位代码

解决Android设备获取经纬度的问题

首先得明确:你当前用的http://www.google.com/glm/mmap接口早就被Google废弃了,这就是这个基站定位方案完全无效的核心原因。别再死磕这个旧接口了,咱们改用Android官方推荐的现代定位方案,结合你已经写好的LocationListener来实现,步骤如下:

一、迁移到Fused Location Provider(官方推荐)

Fused Location Provider是Google Play Services提供的定位库,它会自动整合GPS、基站、WiFi等多种定位源,精度和稳定性都远胜旧方案,也是现在Android开发的标准做法。

1. 添加依赖

在你的app模块的build.gradle(注意是Module级别的,不是Project级)里添加定位库依赖:

dependencies {
    implementation 'com.google.android.gms:play-services-location:21.0.1'
}

2. 处理运行时权限

从Android 6.0(API 23)开始,ACCESS_FINE_LOCATION这类定位权限属于危险权限,必须在运行时主动申请,只在Manifest里声明是没用的。在MainActivity里加上权限申请逻辑:

private static final int REQUEST_LOCATION_PERMISSION = 100;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main); // 记得绑定你的布局文件

    // 先检查定位权限是否已获取
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        // 权限未获取,发起申请
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                REQUEST_LOCATION_PERMISSION);
    } else {
        // 权限已就绪,开始获取定位
        startLocationUpdates();
    }
}

// 处理权限申请的回调结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_LOCATION_PERMISSION) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            startLocationUpdates();
        } else {
            Toast.makeText(this, "需要授予定位权限才能获取位置信息", Toast.LENGTH_SHORT).show();
        }
    }
}

3. 整合你的LocationListener实现定位更新

把你写的LocationListener和Fused Location Provider结合起来,实现真正的定位逻辑:

private FusedLocationProviderClient mFusedLocationClient;
private LocationRequest mLocationRequest;

// 保留你原来的LocationListener,补充逻辑
private final LocationListener mLocationListener = new LocationListener() {
    @Override
    public void onLocationChanged(final Location location) {
        // 在这里拿到精准的经纬度(double类型,保留小数精度)
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();
        Log.e(TAG, "当前纬度:" + latitude + ",当前经度:" + longitude);
        
        // 如果只需要一次定位结果,拿到后可以停止更新
        mFusedLocationClient.removeLocationUpdates(mLocationListener);
    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {}

    @Override
    public void onProviderEnabled(String s) {}

    @Override
    public void onProviderDisabled(String s) {}
};

private void startLocationUpdates() {
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    
    // 配置定位请求参数
    mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // 高精度模式(优先GPS)
    mLocationRequest.setInterval(5000); // 定位更新间隔(毫秒)
    mLocationRequest.setFastestInterval(2000); // 最快更新间隔(应对紧急情况)

    // 检查设备定位设置是否符合要求
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(mLocationRequest);
    SettingsClient client = LocationServices.getSettingsClient(this);
    Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());

    task.addOnSuccessListener(this, locationSettingsResponse -> {
        // 定位设置正常,开始请求位置更新
        try {
            mFusedLocationClient.requestLocationUpdates(mLocationRequest,
                    mLocationListener,
                    Looper.getMainLooper());
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    });

    task.addOnFailureListener(this, e -> {
        if (e instanceof ResolvableApiException) {
            // 定位设置未开启,引导用户跳转到系统设置打开
            try {
                ResolvableApiException resolvable = (ResolvableApiException) e;
                resolvable.startResolutionForResult(MainActivity.this, 101);
            } catch (IntentSender.SendIntentException sendEx) {
                sendEx.printStackTrace();
            }
        } else {
            Toast.makeText(this, "无法获取定位,请检查系统定位设置", Toast.LENGTH_SHORT).show();
        }
    });
}

// 处理定位设置跳转的结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 101) {
        if (resultCode == RESULT_OK) {
            startLocationUpdates();
        } else {
            Toast.makeText(this, "未开启定位设置,无法获取位置", Toast.LENGTH_SHORT).show();
        }
    }
}

二、你原有代码的其他明显问题

就算暂时不想用官方方案,你原来的代码还有两个致命问题:

  • myLatitude和myLongitude定义成了int类型,但经纬度是带小数的数值(比如39.9042),用int会直接丢失精度,必须改成double类型。
  • 旧的Google mmap接口已经彻底失效,没有任何办法再通过它获取基站定位数据,必须放弃。

三、Manifest配置补充

除了你已经添加的权限,还可以加上定位特性声明(可选,但能帮助Google Play过滤不支持定位的设备):

<uses-feature
    android:name="android.hardware.location.gps"
    android:required="false" />
<uses-feature
    android:name="android.hardware.location.network"
    android:required="false" />

最后提醒:测试定位功能一定要用真机,模拟器的定位数据要么不准确,要么根本无法获取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:46:17