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
相关产品推荐
相关产品推荐

