高德地图——定位 检索 导航全套

附上DEMO

申请key

http://lbs.amap.com/dev/key#/

秘钥生成方法

测试版SHA1获取方法:
  public String sHA1(Context context) {
        try {
            PackageInfo info = 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(":");
            }
            return hexString.toString();
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }


配置工程

1、导入jar,so文件,配置 AndroidManifest.xml,官方有。

准备完成,开始定位地图:

首先开启定位功能,配置监听事件
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        presenter = new SearchPresenter(this);
        //获取地图控件引用
        mMapView = (MapView) findViewById(R.id.map);
        //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),实现地图生命周期管理
        mMapView.onCreate(savedInstanceState);
        //初始化地图变量
        if (aMap == null) {
            aMap = mMapView.getMap();
        }
        aMap.setInfoWindowAdapter(this);
        mlocationClient = new AMapLocationClient(this);
//初始化定位参数
        mLocationOption = new AMapLocationClientOption();
//设置定位监听
        mlocationClient.setLocationListener(this);
//设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//设置定位间隔,单位毫秒,默认为2000ms
        mLocationOption.setInterval(2000);
        //设置一次定位
        mLocationOption.setOnceLocation(true);
//设置定位参数
        mlocationClient.setLocationOption(mLocationOption);
// 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,
// 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求
// 在定位结束后,在合适的生命周期调用onDestroy()方法
// 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除
//启动定位
        mlocationClient.startLocation();
        aMap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                return false;
            }
        });
    }

定位成功,回调监听:

 @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);//定位时间

                // 如果不设置标志位,此时再拖动地图时,它会不断将地图移动到当前的位置
                //设置缩放级别
                aMap.moveCamera(CameraUpdateFactory.zoomTo(12));
                //将地图移动到定位点
                aMap.moveCamera(CameraUpdateFactory
                        .changeLatLng(new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude())));
                LatLng latLng = new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude());
                latLonPoint = latLng;
                //在地图中设置定位坐标点
                MarkerOptions markerOption = new MarkerOptions();
                markerOption.position(latLng);
                markerOption.draggable(true);
                markerOption.icon(BitmapDescriptorFactory.fromResource(R.mipmap.dingwei));
                markerOption.title(amapLocation.getPoiName()).snippet(amapLocation.getAddress());
                Marker marker = aMap.addMarker(markerOption);
                marker.setRotateAngle(0);
                //定位成功,开启检测功能
                startSearch(amapLocation.getLatitude(), amapLocation.getLongitude());
               
            } else {
                //显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。
                Log.e("AmapError", "location Error, ErrCode:"
                        + amapLocation.getErrorCode() + ", errInfo:"
                        + amapLocation.getErrorInfo());
            }
        }
    }

在定位回调中开启检测功能
startSearch(amapLocation.getLatitude(), amapLocation.getLongitude());

 private void startSearch(double Latitude, double Longitude) {
        PoiSearch.Query query = new PoiSearch.Query("加油站", "汽车维修|修车服务", "");
        // keyWord表示搜索字符串,第二个参数表示POI搜索类型,默认为:生活服务、餐饮服务、商务住宅
        // 共分为以下20种:汽车服务|汽车销售|
        // 汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务|
        // 住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|交通设施服务|
        // 金融保险服务|公司企业|道路附属设施|地名地址信息|公共设施
        // cityCode表示POI搜索区域,(这里可以传空字符串,空字符串代表全国在全国范围内进行搜索)
        query.setPageSize(10);// 设置每页最多返回多少条poiitem
        query.setPageNum(1);// 设置查第一页
        PoiSearch poiSearch = new PoiSearch(this, query);
        //如果不为空值
        if (Latitude != 0.0 && Longitude != 0.0) {
            poiSearch.setBound(new PoiSearch.SearchBound(new LatLonPoint(Latitude,
                    Longitude), 6000));// 设置周边搜索的中心点以及区域
            poiSearch.setOnPoiSearchListener(this);// 设置数据返回的监听器
            poiSearch.searchPOIAsyn();// 开始搜索
        } else {
//            Toast.makeText(SearchActivity.this, "定位失败", 0).show();
        }
    }

