工作笔记:Android高德定位使用说明

高德定位模块使用说明

权限和KEY

在AndroidManifest.xml添加权限,如果仅使用定位功能,其他不需要的权限可去掉。

<!-- Normal Permissions 不需要运行时注册 -->
<!-- 获取运营商信息,用于支持提供运营商信息相关的接口 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>

<!-- 请求网络 -->
<uses-permission android:name="android.permission.INTERNET"/>

<!-- 不是SDK需要的权限,是示例中的后台唤醒定位需要的权限 -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>

<!-- 需要运行时注册的权限 -->
<!-- 用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- 用于访问GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- 用于提高GPS定位速度 -->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
<!-- 写入扩展存储,向扩展卡写入数据,用于写入缓存定位数据 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 读取缓存数据 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<!-- 用于读取手机当前的状态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

<!-- 更改设置 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

<!--如果设置了target >= 28 如果需要启动后台定位则必须声明这个权限-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!--如果您的应用需要后台定位权限,且有可能运行在Android Q设备上,并且设置了target>28,必须增加这个权限声明-->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

在AndroidManifest.xml的application中添加APSService和KEY

<!-- 设置key -->
<meta-data
    android:name="com.amap.api.v2.apikey"
    android:value="您申请的key"/> 
    
<service
    android:name="com.amap.api.location.APSService"
    android:foregroundServiceType="location" />

添加依赖

相关下载-Android 定位SDK|高德地图API (amap.com)下载对应的jar,直接导入到项目libs

img

在app的build.gradle添加依赖

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
}

代码

/**
 *    author : 吴明辉
 *    e-mail : 1412378121@qq.com
 *    date   : 2022/3/2213:55
 *    git    : https://gitee.com/yunianvh
 *    desc   :
 */

import androidx.fragment.app.FragmentActivity
import com.amap.api.location.AMapLocation
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.yangchoi.lib_base.utils.LogUtil.e
import java.io.File
import java.io.FileWriter
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*

