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

来源:互联网 发布:java继承接口的关键字 编辑:程序博客网 时间:2024/05/21 17:48

附上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<PoiItem> 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<NaviLatLng> sList = new ArrayList<NaviLatLng>();    protected  List<NaviLatLng> eList = new ArrayList<NaviLatLng>();    protected List<NaviLatLng> 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<NaviLatLng> startPoints = new ArrayList<NaviLatLng>();        ArrayList<NaviLatLng> endPoints = new ArrayList<NaviLatLng>();        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文件兼容方法
0 0