重拾Android之路之接入高德地图


引言

两年前做的项目是基于百度地图API进行地图嵌入的,这次准备试下高德地图。说实话,虽然我手机上只装过百度地图,而从没用过高德,但是对于基础数据的快速更新,对高德的好感度颇高!废话不多说,搞个Demo先。

正文

高德SDK
官方参考文档

1、注册开发者,创建应用

这个几乎是所有开放平台都通用的做法,无外乎注册帐号,成为开发者,然后创建一个Android应用,会为你分配一个key绑定你的服务。

在注册key时,发布版安全码SHA1PackageName的获取方式有些小问题。

重拾Android之路之接入高德地图_第1张图片

官方:获取key的指导

在官方指导页中,并没有提及生成keystore的方法以及生成keystore存放的路径,就这个问题,来详细说明下。

请参照我的另一篇博客: 重拾Android之路之Android签名及打包

通过Android Studio获取SHA1

第一步、打开 Android Studio 的 Terminal 工具。
第二步、输入命令:keytool -v -list -keystore keystore的文件路径。
第三步、输入 Keystore 密码

重拾Android之路之接入高德地图_第2张图片
重拾Android之路之接入高德地图_第3张图片

debug模式下的密码为空。
自定义的签名证书的密码需要填写。

2、通过Gradle集成SDK
  • Projectbuild.gradle文件中配置repositories,添加mavenjcenter仓库地址

Android Studio默认会在Project的build.gradle为所有module自动添加jcenter的仓库地址,如果已存在,则不需要重复添加。Project的build.gradle文件在Project目录中位置如图所示:


重拾Android之路之接入高德地图_第4张图片

