Android 快速掌握高德地图SDK(内含实践项目)

上周学习了高德地图和极光推送的SDK,需要在项目中用到,不过学习起来还是费了一番功夫去看文档和Demo代码的。(不得不吐槽部分文档真的无厘头,只有简单的实例程序注释都没有,上下文还不对接,真是醉了),所以打算把最直白的步骤写在博客中,也希望能帮到还不会用这两种SDK的小伙伴们,少走弯路,提高工作效率。


本文主要介绍高德地图SDK的使用步骤:

包括从获取Key,到导包,到布局文件,以及编码实现。

还有两个最常用的功能:

实现定位自身。

根据地名或者坐标实现搜索定位并显示小蓝点。

一、获取高德Key:

点击这里进入高德控制台,点击创建应用,输入应用名称和应用类型。

Android 快速掌握高德地图SDK(内含实践项目)_第1张图片

应用创建完成后,点击添加key开始添加新key:

Android 快速掌握高德地图SDK(内含实践项目)_第2张图片

SHA1码的获取方式有两种:

1、Eclipse可以直接从Preferances -> Android -> Build查看当前应用的SHA1值。

2、AndroidStudio用户有两种方式,第一种通过命令行语句获得,不过这样子还要签名要费一番周折,第二种方式最简单直接用一个方法输出当前应用的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();
        Log.d("xiaojingyu", result);
        return result.substring(0, result.length() - 1);
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return null;
}
之后提交,就会得到一串类似于38bcab8bxxxxxx5bed57ba835e1的字符,这就是我们开发所需要的key了。


二、导包:

eclipse就不说了,直接把包放到libs里就可以了。

AndroidStudio复杂一点,但也就是放到libs里再add 到library就行了。

如下几个是需要用到的包:

Android 快速掌握高德地图SDK(内含实践项目)_第3张图片

以及包下载地址


三、获取权限:

需要的权限都要添加进AndroidMainfest.xml文件中:

















四、编码实现:

首先是布局文件:

设置高德sdk指定的MapView:

        
        

于是开始代码的编写。既然布局文件中用到了MapView,代码中肯定还是要初始化的:

MapView mMapView = null;
那这个MapView的作用是什么呢?读完代码(文档并不会告诉你)我们可以发现它是地图的View,需要实现地图的生命周期管理:

        mMapView = (MapView) v.findViewById(R.id.map);
        //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),实现地图生命周期管理
        mMapView.onCreate(savedInstanceState);
当然起到控制作用的还有一个关键类AMap,起到对地图的一些基本管理以及控制接口作用,我们可以在初始化的时候进行如下操作来初始化amap实例:

        if (aMap == null) {
            aMap = mMapView.getMap();
            aMap.moveCamera(CameraUpdateFactory.zoomTo(0)); //设置缩放为0,则一进来就显示整个中国大陆
            aMap.setLocationSource(this);// 设置定位监听
            aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
            aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false
            // 设置定位的类型为定位模式 ,可以由定位、跟随或地图根据面向方向旋转几种
            aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
        }


实现当前位置系统小蓝点:

我们可以用当前Activity实现AMap定位监听AMapLocationListener,并重写它的定位方法:

    @Override
    public void onLocationChanged(AMapLocation amapLocation) {
        if (mListener != null && amapLocation != null) {
            if (amapLocation != null
                    && amapLocation.getErrorCode() == 0) {
                mListener.onLocationChanged(amapLocation);// 显示系统小蓝点
            } else {
                String errText = "定位失败," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();
                Log.e("AmapErr", errText);
            }
        }
    }
这里还要用到一个位置改变监听:OnLocationChangedListener,通过它的方法onLocationChanged(amaplocation)来实现地图上位置的改变!


实现响应地理编码(输入地名定位到具体位置):

可以看到在Amap的初始化的代码中需要设置定位监听,所以需要当前Activity实现LocationSource接口,并重写激活定位以及停止定位两个接口方法:

    /**
     * 激活定位
     */
    @Override
    public void activate(OnLocationChangedListener listener) {
        Log.d("xiaojingyu", "activate");
        mListener = listener;
        if (mLocationClient == null) {
            mLocationClient = new AMapLocationClient(getActivity());
            mLocationOption = new AMapLocationClientOption();
            //设置定位监听
            mLocationClient.setLocationListener(this);
            //设置为高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //设置定位参数
            mLocationClient.setLocationOption(mLocationOption);
            // 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,
            // 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后,在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除
            mLocationClient.startLocation();
        }
    }

    /**
     * 停止定位
     */
    @Override
    public void deactivate() {
        Log.d("xiaojingyu", "deactivate");
        mListener = null;
        if (mLocationClient != null) {
            mLocationClient.stopLocation();
            mLocationClient.onDestroy();
        }
        mLocationClient = null;
    }
