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

Android Java:静态上下文下如何避免用Listener获取最后用户位置

问题描述

我想要获取last user's position(最后用户位置),但当前处于静态上下文环境中。

相关代码:

public void getLastKnownLocation() {
    FusedLocationProviderClient fusedLocationClient = LocationServices.
            getFusedLocationProviderClient(App.getContext());

    fusedLocationClient.getLastLocation()
            .addOnSuccessListener(**activity_needed_here**, new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    // Got last known location. In some rare situations this can be null.
                    if (location != null) {
                        System.out.println("Speed is " + location.getSpeed());
                    }
                }
            });
}

问题在于我处于静态上下文,无法传入Activity对象,但可以访问app context(应用上下文)。请问如何避免使用addOnSuccessListener,或是如何在静态上下文中实现该功能?


解决方案

方案1:用同步方式替代异步回调

getLastLocation()返回的Task<Location>支持同步等待结果,用Tasks.await()就能跳过addOnSuccessListener。注意必须在子线程调用,避免阻塞主线程:

public static Location getLastKnownLocationSync() {
    FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(App.getContext());
    try {
        // 设置5秒超时,可根据需求调整
        return Tasks.await(fusedLocationClient.getLastLocation(), 5, TimeUnit.SECONDS);
    } catch (ExecutionException | InterruptedException | TimeoutException e) {
        e.printStackTrace();
        return null;
    }
}

调用示例(必须在子线程执行):

new Thread(() -> {
    Location location = getLastKnownLocationSync();
    if (location != null) {
        System.out.println("Speed is " + location.getSpeed());
    }
}).start();

方案2:使用无需Activity的异步回调重载

其实addOnSuccessListener有不需要Activity的版本,不用绑定生命周期,直接传监听器即可。你之前的代码误用了需要Activity的重载,静态上下文里可以直接用无Activity参数的版本:

public static void getLastKnownLocationAsync() {
    FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(App.getContext());

    fusedLocationClient.getLastLocation()
            .addOnSuccessListener(new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    if (location != null) {
                        System.out.println("Speed is " + location.getSpeed());
                    }
                }
            })
            .addOnFailureListener(e -> e.printStackTrace());
}

这种方式直接用App Context发起请求,回调会在后台线程执行,如果要更新UI,记得切换回主线程。

关键注意点

  • 必须确保已申请并获得位置权限(ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION),否则请求会失败。
  • getLastLocation()可能返回null(比如设备从未获取过位置、位置服务关闭等),必须做null判断。
  • 同步方式绝对不能在主线程调用,否则会触发ANR。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:51:00