附上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文件兼容方法