Android封装高德地图定位工具类Util的详细步骤
作者:JasonYin 发布时间:2022-09-10 10:23:17
标签:android,封装,util
目录
前提
第一步、去官网创建高德Key
第二步 通过Gradle集成SDK(方便):
第三步 配置参数
第四步 获取定位数据
总结
前提
每次做的项目中或者维护公司之前旧项目的时候,都会用到通过定位来获取经纬度,我们都知道,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://juejin.cn/post/6982807305058287623


猜你喜欢
- 自从使用 HttpClient 和 Jsoup 配合编写了几个简单的入门爬虫之后,发现对于绝对路径的需求是很频繁的,因为大部分的网页都写相对
- Spring课程工程构建 在IDEA 工作空间里面创建Spring文件夹。打开IDEA,file–>Open&am
- ActiveMQ是什么ActiveMQ是消息队列技术,为解决高并发问题而生ActiveMQ生产者消费者模型(生产者和消费者可以跨平台、跨系统
- 今天给大家介绍一下SpringBoot中JPA的一些常用操作,例如:增删改查、分页、排序、事务操作等功能。下面先来介绍一下JPA中一些常用的
- 本文实例讲述了Android编程基于距离传感器控制手机屏幕熄灭的方法。分享给大家供大家参考,具体如下:在现实生活中,打电话的时候手机挨着自己
- 如下所示:using System;using System.Collections.Generic;using System.Linq;u
- 导入依赖(pom.xml) <!--整合Shiro安全框架--> <dependency>
- 简介上一篇我们讲了简单的动态BroadCast,今天我们通过手工来发送一条BroadCast进一步来了解BroadCast。在上一篇里我们使
- spring中事务处理原理 利用aop生成代理对象执行带有Transactional事务注解的
- 1 前言项目中,目前主流的当然是微服务项目。为了应对高并发,以及保证自己的服务比较稳定,通常会把服务按照模块,或者具体的业务划分为多个独立的
- 本文实例讲述了C#提取网页中超链接link和text部分的方法。分享给大家供大家参考,具体如下:string s = "..&qu
- WPF 窗体设置亚克力效果框架使用大于等于.NET40。Visual Studio 2022。项目使用 MIT 开源许可
- 说起空间动态、微博的点赞效果,网上也是很泛滥,各种实现与效果一大堆。而详细实现的部分,讲述的也是参差不齐,另一方面估计也有很多大侠也不屑一顾
- 思路:首先进入登录界面,输入账号和密码后登陆到主界面,在主界面通过点击按钮发送一条强制下线的广播,广播接收者收到广播后重新进入登陆界面。新建
- Lambda是第十一个希腊字母,大写Λ,小写λ,额,跑题了…Lambda表达式 是Java8的新特性之一:Lambda表达式函数式接口流AP
- 1. 什么是RESTREST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状
- 1.先看源码文档/** * Indicates that an annotation type is automatically inher
- 一、TkMybatisTkmybatis 是基于 Mybatis 框架开发的一个工具,通过调用它提供的方法实现对单表的数据操作,不需要写任何
- 前言:阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成,这种状态转换需要耗费处理器时间。如果同步代码块中的内容过于简单,状态转换消
- 在本文中,我们将介绍二进制搜索相对于简单线性搜索的优势,并介绍它在 Java 中的实现。1. 需要有效的搜索假设我们在wine-sellin