class LocationManager(
    context: FragmentActivity?,
    private val offlineSavePath: String?,
    locationCallBack: LocationCallBack?
) {
    //声明AMapLocationClient类对象
    private var mLocationClient: AMapLocationClient? = null
    private var DATE_FORMAT = SimpleDateFormat("yyyyMMdd")
    private var todayName: String? = null
    var isSaveOfflineLocation: Boolean = false

    companion object {
        private val TAG = LocationManager::class.java.simpleName
    }

    //回调信息对象
    class LocationBean {
        var time: Long? = null
        var latitude: Double? = null
        var longitude: Double? = null
        var address: String? = null
        var locationDetail: String? = null
    }

    //回调
    interface LocationCallBack {
        fun onLocationInfo(locationBean: LocationBean?)
    }

    //声明定位回调监听器
    private var mLocationListener = AMapLocationListener { aMapLocation ->
        if (aMapLocation != null) {
            e(TAG, "onLocationChanged   errorCode: [ " + aMapLocation.errorCode + " ]")
            if (aMapLocation.errorCode == 0) {
                val gpsAccuracyStatus = aMapLocation.gpsAccuracyStatus //0差  1好  -1未知
                val locationType =
                    aMapLocation.locationType //0失败 1gps 2前次定位 4:缓存 5:wifi 6:基站 8:离线  9:缓存
                val accuracy = aMapLocation.accuracy //精度
                val gpsSatellites = aMapLocation.satellites //搜星数
                val trustedLevel = aMapLocation.trustedLevel //定位可信度  1好 2正常 3低 4差
                val speed = aMapLocation.speed //速度
                val locationDetail =
                    "卫星信号强度:$gpsAccuracyStatus  定位类型:$locationType  精度:$accuracy  gps搜星数:$gpsSatellites  可信度:$trustedLevel  速度:$speed"
                e(TAG, "onLocationChanged : $locationDetail")
                //去掉离线缓存
                if (locationType == AMapLocation.LOCATION_TYPE_FIX_CACHE || locationType == AMapLocation.LOCATION_TYPE_LAST_LOCATION_CACHE) {
                    return@AMapLocationListener
                }
                //通过回调接口返回回去
                var bean = LocationBean()
                bean.time = aMapLocation.time
                bean.latitude = aMapLocation.latitude
                bean.longitude = aMapLocation.longitude
                bean.address = aMapLocation.address
                bean.locationDetail = locationDetail
                locationCallBack!!.onLocationInfo(bean)

                //保存经纬度到本地文件(长链接没有连接时)
                saveOfflineLocation(aMapLocation.latitude, aMapLocation.longitude)
            } else {
                //定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。
                e(
                    TAG, "location Error, ErrCode:"
                            + aMapLocation.errorCode
                            + ", errInfo:"
                            + aMapLocation.errorInfo
                )
            }
        }
    }

    //isSaveOfflineLocation=true保存经纬度到本地,false不保存
    fun isSaveOfflineLocation(isSaveOfflineLocation: Boolean) {
        this.isSaveOfflineLocation = isSaveOfflineLocation
    }

    //本地保存经纬度
    private fun saveOfflineLocation(lat: Double, lon: Double) {
        if (offlineSavePath!!.isBlank() || !isSaveOfflineLocation) return
        e(TAG, "saveOfflineLocation 保存经纬度: $lat,$lon")
        val todayPath: String = offlineSavePath + todayName
        val locFile = File(todayPath)
        try {
            if (!locFile.exists()) locFile.createNewFile()
            val time = System.currentTimeMillis() / 1000
            val strData = "$time,$lat,$lon;"
            // 打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件
            val writer = FileWriter(todayPath, true)
            writer.write(strData)
            writer.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    fun startLocation() {
        mLocationClient!!.startLocation()//启动定位
    }

    fun stopLocation() {
        mLocationClient!!.stopLocation() //停止定位后,本地定位服务并不会被销毁
    }


    init {
        //获取当天时间用于本地保存的文件名
        val format = DATE_FORMAT.format(Date())
        todayName = File.separator + "$format.txt"

        if (mLocationClient != null) {
            e(TAG, "mLocationClient != null")
        } else {
            //初始化定位
            mLocationClient = AMapLocationClient(context)
            //声明AMapLocationClientOption对象
            val locationOption = AMapLocationClientOption()
            locationOption.locationMode =
                AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
            locationOption.interval = (10 * 1000).toLong()
            locationOption.isSensorEnable = true
            //给定位客户端对象设置定位参数
            mLocationClient!!.setLocationOption(locationOption)
            //设置定位回调监听
            mLocationClient!!.setLocationListener(mLocationListener)
        }
    }
}

调用

在调用之前要确保权限已打开,推荐用PermissionX打开权限

 var c = LocationManager(this, null, null)
 c.startLocation()
 c.isSaveOfflineLocation(false)

PermissionX申请权限

记得添加依赖:com.permissionx.guolindev:permissionx:1.3.0

PermissionX.init(this).permissions(
    Manifest.permission.ACCESS_COARSE_LOCATION,
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS
).onExplainRequestReason { scope: ExplainScope, deniedList: List<String?>? ->
    scope.showRequestReasonDialog(
        deniedList,
        "需要您同意以下授权才能正常使用定位功能",
        "同意",
        "拒绝"
    )
}.request { allGranted: Boolean, grantedList: List<String?>?, deniedList: List<String?> ->
    if (allGranted) {
        Toast.makeText(this, "您同意了所有权限!", Toast.LENGTH_SHORT).show()
        // 获取系统的LocationManager服务
        var c = LocationManager(this, null)
        c.startLocation()
    } else {
        Toast.makeText(this, "您拒绝了以下权限:$deniedList", Toast.LENGTH_SHORT).show()
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玉念聿辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值