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()
        }
    }
}
相关推荐
千里马学框架2 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台2 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone2 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc2 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo2 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone2 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen2 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone2 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui