Android中如何用SharedPreference保存并替换LatLng位置以获取最新值?
没问题,这需求在Android开发里挺常见的,我给你一步步拆解实现思路和代码示例,保证清晰好懂:
1. 封装SharedPreference工具类
SharedPreference本身不能直接存储LatLng对象,我们需要把它转换成可存储的类型(比如拆分经纬度为浮点值,或者用Gson转成JSON字符串)。这里提供两种常用方案:
方案1:拆分经纬度存储(无需额外依赖)
这种方式简单直接,适合不需要复杂对象存储的场景:
class LocationPreferenceHelper(context: Context) { // 定义SharedPreference实例和存储键 private val sharedPref = context.getSharedPreferences("LocationPrefs", Context.MODE_PRIVATE) private val KEY_LATITUDE = "saved_latitude" private val KEY_LONGITUDE = "saved_longitude" // 保存/更新位置(更新其实就是覆盖旧值,所以和保存逻辑一致) fun saveOrUpdateLocation(latLng: LatLng) { sharedPref.edit() .putFloat(KEY_LATITUDE, latLng.latitude.toFloat()) .putFloat(KEY_LONGITUDE, latLng.longitude.toFloat()) .apply() // 异步提交,避免阻塞主线程 } // 获取最新保存的位置,返回null表示从未保存过 fun getSavedLocation(): LatLng? { val savedLat = sharedPref.getFloat(KEY_LATITUDE, Float.MIN_VALUE) val savedLng = sharedPref.getFloat(KEY_LONGITUDE, Float.MIN_VALUE) return if (savedLat != Float.MIN_VALUE && savedLng != Float.MIN_VALUE) { LatLng(savedLat.toDouble(), savedLng.toDouble()) } else { null } } }
方案2:用Gson转JSON存储(适合复杂对象)
如果后续需要存储更多位置相关信息,用JSON序列化更灵活,需要先添加Gson依赖:
// 在app模块的build.gradle中添加 implementation 'com.google.code.gson:gson:2.10.1'
然后实现工具类:
class LocationPreferenceHelper(context: Context) { private val sharedPref = context.getSharedPreferences("LocationPrefs", Context.MODE_PRIVATE) private val KEY_LATLNG_JSON = "saved_latlng_json" private val gson = Gson() fun saveOrUpdateLocation(latLng: LatLng) { val latLngJson = gson.toJson(latLng) sharedPref.edit() .putString(KEY_LATLNG_JSON, latLngJson) .apply() } fun getSavedLocation(): LatLng? { val savedJson = sharedPref.getString(KEY_LATLNG_JSON, null) return savedJson?.let { gson.fromJson(it, LatLng::class.java) } } }
2. 处理GPS位置更新并同步到SharedPreference
接下来需要在获取到新的GPS位置时,调用工具类的更新方法。这里推荐用Google的Fused Location Provider API(比原生LocationManager更稳定高效):
class MainActivity : AppCompatActivity() { private lateinit var locationPreferenceHelper: LocationPreferenceHelper private lateinit var fusedLocationClient: FusedLocationProviderClient private lateinit var locationCallback: LocationCallback override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 初始化工具类 locationPreferenceHelper = LocationPreferenceHelper(this) // 初始化FusedLocationClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) // 配置位置请求参数 val locationRequest = LocationRequest.create().apply { priority = LocationRequest.PRIORITY_HIGH_ACCURACY // 高精度定位 interval = 10000 // 10秒更新一次(根据需求调整) fastestInterval = 5000 // 最快更新间隔 } // 定义位置回调,获取到新位置时更新SharedPreference locationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult) { super.onLocationResult(locationResult) locationResult.lastLocation?.let { location -> val newLatLng = LatLng(location.latitude, location.longitude) // 同步更新到SharedPreference locationPreferenceHelper.saveOrUpdateLocation(newLatLng) // 这里可以添加UI刷新等逻辑 Log.d("LocationUpdate", "新位置已保存:${newLatLng.latitude}, ${newLatLng.longitude}") } } } } override fun onStart() { super.onStart() // 检查定位权限,申请通过后开始请求位置更新 if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()) } else { // 动态申请定位权限 ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 1001) } } override fun onStop() { super.onStop() // 停止位置更新,避免后台耗电 fusedLocationClient.removeLocationUpdates(locationCallback) } // 处理权限申请结果 override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == 1001 && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限通过后开始请求位置更新 fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()) } } }
3. 获取最新保存的位置
在任何需要的地方(比如启动APP时恢复位置),调用工具类的getSavedLocation()方法即可:
val savedLocation = locationPreferenceHelper.getSavedLocation() savedLocation?.let { // 存在已保存的位置,做后续处理(比如显示地图标记) Log.d("SavedLocation", "最新保存的位置:${it.latitude}, ${it.longitude}") } ?: run { // 没有保存过位置,提示用户或触发首次定位 Log.d("SavedLocation", "未找到已保存的位置") }
关键注意事项
- 权限处理:务必在
AndroidManifest.xml中添加定位权限,并动态申请:
Android 10及以上如果需要后台定位,还需添加<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />ACCESS_BACKGROUND_LOCATION权限。 - 空值判断:获取保存的位置时一定要判断是否为null,避免空指针异常。
- 性能优化:根据业务需求调整位置更新的间隔,避免过于频繁的定位导致耗电过快。
- 多进程场景:如果你的APP是多进程架构,
MODE_PRIVATE的SharedPreference可能无法共享数据,建议改用ContentProvider或其他跨进程存储方案。
内容的提问来源于stack exchange,提问作者user9706969
相关产品推荐
相关产品推荐

