Android封装高德地图定位工具类Util

作者: Kepler_II | 来源:发表于2021-07-09 15:15 被阅读0次

    前提

    每次做的项目中或者维护公司之前旧项目的时候,都会用到通过定位来获取经纬度,我们都知道,Android官方也提供了获取经纬度的方法,但是不太好使,所以就用了高德地图的API,不能每次用的时候都要写一堆代码,效率挺低的,于是就想着,封装成一个工具类,方便调用,为以后的项目,不管是管理方面还是查找方面都简洁了不少。

    第一步、去官网创建高德Key

    官网地址:lbs.amap.com/product/loc…

    带*号的填完后,点击提交,获取SHA1值如下(通过代码获取的)或者通过命令行获取,两者都行。 Android studio代码获取SHA1值

    调用 Log.e("-->打印sha1 ","${sha1(this)}")
    fun sha1(context: Context): String {
            try {
                val info: PackageInfo = context.packageManager.getPackageInfo(
                        context.packageName, PackageManager.GET_SIGNATURES)
                val cert: ByteArray = info.signatures.get(0).toByteArray()
                val md: MessageDigest = MessageDigest.getInstance("SHA1")
                val publicKey: ByteArray = md.digest(cert)
                val hexString = StringBuffer()
                for (i in publicKey.indices) {
                    val appendString = Integer.toHexString(0xFF and publicKey[i].toInt())
                            .toUpperCase(Locale.US)
                    if (appendString.length == 1) hexString.append("0")
                    hexString.append(appendString)
                    hexString.append(":")
                }
                val result = hexString.toString()
                return result.substring(0, result.length - 1)
            } catch (e: PackageManager.NameNotFoundException) {
                e.printStackTrace()
            } catch (e: NoSuchAlgorithmException) {
                e.printStackTrace()
            }
            return ""
        }
    复制代码
    

    第二步 通过Gradle集成SDK(方便):

    1、在Project的build.gradle文件中配置repositories,添加maven或jcenter仓库地址:

    allprojects { repositories { jcenter() // 或者 mavenCentral() } }
    复制代码
    

    2、在主工程的build.gradle文件配置dependencies

       //定位
       implementation 'com.amap.api:location:latest.integration'
    复制代码
    

    第三步 配置参数

    第1步,配置AndroidManifest.xml

    请在application标签中声明service组件,每个app拥有自己单独的定位service。

     <!-- 定位需要的服务 使用2.0的定位需要加上这个 -->
            <service android:name="com.amap.api.location.APSService" >
            </service>
    复制代码
    

    第2步,声明权限 如果项目中已有其中的权限,那就不用加了

    <!--用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission> <!--用于访问GPS定位--> 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
    <!--用于获取运营商信息,用于支持提供运营商信息相关的接口--> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
    <!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
    <!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
    <!--用于访问网络,网络定位需要上网-->
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <!--用于读取手机当前的状态-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
    <!--用于写入缓存数据到扩展存储卡-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <!--用于申请调用A-GPS模块-->
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
    
    复制代码
    

    第3步,设置高德Key:

    <meta-data android:name="com.amap.api.v2.apikey" android:value="key">//开发者申请的key           </meta-data>
    复制代码
    

    第四步 获取定位数据

    在需要获取经纬度的页面调用如下代码:

        private var amapLocationUtil: AmapLocationUtil? = null
    
         fun initLocationOption() {
            if (null == amapLocationUtil) {
                amapLocationUtil = AmapLocationUtil(CommApplication.getApplication())
            }
            amapLocationUtil!!.initLocation()
            amapLocationUtil!!.startLocation()
            amapLocationUtil!!.setOnCallBackListener { longitude, latitude, location, isSucdess, address ->
           //Log.e("--->", "longitude" + longitude + "\n" + "latitude" + latitude + "\n" + "isSucdess" + isSucdess + "\n" + "address" + address);
           //Log.e("--->",location.getProvince()+ "\n" +location.getCity()+"\n"+location.getDistrict());
            //isSucdess    true  定位成功   false  失败
                if (isSucdess) {
    
                } else {
                //定位失败,重试定位
                amapLocationUtil!!.startLocation()
                }
            }
        }
    
    复制代码
    

    注意:如果是在当前Activity实例化的,不要忘了销毁

    override fun onDestroy() {
            super.onDestroy()
            if (amapLocationUtil != null) {
                amapLocationUtil!!.destroyLocation()
            }
        }
    复制代码
    

    看到了代码里调用了AmapLocationUtil,这个是我封装好的一个工具类,方便调用,代码如下:

    
    /**
     *
     * Created by JasonYin
     * Description:封装高德地图Util
     *
     */
    class AmapLocationUtil(private val mContext: Context) {
        private var locationClient: AMapLocationClient? = null
        private var locationOption: AMapLocationClientOption? = null
        private var mOnCallBackListener: onCallBackListener? = null
        /**
         * 初始化定位
         */
        fun initLocation() { //初始化client
            if (null == locationClient) {
                locationClient = AMapLocationClient(mContext)
            }
            locationOption = defaultOption
            //设置定位参数
            locationClient!!.setLocationOption(locationOption)
            // 设置定位监听
            locationClient!!.setLocationListener(locationListener)
        }//可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        //可选,设置是否gps优先,只在高精度模式下有效。默认关闭
        //可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        //可选,设置定位间隔。默认为2秒
        //可选,设置是否返回逆地理地址信息。默认是true
        //可选,设置是否单次定位。默认是false
        //可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用
        //可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        //可选,设置是否使用传感器。默认是false
        //可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差
        //可选,设置是否使用缓存定位,默认为true
    //可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        //可选,设置是否gps优先,只在高精度模式下有效。默认关闭
    
        //如果网络可用就选择高精度
        private val defaultOption: AMapLocationClientOption
            private get() {
                val mOption = AMapLocationClientOption()
                //如果网络可用就选择高精度
                if (NetworkUtils.isConnected()) { //可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
                    mOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
                    mOption.isGpsFirst = true //可选,设置是否gps优先,只在高精度模式下有效。默认关闭
                } else {
                    mOption.locationMode = AMapLocationClientOption.AMapLocationMode.Device_Sensors //可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
                    mOption.isGpsFirst = true //可选,设置是否gps优先,只在高精度模式下有效。默认关闭
                }
                mOption.httpTimeOut = 30000 //可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效
                mOption.interval = 2000 //可选,设置定位间隔。默认为2秒
                mOption.isNeedAddress = true //可选,设置是否返回逆地理地址信息。默认是true
                mOption.isOnceLocation = false //可选,设置是否单次定位。默认是false
                mOption.isOnceLocationLatest = false //可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用
                AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP) //可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
                mOption.isSensorEnable = true //可选,设置是否使用传感器。默认是false
                mOption.isWifiScan = true //可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差
                mOption.isLocationCacheEnable = true //可选,设置是否使用缓存定位,默认为true
                return mOption
            }
    
        var locationListener = AMapLocationListener { location ->
            val sb = StringBuilder()
            if (null != location) { //errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明
                if (location.errorCode == 0) {
                    longitude = location.longitude
                    latitude = location.latitude
                    val district = location.district
                    locationSuccess(longitude, latitude, true, location, district)
                    //定位成功,停止定位:如果实时定位,就把stopLocation()关闭
                    stopLocation()
                } else { //定位失败
    //                    sb.append("定位失败" + "\n");
    //                    sb.append("错误码:" + location.getErrorCode() + "\n");
    //                    sb.append("错误信息:" + location.getErrorInfo() + "\n");
    //                    sb.append("错误描述:" + location.getLocationDetail() + "\n");
    //                    Log.e("---> 定位失败", sb.toString());
                    LocationFarile(false, location)
                }
            } else {
                LocationFarile(false, location)
            }
        }
    
        private fun LocationFarile(isSucdess: Boolean, location: AMapLocation) {
            if (mOnCallBackListener != null) {
                mOnCallBackListener!!.onCallBack(0.0, 0.0, location, false, "")
            }
        }
    
        fun locationSuccess(longitude: Double, latitude: Double, isSucdess: Boolean, location: AMapLocation?, address: String?) {
            if (mOnCallBackListener != null) {
                mOnCallBackListener!!.onCallBack(longitude, latitude, location, true, address)
            }
        }
    
        fun setOnCallBackListener(listener: onCallBackListener?) {
            mOnCallBackListener = listener
        }
    
        interface onCallBackListener {
            fun onCallBack(longitude: Double, latitude: Double, location: AMapLocation?, isSucdess: Boolean, address: String?)
        }
    
        /**
         * 开始定位
         */
        fun startLocation() {
            locationClient!!.startLocation()
        }
    
        /**
         * 停止定位
         */
        fun stopLocation() {
            locationClient!!.stopLocation()
        }
    
        /**
         * 销毁定位
         */
        fun destroyLocation() {
            if (null != locationClient) {
                /**
                 * 如果AMapLocationClient是在当前Activity实例化的,
                 * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
                 */
                locationClient!!.onDestroy()
                locationClient = null
                locationOption = null
            }
        }
    
        companion object {
            var longitude = 0.0
            var latitude = 0.0
        }
    
    }
    

    本文在开源项目:https://github.com/Android-Alvin/Android-LearningNotes 中已收录,里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中...

    相关文章

      网友评论

        本文标题:Android封装高德地图定位工具类Util

        本文链接:https://www.haomeiwen.com/subject/gnyfpltx.html