使用Firebase Auth的Android应用获取经纬度报错,RecyclerView正常
LocationRequest实例化报错的问题 看起来你在使用旧版Google位置服务API时,碰到了mLocationRequest = new LocationRequest();的报错——结合你的ListOnline类已经实现了GoogleApiClient.ConnectionCallbacks等相关接口,我来帮你梳理几个最常见的解决方向:
1. 确认位置服务依赖是否正确配置
首先检查你的**Module级build.gradle**里是否添加了正确的位置服务依赖,版本要和你的项目compileSdkVersion适配:
dependencies { // 确保添加该依赖,版本可根据项目调整,比如21.0.1是较新的稳定版 implementation 'com.google.android.gms:play-services-location:21.0.1' }
如果依赖缺失或者版本过低,会直接导致LocationRequest类无法找到或初始化失败。
2. 检查Manifest权限配置
获取位置信息必须在AndroidManifest.xml中声明必要权限,同时Android 6.0+还需要动态申请权限:
<!-- 精确定位权限(优先用这个) --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 粗略定位权限(备选) --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Android 10+如需后台定位,需添加这个 --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <!-- 声明应用使用GPS硬件(可选,标记为非强制) --> <uses-feature android:name="android.hardware.location.gps" android:required="false" />
没有权限的话,哪怕代码逻辑正确,位置服务也无法正常工作。
3. 适配LocationRequest的初始化方式
从Google Play Services Location 12.0.0版本开始,new LocationRequest()构造方法已被废弃,官方推荐用LocationRequest.create()或Builder模式创建实例:
// 简洁的创建方式 mLocationRequest = LocationRequest.create(); // 或者用Builder灵活配置参数(推荐,可自定义精度、更新间隔等) mLocationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 10000) .setWaitForAccurateLocation(false) .setMinUpdateIntervalMillis(5000) .setMaxUpdateDelayMillis(10000) .build();
如果你的依赖版本较新,直接调用旧构造方法必然会报错,改用上面的方式就能解决。
4. 检查GoogleApiClient的完整初始化流程
确保你正确初始化了GoogleApiClient,并且仅在onConnected回调完成后才去初始化LocationRequest和请求位置更新:
private GoogleApiClient mGoogleApiClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_online); // 初始化GoogleApiClient,绑定位置服务API mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } @Override protected void onStart() { super.onStart(); // 启动时连接GoogleApiClient mGoogleApiClient.connect(); } @Override protected void onStop() { super.onStop(); // 停止时断开连接并移除位置更新监听 if (mGoogleApiClient.isConnected()) { LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); mGoogleApiClient.disconnect(); } } @Override public void onConnected(@Nullable Bundle bundle) { // 连接成功后再处理位置请求逻辑 mLocationRequest = LocationRequest.create(); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRequest.setInterval(10000); // 10秒更新一次 mLocationRequest.setFastestInterval(5000); // 最快5秒更新一次 // 先检查权限,再请求位置更新 if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); } }
如果GoogleApiClient还没连接成功就去操作LocationRequest,很容易触发异常。
额外建议:考虑迁移到新版Fused Location Provider
旧的GoogleApiClient方式已经被逐步淘汰,Google推荐使用**FusedLocationProviderClient**来实现位置获取——代码更简洁,稳定性也更好:
private FusedLocationProviderClient fusedLocationClient; private LocationCallback locationCallback; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_online); // 初始化FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(this); // 初始化位置回调,用于接收位置更新 locationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { if (locationResult == null) return; for (Location location : locationResult.getLocations()) { // 成功获取纬度和经度 double latitude = location.getLatitude(); double longitude = location.getLongitude(); // 这里可以将坐标上传到Firebase或更新UI } } }; } // 发起位置更新请求的方法 private void startLocationUpdates() { LocationRequest locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setInterval(10000); // 检查设备位置设置是否满足要求(比如是否开启GPS) LocationSettingsRequest.Builder settingsBuilder = new LocationSettingsRequest.Builder() .addLocationRequest(locationRequest); SettingsClient settingsClient = LocationServices.getSettingsClient(this); Task<LocationSettingsResponse> settingsTask = settingsClient.checkLocationSettings(settingsBuilder.build()); settingsTask.addOnSuccessListener(response -> { // 位置设置符合要求,开始请求更新(先检查权限) if (ContextCompat.checkSelfPermission(ListOnline.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()); } }); settingsTask.addOnFailureListener(e -> { // 位置设置不满足,比如GPS未开启,引导用户开启 if (e instanceof ResolvableApiException) { try { ResolvableApiException resolvableEx = (ResolvableApiException) e; resolvableEx.startResolutionForResult(ListOnline.this, 1001); // 请求码自定义 } catch (IntentSender.SendIntentException ignored) {} } }); }
迁移到新版API能避免旧API的兼容性问题,也更符合Google的最新开发规范。
你可以先从检查依赖和权限入手,再调整LocationRequest的初始化方式,应该就能解决报错问题了。
内容的提问来源于stack exchange,提问作者Pilojan Siva