这里需要用到一个定位的Client对象,以及一个Option位置对象

记得申明:

public AMapLocationClient mLocationClient = null;
public AMapLocationClientOption mLocationOption = null;


接下来我们需要申明并初始化两个搜索组件:

//搜索组件
private GeocodeSearch geocoderSearch;
private Marker geoMarker;

都需要在onCreate之后就进行初始化:

geocoderSearch = new GeocodeSearch(getActivity());
        geocoderSearch.setOnGeocodeSearchListener(this);

            geoMarker = aMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f)
                    .icon(BitmapDescriptorFactory
                            .defaultMarker(BitmapDescriptorFactory.HUE_BLUE)));
其中geoMarker是用来显示定位成功之后的小蓝点。
接下来我们就可以写具体的相应地理编码方法了:

    /**
     * 响应地理编码
     */
    public void getLatlon(final String name) {
        //showDialog();
        GeocodeQuery query = new GeocodeQuery(name, "0086");// 第一个参数表示地址,第二个参数表示查询城市,中文或者中文全拼,citycode、adcode,
        geocoderSearch.getFromLocationNameAsyn(query);// 设置同步地理编码请求
    }
其中第二个参数我设置成0086是中国的区号,这样可以实现全国范围内查找。比如我只设置成长沙的区号0731,那么我只能输入长沙的地名进行查找,再查比如岳阳是查不到的。

之后会回调geocoderSearch的监听方法实现定位:

    @Override
    public void onGeocodeSearched(GeocodeResult result, int rCode) {
        //dismissDialog();

        if (rCode == 1000) {
            if (result != null && result.getGeocodeAddressList() != null
                    && result.getGeocodeAddressList().size() > 0) {
                GeocodeAddress address = result.getGeocodeAddressList().get(0);
                aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                        AMapUtil.convertToLatLng(address.getLatLonPoint()), 15));
                geoMarker.setPosition(AMapUtil.convertToLatLng(address
                        .getLatLonPoint()));
                addressName = "经纬度值:" + address.getLatLonPoint() + "\n位置描述:"
                        + address.getFormatAddress();
                //   ToastUtil.show(getActivity(), addressName);
            } else {
                ToastUtil.show(getActivity(), "没有查询到结果~!");
            }
        } else {
            ToastUtil.showerror(getActivity(), rCode);
        }
    }

所谓的相应逆地理编码其实就是传入坐标值然后实现定位,跟上文中的相应地理编码异曲同工,这里就不再实现一遍了。

用到的功能大概就是这些,如果还需要其他的功能可以参考高德SDK官方文档:
http://lbs.amap.com/api/android-location-sdk/guide/android-location/getlocation/

最后是我最后实现的效果动图:

Android 快速掌握高德地图SDK(内含实践项目)_第4张图片


因为涉及项目相关,所以不能把全部源码贴上来了。

有问题的朋友在评论区留言,我会一一解答。









**********************************************分隔线***************************************************

应评论区朋友的要求,在这里贴上响应逆地理编码的代码:

    /**
     * 响应逆地理编码
     */
    public void getAddress(final LatLonPoint latLonPoint) {
        showDialog();
        RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200,
                GeocodeSearch.AMAP);// 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系
        geocoderSearch.getFromLocationAsyn(query);// 设置同步逆地理编码请求
    }
	/**
	 * 逆地理编码回调
	 */
	@Override
	public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
		dismissDialog();
		if (rCode == 1000) {
			if (result != null && result.getRegeocodeAddress() != null
					&& result.getRegeocodeAddress().getFormatAddress() != null) {
				addressName = result.getRegeocodeAddress().getFormatAddress()
						+ "附近";
				aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
						AMapUtil.convertToLatLng(latLonPoint), 15));
				regeoMarker.setPosition(AMapUtil.convertToLatLng(latLonPoint));
				ToastUtil.show(GeocoderActivity.this, addressName);
			} else {
				ToastUtil.show(GeocoderActivity.this, R.string.no_result);
			}
		} else {
			ToastUtil.showerror(this, rCode);
		}
	}

使用方式为在getAddress(LatLonP oint)中传入需要定位的坐标系,LatLonPoint类是包含在Jar包中的,具体使用方法可以在代码里直接ctrl+1查看。


 

你可能感兴趣的:(Android,Android进阶学习笔记)