配置如下:
allprojects { repositories { jcenter() // 或者 mavenCentral() } }

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

根据项目需求添加SDK依赖。引入各个SDK功能最新版本, dependencies 配置方式如下:

SDK 引入代码
3D地图 compile 'com.amap.api:3dmap:latest.integration'
2D地图 compile 'com.amap.api:map2d:latest.integration'
导航 compile 'com.amap.api:navi-3dmap:latest.integration'
搜索 compile 'com.amap.api:search:latest.integration'
定位 compile 'com.amap.api:location:latest.integration'

主工程的build.gradle文件在Project目录中位置:

重拾Android之路之接入高德地图_第5张图片

以3D的demo工程为例添加3d地图SDK、定位SDK、搜索功能,配置如下:

android { 
  defaultConfig { 
    ndk { 
      //设置支持的SO库架构(开发者可以根据需要,选择一个或多个平台的so) 
      abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86","arm64-v8a","x86_64"
    } 
  }
} 

dependencies { 
  compile fileTree(dir: 'libs', include: ['*.jar']) //3D地图so及jar 
  compile 'com.amap.api:3dmap:latest.integration' //定位功能 
  compile 'com.amap.api:location:latest.integration' //搜索功能 
  compile 'com.amap.api:search:latest.integration' }

以上为引入最新版本的SDK,推荐这种方式。如需引入指定版本SDK(所有SDK版本号均与官网发版一致)如下:

dependencies { 
  compile fileTree(dir: 'libs', include: ['*.jar']) 
  compile 'com.amap.api:3dmap:5.0.0' 
  compile 'com.amap.api:location:3.3.0' 
  compile 'com.amap.api:search:5.0.0' 
}

注意:


1、3D地图 SDK 和导航 SDK,5.0.0 版本以后全面支持多平台 so 库(armeabi、armeabi-v7a、arm64-v8a、x86、x86_64),开发者可以根据需要选择。同时还需要注意的是:如果您涉及到新旧版本更替请移除旧版本的 so 库之后替换新版本 so 库到工程中。
2、navi导航SDK 5.0.0以后版本包含了3D地图SDK,所以请不要同时引入map3d和navi SDK。
3、如果build失败提示com.amap.api:XXX:X.X.X 找不到,请确认拼写及版本号是否正确,如果访问不到jcenter可以切换为maven仓库尝试一下。
4、依照上述方法引入SDK以后,不需要在libs文件夹下导入对应SDK的so和jar包,会有冲突。

3、配置AndroidMainfest.xml文件













        
        
        
        

4、Activity的布局文件

5、Activity,注释非常详细
//监听定位和定位变化
public class MainActivity extends AppCompatActivity implements  LocationSource, AMapLocationListener {

    //显示地图需要的变量
    private MapView mapView;//地图控件
    private AMap aMap;//地图对象


    //定位需要的声明
    private AMapLocationClient mLocationClient = null;//定位发起端
    private AMapLocationClientOption mLocationOption = null;//定位参数
    private OnLocationChangedListener mListener = null;//定位监听器

    //标识,用于判断是否只显示一次定位信息和用户重新定位
    private boolean isFirstLoc = true;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //显示地图
        mapView = (MapView) findViewById(R.id.map);
        //必须要写
        mapView.onCreate(savedInstanceState);
        //获取地图对象
        aMap = mapView.getMap();


        //设置显示定位按钮 并且可以点击
        UiSettings settings = aMap.getUiSettings();
        //设置定位监听
        aMap.setLocationSource(this);
        // 是否显示定位按钮
        settings.setMyLocationButtonEnabled(true);
        // 是否可触发定位并显示定位层
        aMap.setMyLocationEnabled(true);


        //定位的小图标 默认是蓝点 这里自定义一团火,其实就是一张图片
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.mipmap.firetwo));
        myLocationStyle.radiusFillColor(android.R.color.transparent);
        myLocationStyle.strokeColor(android.R.color.transparent);
        aMap.setMyLocationStyle(myLocationStyle);

        //开始定位
        initLoc();


    }


    //定位
    private void initLoc() {
        //初始化定位
        mLocationClient = new AMapLocationClient(getApplicationContext());
        //设置定位回调监听
        mLocationClient.setLocationListener(this);
        //初始化定位参数
        mLocationOption = new AMapLocationClientOption();
        //设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //设置是否返回地址信息(默认返回地址信息)
        mLocationOption.setNeedAddress(true);
        //设置是否只定位一次,默认为false
        mLocationOption.setOnceLocation(false);
        //设置是否强制刷新WIFI,默认为强制刷新
        mLocationOption.setWifiActiveScan(true);
        //设置是否允许模拟位置,默认为false,不允许模拟位置
        mLocationOption.setMockEnable(false);
        //设置定位间隔,单位毫秒,默认为2000ms
        mLocationOption.setInterval(2000);
        //给定位客户端对象设置定位参数
        mLocationClient.setLocationOption(mLocationOption);
        //启动定位
        mLocationClient.startLocation();
    }


    //定位回调函数
    @Override
    public void onLocationChanged(AMapLocation amapLocation) {

        if (amapLocation != null) {
            if (amapLocation.getErrorCode() == 0) {
                //定位成功回调信息,设置相关消息
                amapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见官方定位类型表
                amapLocation.getLatitude();//获取纬度
                amapLocation.getLongitude();//获取经度
                amapLocation.getAccuracy();//获取精度信息
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = new Date(amapLocation.getTime());
                df.format(date);//定位时间
                amapLocation.getAddress();//地址,如果option中设置isNeedAddress为false,则没有此结果,网络定位结果中会有地址信息,GPS定位不返回地址信息。
                amapLocation.getCountry();//国家信息
                amapLocation.getProvince();//省信息
                amapLocation.getCity();//城市信息
                amapLocation.getDistrict();//城区信息
                amapLocation.getStreet();//街道信息
                amapLocation.getStreetNum();//街道门牌号信息
                amapLocation.getCityCode();//城市编码
                amapLocation.getAdCode();//地区编码

                // 如果不设置标志位,此时再拖动地图时,它会不断将地图移动到当前的位置
                if (isFirstLoc) {
                    //设置缩放级别
                    aMap.moveCamera(CameraUpdateFactory.zoomTo(17));
                    //将地图移动到定位点
                    aMap.moveCamera(CameraUpdateFactory.changeLatLng(new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude())));
                    //点击定位按钮 能够将地图的中心移动到定位点
                    mListener.onLocationChanged(amapLocation);
                    //添加图钉
                    aMap.addMarker(getMarkerOptions(amapLocation));
                    //获取定位信息
                    StringBuffer buffer = new StringBuffer();
                    buffer.append(amapLocation.getCountry() + "" + amapLocation.getProvince() + "" + amapLocation.getCity() + "" + amapLocation.getProvince() + "" + amapLocation.getDistrict() + "" + amapLocation.getStreet() + "" + amapLocation.getStreetNum());
                    Toast.makeText(getApplicationContext(), buffer.toString(), Toast.LENGTH_LONG).show();
                    isFirstLoc = false;
                }


            } else {
                //显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。
                Log.e("AmapError", "location Error, ErrCode:"
                        + amapLocation.getErrorCode() + ", errInfo:"
                        + amapLocation.getErrorInfo());

                Toast.makeText(getApplicationContext(), "定位失败", Toast.LENGTH_LONG).show();
            }
        }
    }

    //自定义一个图钉,并且设置图标,当我们点击图钉时,显示设置的信息
    private MarkerOptions getMarkerOptions(AMapLocation amapLocation) {
         //设置图钉选项
        MarkerOptions options = new MarkerOptions();
        //图标
        options.icon(BitmapDescriptorFactory.fromResource(R.mipmap.fire));
        //位置
        options.position(new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude()));
        StringBuffer buffer = new StringBuffer();
        buffer.append(amapLocation.getCountry() + "" + amapLocation.getProvince() + "" + amapLocation.getCity() +  "" + amapLocation.getDistrict() + "" + amapLocation.getStreet() + "" + amapLocation.getStreetNum());
        //标题
        options.title(buffer.toString());
        //子标题
        options.snippet("这里好火");
        //设置多少帧刷新一次图片资源
        options.period(60);

        return options;

    }
    //激活定位
    @Override
    public void activate(OnLocationChangedListener listener) {
        mListener = listener;

    }

    //停止定位
    @Override
    public void deactivate() {
        mListener = null;
    }


    /**
     * 方法必须重写
     */
    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }
}
补充说明

初始化定位

请在主线程中声明AMapLocationClient类对象,需要传Context类型的参数。推荐用getApplicationContext()方法获取全进程有效的context。

//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明定位回调监听器
public AMapLocationListener mLocationListener = new AMapLocationListener();
//初始化定位
mLocationClient = new AMapLocationClient(getApplicationContext());
//设置定位回调监听
mLocationClient.setLocationListener(mLocationListener);

坑点

坑提醒:
请注意key不能带有空格,SHA1严格校验大小写。

正如我上面提醒的,一直报错提醒key值问题

status":"0","info":"INVALID_USER_KEY","infocode":"10001"

判断定位是否开启的Util

解决方案:
先是定位服务----->后拿系统服务----->然后判断----->如果没开就跳转,开了就显示开了

核心代码:

//对GPS的判断 
boolean ok=lm.isProviderEnabled(LocationManager.GPS_PROVIDER); 

权限问题




/**
 * 判断定位是否开启
 */
public class LocationUtil {
    public static boolean isLocated(Context context) {
        //得到系统的位置服务,判断GPS是否激活
        LocationManager locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }

    public static void openSettings(Activity activity) {
        Intent intent = new Intent();
        intent.setAction(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
        activity.startActivity(intent);
    }
}

你可能感兴趣的:(重拾Android之路之接入高德地图)