Android中替代FusedLocation获取用户位置的Java代码求助
不依赖FusedLocation的Android位置获取解决方案(Java)
你的原代码仅依赖GPS_PROVIDER的getLastKnownLocation方法,该方法只能获取缓存位置——如果GPS从未开启或无缓存数据,就会返回null。同时代码缺少权限请求后的回调处理,也未检查定位服务是否开启,这些都是导致获取失败的核心原因。
以下是完整的可运行实现:
步骤1:配置AndroidManifest.xml
添加必要权限与服务声明:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Android 12+ 后台定位权限(按需添加) --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" android:maxSdkVersion="33" /> <!-- 声明定位硬件依赖(非强制) --> <uses-feature android:name="android.hardware.location.gps" android:required="false" /> <uses-feature android:name="android.hardware.location.network" android:required="false" />
步骤2:完整MainActivity代码
package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import android.Manifest; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.provider.Settings; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements LocationListener { private Button getLocationBtn; private LocationManager locationManager; private static final int LOCATION_PERMISSION_REQUEST_CODE = 100; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getLocationBtn = findViewById(R.id.getLocationBTN); locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); getLocationBtn.setOnClickListener(v -> requestLocationUpdates()); } private void requestLocationUpdates() { // 检查定位权限 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE); return; } // 检查GPS/网络定位服务是否开启 boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (!isGpsEnabled && !isNetworkEnabled) { Toast.makeText(this, "请开启定位服务", Toast.LENGTH_SHORT).show(); startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)); return; } // 同时监听网络(快速获取)和GPS(高精度)定位 if (isNetworkEnabled) { locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 10, this); } if (isGpsEnabled) { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10, this); } // 先尝试获取缓存的最近位置 Location lastKnownLocation = getLastBestLocation(); if (lastKnownLocation != null) { showLocation(lastKnownLocation); } else { Toast.makeText(this, "正在获取位置,请稍候...", Toast.LENGTH_SHORT).show(); } } private Location getLastBestLocation() { Location gpsLocation = null; Location networkLocation = null; if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return null; } if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); } if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } // 返回更新的位置(GPS优先级更高) if (gpsLocation != null && networkLocation != null) { return gpsLocation.getTime() > networkLocation.getTime() ? gpsLocation : networkLocation; } else { return gpsLocation != null ? gpsLocation : networkLocation; } } @Override public void onLocationChanged(Location location) { // 获取到实时位置后展示,并停止监听节省电量 showLocation(location); locationManager.removeUpdates(this); } @Override public void onProviderEnabled(String provider) { Toast.makeText(this, provider + " 已开启", Toast.LENGTH_SHORT).show(); } @Override public void onProviderDisabled(String provider) { Toast.makeText(this, provider + " 已关闭", Toast.LENGTH_SHORT).show(); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // 可选处理定位服务状态变化 } private void showLocation(Location location) { double latitude = location.getLatitude(); double longitude = location.getLongitude(); String provider = location.getProvider(); Toast.makeText(this, String.format("位置获取成功\n纬度: %.6f\n经度: %.6f\n来源: %s", latitude, longitude, provider), Toast.LENGTH_LONG).show(); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { requestLocationUpdates(); } else { Toast.makeText(this, "需要定位权限才能获取位置", Toast.LENGTH_SHORT).show(); } } } @Override protected void onDestroy() { super.onDestroy(); // 销毁时移除监听,避免内存泄漏 if (locationManager != null) { locationManager.removeUpdates(this); } } }
核心改进点
- 权限闭环处理:添加权限请求回调,确保权限授予后自动重试位置获取
- 服务状态检测:检测定位服务是否开启,未开启时引导用户进入设置页面
- 多源定位兼容:同时支持网络定位(快速)和GPS定位(高精度),优先返回最新位置
- 实时位置监听:不再依赖缓存位置,通过
LocationListener获取实时更新 - 资源自动清理:Activity销毁时移除位置监听,避免不必要的电量消耗
内容的提问来源于stack exchange,提问作者Aryan Shinde
相关产品推荐
相关产品推荐

