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

Android API 21/22下定位无返回问题求助(非过时方案)

适配API 21/22的非过时Android定位方案

问题核心原因

  1. 权限逻辑缺失:API 21/22无需运行时权限,但必须在Manifest中声明定位权限且用户安装时授权,你的代码仅处理了API≥23的权限校验,低版本未做权限检查。
  2. LocationRequest兼容性问题:LocationRequest.Builder是Google Play Services Location 18.0.0新增API,API21/22设备的Play Services版本可能低于该版本,导致无法正常创建请求。
  3. 回调线程未指定:requestLocationUpdates最后一个参数传null,低版本系统中可能导致回调无法触发,需指定主线程Looper。

完整修正实现

1. 配置Manifest权限

确保AndroidManifest.xml中添加定位权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

2. 全版本权限校验逻辑

覆盖API21/22及更高版本的权限检查:

private boolean hasLocationPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        return ActivityCompat.checkSelfPermission(requireActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                || ActivityCompat.checkSelfPermission(requireActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
    } else {
        // API21/22 权限在安装时授予,直接检查应用是否已获得权限
        PackageManager pm = requireActivity().getPackageManager();
        return pm.checkPermission(Manifest.permission.ACCESS_FINE_LOCATION, requireActivity().getPackageName()) == PackageManager.PERMISSION_GRANTED
                || pm.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, requireActivity().getPackageName()) == PackageManager.PERMISSION_GRANTED;
    }
}

3. 兼容的LocationRequest创建方式

改用LocationRequest.create()替代LocationRequest.Builder,同时适配低版本不支持的API:

private static LocationRequest createLocationRequest() {
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(5000);
    locationRequest.setFastestInterval(2000);
    locationRequest.setMaxWaitTime(100);
    locationRequest.setNumUpdates(1);
    
    // setWaitForAccurateLocation是API26+新增,API21/22不支持
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        locationRequest.setWaitForAccurateLocation(true);
    }
    return locationRequest;
}

4. 修正后的定位请求代码

添加权限校验,指定主线程Looper确保回调触发:

if (!hasLocationPermission()) {
    Log.d("Location", "无法获取用户位置:权限未授权");
    return;
}

Log.d("Location", "正在请求用户位置...");
FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(requireActivity());
// 保存callback引用用于后续注销
LocationCallback locationCallback = new LocationCallback() {
    @Override
    public void onLocationResult(@NonNull LocationResult locationResult) {
        super.onLocationResult(locationResult);
        Location location = locationResult.getLastLocation();
        if (location != null) {
            Log.d("User location", location.toString());
            // 处理获取到的位置数据
        } else {
            Log.d("User location", "获取到的位置为空");
        }
    }

    @Override
    public void onLocationAvailability(@NonNull LocationAvailability locationAvailability) {
        super.onLocationAvailability(locationAvailability);
        if (!locationAvailability.isLocationAvailable()) {
            Log.d("Location", "当前位置不可用");
        }
    }
};

client.requestLocationUpdates(createLocationRequest(), locationCallback, Looper.getMainLooper());

5. 额外注意事项

  • Play Services依赖版本:使用兼容API21/22的版本,推荐添加:
    implementation 'com.google.android.gms:play-services-location:21.0.1'
    
  • 模拟器测试:API21/22模拟器需开启GPS功能,手动设置位置后可尝试重启定位服务;
  • 回调注销:在Fragment生命周期中及时注销请求,避免内存泄漏:
    @Override
    public void onStop() {
        super.onStop();
        if (locationCallback != null) {
            LocationServices.getFusedLocationProviderClient(requireActivity())
                    .removeLocationUpdates(locationCallback);
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 06:02:24