检索成功后,在地图上设置涂点:
 @Override
    public void onPoiSearched(PoiResult poiResult, int i) {
        //结果
        if (poiResult.getPois() == null)
            return;
        ArrayList poiItems = poiResult.getPois();

        for (PoiItem a : poiItems) {
            addMarkerToMap(a);
        }

    }

    private void addMarkerToMap(PoiItem a) {
        LatLng latLng = new LatLng(a.getLatLonPoint().getLatitude(), a.getLatLonPoint().getLongitude());
        MarkerOptions markerOption = new MarkerOptions();
        markerOption.position(latLng);
        markerOption.draggable(true);
        markerOption.icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_location));
        markerOption.title(a.getCityName()).snippet(a.getBusinessArea());
        Marker marker = aMap.addMarker(markerOption);
        marker.setRotateAngle(0);
        //显示InfoWindow
    }

接下来是目标点点击事件,这里我采用了点击后弹出自定义弹窗:
 @Override
    public View getInfoWindow(final Marker marker) {
        View view = getLayoutInflater().inflate(R.layout.bdmap_node_popwindow,
                null);
        view.findViewById(R.id.item3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                naviMapStart(marker);
            }
        });
        return view;
    }

    @Override
    public View getInfoContents(final Marker marker) {
        View view = getLayoutInflater().inflate(R.layout.bdmap_node_popwindow,
                null);
//        TextView title = (TextView) view.findViewById(R.id.title);
//        title.setText(marker.getTitle());
        view.findViewById(R.id.item3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                naviMapStart(marker);
            }
        });
        return view;
    }

注意:设置自定义弹窗首先要先设置监听,让高德来拿取我们自定义的view,这里很坑,卡了我3、4个小时。
//设置自定义view事件 
aMap.setInfoWindowAdapter(this);
当然activity需要继承接口 AMap.InfoWindowAdapter。

到这里界面基本上就完成了,接下来就是点击我们自定义弹窗中按钮时调用导航:

导航功能配置

