安卓获取当前地理位置(基于GPS和网络)
2023-09-27 14:27:30 时间
背景
安卓开发经常需要获取地理位置,所以对获取地理位置做了下整理,方便大家使用。
解决方案:
- Manifest文件添加权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
- 添加依赖
implementation "com.google.code.gson:gson:2.8.5"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1"
implementation "org.jetbrains.kotlinx:kotlinx
implementation 'com.afollestad:assent:2.3.1'
- 主要代码:
LocationUtils.kt
object LocationUtils {
private val TAG = LocationUtils::class.java.simpleName
/**
* 获取地理位置,先根据GPS获取,再根据网络获取
*
* @return
*/
@SuppressLint("MissingPermission")
fun getLocation(context: Context, callback: Callback) {
val locationListener: LocationListener = getLocationListener(callback)
try {
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { //从gps获取经纬度
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, locationListener)
} else {//从网络获取经纬度
getLocationByNetwork(context, callback)
}
} catch (e: Exception) {
Log.e(TAG, e.message)
}
}
private fun getLocationListener(callback: Callback): LocationListener {
return object : LocationListener {
// Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {
Log.d(TAG, "onStatusChanged")
}
// Provider被enable时触发此函数,比如GPS被打开
override fun onProviderEnabled(provider: String) {
Log.d(TAG, "onProviderEnabled")
}
// Provider被disable时触发此函数,比如GPS被关闭
override fun onProviderDisabled(provider: String) {
Log.d(TAG, "onProviderDisabled")
}
//当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发
override fun onLocationChanged(location: Location) {
callback.onLocationChanged(location)
}
}
}
/**
* 判断是否开启了GPS或网络定位开关
*
* @return
*/
fun isLocationProviderEnabled(context: Context): Boolean {
var result = false
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
|| locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
result = true
}
return result
}
/**
* 获取地理位置,先根据GPS获取,再根据网络获取
*
* @return
*/
@SuppressLint("MissingPermission")
private fun getLocationByNetwork(context: Context, callback: Callback) {
val locationListener: LocationListener = getLocationListener(callback)
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
try {
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0f, locationListener)
}
} catch (e: Exception) {
Log.e(TAG, e.message)
}
}
}
interface Callback {
fun onLocationChanged(location: Location)
}
调用样例(Kotlin):
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
locateBtn.setOnClickListener { locate() }
}
private fun locate() {
locationTv.text = ""
runWithPermissions(Permission.ACCESS_FINE_LOCATION) {
if (LocationUtils.isLocationProviderEnabled(this@MainActivity)) {
progressBar.visibility = VISIBLE
showLocationWithToast()
} else {
showAlert("本应用需要获取地理位置,请打开获取位置的开关", this)
}
}
}
private fun showLocationWithToast() {
LocationUtils.getLocation(this@MainActivity, object : Callback {
override fun onLocationChanged(location: Location) {
onGetLocation(location)
}
})
}
private fun onGetLocation(location: Location) {
GlobalScope.launch(Dispatchers.IO) {
val result = getAddressInfo(location)
launch(Dispatchers.Main) {
result?.let {
locationTv.text = it.toString()
progressBar.visibility = GONE
}
}
}
}
}
备注
- 上面代码中使用了第三方库assent来动态申请权限
- 采用了coroutines来执行异步任务
- 采用了百度web api来根据地理位置查询地址信息(ak需要自己申请)
效果图:
Demo源代码
https://gitee.com/hspbc/geolocationDemo/tree/master/demo
关于我
厦门大学计算机专业 | 前华为工程师
Java | 安卓 | 前端 | 小程序 | 鸿蒙
公众号:蓝不蓝编程
相关文章
- 安卓逆向_18 --- APK保护策略【Java代码混淆、资源混淆、签名校验】
- 安卓数据库开发helper
- 我的Android前生今世之缘-学习经验-安卓入门教程(六)
- 《移动安全》(1)Android开发基础:安卓操作系统架构与应用程序组件
- 安卓集成新版推送SDK与旧版本账号SDK发生依赖冲突,如何解决?
- 一种恶意程序专门攻击安卓
- 安卓apk版本检测下载升级全过程
- 都是权限惹的祸:安卓恶意APP如何将其他APP中的私有数据搞到手
- 安卓APP应用在各大应用市场上架方法整理
- 安卓手机自动化测试工具是什么
- 获取安卓应用的版本
- 你的智能设备安全吗?360透视镜可全面检测安卓设备漏洞
- 安卓开发笔记(二十二):读取本地(内置)html文件并实现和Javascript交互
- 安卓开发学习笔记(八):线性布局
- 受够了碎片化,Salesforce决定只支持部分安卓设备
- Check Point:中国黑客利用伪基站传播安卓银行木马