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()
        }
    }
}
相关推荐
居然是阿宋24 分钟前
Kotlin高阶函数 vs Lambda表达式:关键区别与协作关系
android·开发语言·kotlin
凉、介38 分钟前
PCI 总线学习笔记(五)
android·linux·笔记·学习·pcie·pci
小贾要学习2 小时前
【C++】继承----下篇
android·java·c++
投笔丶从戎3 小时前
Kotlin Multiplatform--01:项目结构基础
android·开发语言·kotlin
Lary_Rock4 小时前
Android 编译问题 prebuilts/clang/host/linux-x86
android·linux·运维
王江奎5 小时前
Android FFmpeg 交叉编译全指南:NDK编译 + CMake 集成
android·ffmpeg
limingade5 小时前
手机打电话通话时如何向对方播放录制的IVR引导词声音
android·智能手机·蓝牙电话·手机提取通话声音
hepherd6 小时前
Flutter 环境搭建 (Android)
android·flutter·visual studio code
_一条咸鱼_7 小时前
揭秘 Android ListView:从源码深度剖析其使用原理
android·面试·android jetpack