首先要有一个导航activity
public class AMapNaviActivity extends NaviBaseActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_amap_navi);
        mAMapNaviView = (AMapNaviView) findViewById(R.id.navi_view);
        mAMapNaviView.onCreate(savedInstanceState);
        mAMapNaviView.setAMapNaviViewListener(this);
        AMapNaviViewOptions options = mAMapNaviView.getViewOptions();
        options.setLayoutVisible(false);
        mAMapNaviView.setViewOptions(options);

    }

    public void northUp(View view) {
        mAMapNaviView.setNaviMode(AMapNaviView.NORTH_UP_MODE);
    }

    public void carUp(View view) {
        mAMapNaviView.setNaviMode(AMapNaviView.CAR_UP_MODE);
    }

    @Override
    public void onInitNaviSuccess() {
        super.onInitNaviSuccess();
        /**
         * 方法: int strategy=mAMapNavi.strategyConvert(congestion, avoidhightspeed, cost, hightspeed, multipleroute); 参数:
         *
         * @congestion 躲避拥堵
         * @avoidhightspeed 不走高速
         * @cost 避免收费
         * @hightspeed 高速优先
         * @multipleroute 多路径
         *
         *  说明: 以上参数都是boolean类型,其中multipleroute参数表示是否多条路线,如果为true则此策略会算出多条路线。
         *  注意: 不走高速与高速优先不能同时为true 高速优先与避免收费不能同时为true
         */
        int strategy = 0;
        try {
            //再次强调,最后一个参数为true时代表多路径,否则代表单路径
            strategy = mAMapNavi.strategyConvert(true, false, false, false, false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        mAMapNavi.calculateDriveRoute(SearchActivity.startPoints , SearchActivity.endPoints , mWayPointList, strategy);

    }

    @Override
    public void onCalculateRouteSuccess() {
        super.onCalculateRouteSuccess();
        mAMapNavi.startNavi(NaviType.GPS);
    }
}

其中继承的类为:
public class NaviBaseActivity extends Activity implements AMapNaviListener, AMapNaviViewListener {

    protected AMapNaviView mAMapNaviView;
    protected AMapNavi mAMapNavi;
//    protected TTSController mTtsManager;
    protected  List sList = new ArrayList();
    protected  List eList = new ArrayList();
    protected List mWayPointList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
//        //实例化语音引擎
//        mTtsManager = TTSController.getInstance(getApplicationContext());
//        mTtsManager.init();

        //
        mAMapNavi = AMapNavi.getInstance(getApplicationContext());
        mAMapNavi.addAMapNaviListener(this);
//        mAMapNavi.addAMapNaviListener(mTtsManager);

        //设置模拟导航的行车速度
        mAMapNavi.setEmulatorNaviSpeed(75);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mAMapNaviView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mAMapNaviView.onPause();

//        仅仅是停止你当前在说的这句话,一会到新的路口还是会再说的
//        mTtsManager.stopSpeaking();
//
//        停止导航之后,会触及底层stop,然后就不会再有回调了,但是讯飞当前还是没有说完的半句话还是会说完
//        mAMapNavi.stopNavi();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mAMapNaviView.onDestroy();
        //since 1.6.0 不再在naviview destroy的时候自动执行AMapNavi.stopNavi();请自行执行
        mAMapNavi.stopNavi();
        mAMapNavi.destroy();
//        mTtsManager.destroy();
    }

    @Override
    public void onInitNaviFailure() {
        Toast.makeText(this, "init navi Failed", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onInitNaviSuccess() {
        //初始化成功
    }

    @Override
    public void onStartNavi(int type) {
        //开始导航回调
    }

    @Override
    public void onTrafficStatusUpdate() {
        //
    }

    @Override
    public void onLocationChange(AMapNaviLocation location) {
        //当前位置回调
    }

    @Override
    public void onGetNavigationText(int type, String text) {
        //播报类型和播报文字回调
    }

    @Override
    public void onEndEmulatorNavi() {
        //结束模拟导航
    }

    @Override
    public void onArriveDestination() {
        //到达目的地
    }

    @Override
    public void onArriveDestination(NaviStaticInfo naviStaticInfo) {
        //到达目的地,有统计信息回调
    }

    @Override
    public void onArriveDestination(AMapNaviStaticInfo aMapNaviStaticInfo) {

    }

    @Override
    public void onCalculateRouteSuccess() {
        //路线计算成功
    }

    @Override
    public void onCalculateRouteFailure(int errorInfo) {
        //路线计算失败
        Log.i("dm","errorInfo="+errorInfo);
        Toast.makeText(this, "errorInfo:" + errorInfo, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onReCalculateRouteForYaw() {
        //偏航后重新计算路线回调
    }

    @Override
    public void onReCalculateRouteForTrafficJam() {
        //拥堵后重新计算路线回调
    }

    @Override
    public void onArrivedWayPoint(int wayID) {
        //到达途径点
    }

    @Override
    public void onGpsOpenStatus(boolean enabled) {
        //GPS开关状态回调
    }

    @Override
    public void onNaviSetting() {
        //底部导航设置点击回调
    }

    @Override
    public void onNaviMapMode(int isLock) {
        //地图的模式,锁屏或锁车
    }

    @Override
    public void onNaviCancel() {
        finish();
    }


    @Override
    public void onNaviTurnClick() {
        //转弯view的点击回调
    }

    @Override
    public void onNextRoadClick() {
        //下一个道路View点击回调
    }


    @Override
    public void onScanViewButtonClick() {
        //全览按钮点击回调
    }

    @Deprecated
    @Override
    public void onNaviInfoUpdated(AMapNaviInfo naviInfo) {
        //过时
    }

    @Override
    public void onNaviInfoUpdate(NaviInfo naviinfo) {
        //导航过程中的信息更新,请看NaviInfo的具体说明
    }

    @Override
    public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) {
        //已过时
    }

    @Override
    public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {
        //已过时
    }

    @Override
    public void showCross(AMapNaviCross aMapNaviCross) {
        //显示转弯回调
    }

    @Override
    public void hideCross() {
        //隐藏转弯回调
    }

    @Override
    public void showLaneInfo(AMapLaneInfo[] laneInfos, byte[] laneBackgroundInfo, byte[] laneRecommendedInfo) {
        //显示车道信息

    }

    @Override
    public void hideLaneInfo() {
        //隐藏车道信息
    }

    @Override
    public void onCalculateMultipleRoutesSuccess(int[] ints) {
        //多路径算路成功回调
    }

    @Override
    public void notifyParallelRoad(int i) {
        if (i == 0) {
            Toast.makeText(this, "当前在主辅路过渡", Toast.LENGTH_SHORT).show();
            Log.d("wlx", "当前在主辅路过渡");
            return;
        }
        if (i == 1) {
            Toast.makeText(this, "当前在主路", Toast.LENGTH_SHORT).show();

            Log.d("wlx", "当前在主路");
            return;
        }
        if (i == 2) {
            Toast.makeText(this, "当前在辅路", Toast.LENGTH_SHORT).show();

            Log.d("wlx", "当前在辅路");
        }
    }

    @Override
    public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {
        //更新交通设施信息
    }

    @Override
    public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
        //更新巡航模式的统计信息
    }


    @Override
    public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {
        //更新巡航模式的拥堵信息
    }


    @Override
    public void onLockMap(boolean isLock) {
        //锁地图状态发生变化时回调
    }

    @Override
    public void onNaviViewLoaded() {
        Log.d("wlx", "导航页面加载成功");
        Log.d("wlx", "请不要使用AMapNaviView.getMap().setOnMapLoadedListener();会overwrite导航SDK内部画线逻辑");
    }

    @Override
    public boolean onNaviBackClick() {
        return false;
    }


}

到这里简单的导航工具就搞定了,接下来就是在主界面进行调用导航功能:
    private void naviMapStart(Marker marker) {
        // 导航
        // 起点终点列表
        ArrayList startPoints = new ArrayList();
        ArrayList endPoints = new ArrayList();
        LatLng endLatLng = marker.getPosition();
        NaviLatLng endNaviLatLng = new NaviLatLng(endLatLng.latitude,
                endLatLng.longitude);
        endPoints.add(endNaviLatLng);

        NaviLatLng startNaviLatLng = new NaviLatLng(latLonPoint.latitude,
                latLonPoint.longitude);
        startPoints.add(startNaviLatLng);

        // DrivingSaveMoney--省钱
        // DrivingShortDistance--最短距离
        // DrivingNoExpressways--不走高速
        // DrivingFastestTime--最短时间
        // DrivingAvoidCongestion--避免拥堵

//        AMapNavi.getInstance(SearchActivity.this)
//                .calculateDriveRoute(startPoints, endPoints, null,
//                        AMapNavi.DrivingShortDistance);
        SearchActivity.startPoints = startPoints;
        SearchActivity.endPoints = endPoints;
        Intent intent = new Intent(SearchActivity.this,AMapNaviActivity.class);
        startActivity(intent);
    }
致此高德地图关于地图使用,定位功能,检索功能,导航功能就完成了。

附上demo


使用后遇到64位CPU架构兼容报错问题,坎坷解决7种架构兼容问题:
CPU so文件兼容方法

你可能感兴趣的:(Android基础)