在Android开发过程中,经常需要获取手机的定位,这里记录一下使用搞的定位的过程。我选择使用高德的SDK,其实也有Web的API,但是API使用IP定位,Android SDK可以使用多种定位方式。
本文2020.4.12更新,此时文中所有内容均已实践
高德开放平台
功能需要,我使用的是Android 定位SDK,其他SDK类似。
新建一个项目,留意包名,后面要用到。
如果是打开原有项目,注意调整build.gradle文件的applicationid与package一致。
自己去注册账号,申请个人开发者也比较简单
输入发布版安全码 SHA1、调试版安全码 SHA1、以及 Package。
Package与自己的AndroidManifest.xml 配置文件包名一致
填写的SHA1值与本地的SHA1值 匹配(debug或者release至少有一个与本地的SHA1一致)
本地的SHA1获取方法:
向程序中添加以下代码段获取当前APK使用的签明文件SHA1。
public static String sHA1(Context context){
try {
PackageInfo info = context.getPackageManager().getPackageInfo(
context.getPackageName(), PackageManager.GET_SIGNATURES);
byte[] cert = info.signatures[0].toByteArray();
MessageDigest md = MessageDigest.getInstance("SHA1");
byte[] publicKey = md.digest(cert);
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < publicKey.length; i++) {
String appendString = Integer.toHexString(0xFF & publicKey[i])
.toUpperCase(Locale.US);
if (appendString.length() == 1)
hexString.append("0");
hexString.append(appendString);
hexString.append(":");
}
String result = hexString.toString();
return result.substring(0, result.length()-1);
} catch (NameNotFoundException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
在Activity中调用一下
String s = sHA1(WeatherActivity.this);//鉴权
Log.e("sHA1:", s);
Android 定位SDK 相关下载
1、拷贝 jar 文件至 libs 文件夹下
将下载的定位 SDK jar 文件复制到工程的 libs 目录下,如果有老版本定位 jar 文件存在,请删除。定位 SDK 无需 so 库文件支持。
2. Add
切换到Project目录下,右键jar包,选择add as library。OK
3. 配置 build.gradle 文件 一般默认就行
在 build.gradle 文件的 dependencies 中配置
compile fileTree(include: ['*.jar'], dir: 'libs')。
请在application标签中声明service组件,每个app拥有自己单独的定位service。
<service android:name="com.amap.api.location.APSService">service>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION">uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE">uses-permission>
<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>
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS">uses-permission>
在application标签中加入:
<meta-data android:name="com.amap.api.v2.apikey" android:value="key">//开发者申请的key
meta-data>
在Activity中
//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明定位回调监听器
public AMapLocationListener mLocationListener = new MyAMapLocationListener();
//声明AMapLocationClientOption对象
public AMapLocationClientOption mLocationOption = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
//初始化定位
mLocationClient = new AMapLocationClient(getApplicationContext());
//设置定位回调监听
mLocationClient.setLocationListener(mLocationListener);
//初始化AMapLocationClientOption对象
mLocationOption = new AMapLocationClientOption();
//设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//获取一次定位结果:
//该方法默认为false。
mLocationOption.setOnceLocation(false);
//获取最近3s内精度最高的一次定位结果:
//设置setOnceLocationLatest(boolean b)接口为true,启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为true,setOnceLocation(boolean b)接口也会被设置为true,反之不会,默认为false。
//mLocationOption.setOnceLocationLatest(true);
//获取一次定位结果:
//该方法默认为false。
mLocationOption.setOnceLocation(true);
//设置是否返回地址信息(默认返回地址信息)
mLocationOption.setNeedAddress(true);
//设置是否允许模拟位置,默认为false,不允许模拟位置
mLocationOption.setMockEnable(false);
//关闭缓存机制
mLocationOption.setLocationCacheEnable(false);
//给定位客户端对象设置定位参数
mLocationClient.setLocationOption(mLocationOption);
//启动定位
mLocationClient.startLocation();
}
private class MyAMapLocationListener implements AMapLocationListener {
@Override
public void onLocationChanged(AMapLocation aMapLocation) {
if (aMapLocation != null) {
if (aMapLocation.getErrorCode() == 0) {
//此处获得成功,可以参照返回值表取需要的参数,我只要了省市县
Log.e("位置:", aMapLocation.getAddress());
Gprovince = aMapLocation.getProvince();
Gcity = aMapLocation.getCity();
Gdistrict = aMapLocation.getDistrict();
} else {
//定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。
Log.e("AmapError", "location Error, ErrCode:"
+ aMapLocation.getErrorCode() + ", errInfo:"
+ aMapLocation.getErrorInfo());
}
}
}
}
参数详细说明见官网
错误码参考表
停止定位
mLocationClient.stopLocation();//停止定位后,本地定位服务并不会被销毁
销毁定位客户端
销毁定位客户端之后,若要重新开启定位请重新New一个AMapLocationClient对象。
mLocationClient.onDestroy();//销毁定位客户端,同时销毁本地定位服务
当返回INVALID_USER_SCODE(不是INVALID_USER_KEY哦),或错误码1008、32和7,可按照如下操作解决问题:
检查SHA1值 //参照本文Key值获取部分
检查包名
Key值填写位置
详细说明,参照官网
祝各位开发顺利无Bug。