Android 使用高德SDK获取定位

在Android开发过程中,经常需要获取手机的定位,这里记录一下使用搞的定位的过程。我选择使用高德的SDK,其实也有Web的API,但是API使用IP定位,Android SDK可以使用多种定位方式。

高德开放平台
功能需要,我使用的是Android 定位SDK,其他SDK类似。

开发过程

Android Studio新建项目

新建一个项目,留意包名,后面要用到。
如果是打开原有项目,注意调整build.gradle文件的applicationid与package一致

申请高德 Key

自己去注册账号,申请个人开发者也比较简单

新建应用

在这里插入图片描述
类型选择Android SDK

添加Key

在这里插入图片描述
输入发布版安全码 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 Studio 配置工程

Android 定位SDK 相关下载

通过拷贝集成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')。

获取天气定位

配置AndroidManifest.xml
首先,声明Service组件

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

<service android:name="com.amap.api.location.APSService"></service>
 
然后,声明权限
<!--用于进行网络定位-->
<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>
最后,设置高德Key

在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();//销毁定位客户端,同时销毁本地定位服务
 

常见错误

使用Android SDK 调用高德业务返回INVALID_USER_SCODE

当返回INVALID_USER_SCODE(不是INVALID_USER_KEY哦),或错误码1008、32和7,可按照如下操作解决问题:

检查SHA1值 //参照本文Key值获取部分
检查包名
Key值填写位置