前提
每次做的项目中或者维护公司之前旧项目的时候,都会用到通过定位来获取经纬度,我们都知道,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,这个是我封装好的一个工具类,方便调用,代码如下:
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) {
locationClient!!.onDestroy()
locationClient = null
locationOption = null
}
}
companion object {
var longitude = 0.0
var latitude = 0.0
}
}
总结
到此这篇关于Android封装高德地图定位工具类Util的文章就介绍到这了,更多相关Android封装高德定位工具类内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!