Android 定位 获取当前位置 (Kotlin)

导入:

复制代码
implementation 'com.google.android.gms:play-services-location:21.3.0'

头文件:

复制代码
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
import com.google.android.gms.tasks.CancellationTokenSource
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import android.os.Looper
import androidx.core.app.ActivityCompat

代码实现:

复制代码
private val PLAY_SERVICES_RESOLUTION_REQUEST = 9000
private var fusedLocationClient: FusedLocationProviderClient? = null

1.requestLocationUpdates:持续获取定位,根据更新间隔和最快频率

复制代码
fusedLocationClient = LocationServices.getFusedLocationProviderClient(thisContext!!)
if (ActivityCompat.checkSelfPermission(
        thisContext!!,
        Manifest.permission.ACCESS_FINE_LOCATION
    ) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
        thisContext!!,
        Manifest.permission.ACCESS_COARSE_LOCATION
    ) == PackageManager.PERMISSION_GRANTED
) {
    val locationRequest: LocationRequest = LocationRequest.create()
    locationRequest.interval = 2000 // 更新间隔,例如10秒
    locationRequest.fastestInterval = 5000 // 最快频率,例如5秒
    locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    fusedLocationClient!!.requestLocationUpdates(
        locationRequest,
        object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                if (locationResult == null) {
                    LogUtils.d("requestLocationUpdates locationResult == null")
                    return
                }
                for (location in locationResult.locations) {
                    var latitude = location.latitude.toString()
                    var longitude = location.longitude.toString()
                    if (latitude.contains(".")) {
                        latitude = subString(latitude)
                    }
                    if (longitude.contains(".")) {
                        longitude = subString(longitude)
                    }
                    LogUtils.d("requestLocationUpdates onLocationResult latitude = $latitude  longitude = $longitude")
                }
            }
        },
        Looper.myLooper()
    )
}

2.getCurrentLocation:获取一次定位

复制代码
private fun startLocation() {
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    if (ActivityCompat.checkSelfPermission(
            this,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
            this,
            Manifest.permission.ACCESS_COARSE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
    ) {
        LogUtils.d("fusedLocationClient Ok")
        val priority = Priority.PRIORITY_BALANCED_POWER_ACCURACY
        val cancellationTokenSource = CancellationTokenSource()
        val cancellationToken = cancellationTokenSource.token
        fusedLocationClient.getCurrentLocation(
            priority,
            cancellationToken
        )
            .addOnSuccessListener(
                this
            ) { location ->
                if (location != null) {
                    val latitude = location.latitude
                    val longitude = location.longitude
                    LogUtils.d("fusedLocationClient latitude = $latitude  longitude = $longitude")
                } else {
                    LogUtils.d("fusedLocationClient location = null")
                }
            }
            .addOnFailureListener { exception ->
                LogUtils.d("fusedLocationClient exception = $exception")

            }
    }
}
复制代码
//上面方法中 addOnFailureListener 报错如下:
//com.google.android.gms.common.api.ApiException: 17: API: LocationServices.API is not available on this device. Connection failed with: ConnectionResult{statusCode=SERVICE_INVALID, resolution=null, message=null}
//如发生这个错误,可能是当前手机设备没有安装Google Play 服务,可以用如下两个方法检查当前设备是否安装Google Play 服务,再调用获取上面定位方法
复制代码
private fun checkPlayServices(): Boolean {
    val apiAvailability = GoogleApiAvailability.getInstance()
    val resultCode = apiAvailability.isGooglePlayServicesAvailable(this)
    if (resultCode != ConnectionResult.SUCCESS) {
        if (apiAvailability.isUserResolvableError(resultCode)) {
            LogUtils.d("GoogleApiAvailability NO")
            apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
                ?.show()
        } else {
            LogUtils.d("GoogleApiAvailability Google Play")
            finish()
        }
        return false
    }
    return true
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == PLAY_SERVICES_RESOLUTION_REQUEST) {
        if (resultCode == Activity.RESULT_OK) {
            if (checkPlayServices()) {
                startLocation()
            }
        } else {
            LogUtils.d("无法使用 Google Play 服务")
            finish()
        }
    }
}
相关推荐
2301_771717215 小时前
解决mysql报错:1406, Data too long for column
android·数据库·mysql
dvjr cloi5 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
随遇丿而安8 小时前
第2周:`EditText` 不只是输入框,它是 Android 输入体验的第一道门
android
我命由我123458 小时前
Kotlin 开发 - lateinit 关键字
android·java·开发语言·kotlin·android studio·android-studio·android runtime
一起搞IT吧8 小时前
Android性能系列专题理论之十:systrace/perfetto相关指标知识点细节含义总结
android·嵌入式硬件·智能手机·性能优化
小书房13 小时前
Kotlin的by
android·开发语言·kotlin·委托·by
jinanwuhuaguo13 小时前
(第二十八篇)OpenClaw成本与感知的奇点——从“Token封建制”到“全民养虾”的本体论地基
android·人工智能·kotlin·拓扑学·openclaw
xxjj998a14 小时前
Laravel4.x核心特性全解析
android·mysql·laravel
JoshRen14 小时前
2026教程:在Android Termux中集成Gemini 3镜像站实现移动端文档自动处理与摘要生成(附国内免费方案)
android
诸神黄昏EX15 小时前
Android Google KEY
android