最进简单研究了一下关于高德地图的使用,,简单实现了定位搜素,以及驾车的路径规划,一下将介绍我的实现过程:
先展示一下实现的简单效果:
首先需要进行配置,配置详情如下:
1、打开高德开放平台
2、创建应用
3、添加新key:dd9dde5da25a5811031cb1beb5a******
sha1值获取:找到系统默认的debug.keystore(C:\Users\Administrator\.android\debug.keystore)
在cmd窗口或android studio 中的Terminal中执行命令:keytool -v -list -keystore keystore地址
4、添加jar和so库(不要添加v4包)
so库添加方式:
第一种:使用默认配置,不需要修改build.gradle。在 main 目录下创建文件夹 jniLibs (如果有就不需要创建了),将下载文件的 armeabi 文件夹复制到这个目录下,如果已经有这个目录,将下载的 so 库复制到这个目录即可。
第二种:使用自定义配置,将下载文件的 armeabi 文件夹复制到 libs 目录,如果有这个目录,请将下载的 so 库复制到这个目录,然后打开build.gradle,找到 sourceSets 标签:
sourceSets{
main{
jniLibs.srcDirs = ['libs']
}
}
5、配置
1、配置AndroidManifest.xml
1、声明Service组件
<service android:name="com.amap.api.location.APSService"></service>
2、声明权限
<!--用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!--用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!--用于获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<!--用于访问网络,网络定位需要上网-->
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<!--用于读取手机当前的状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<!--用于写入缓存数据到扩展存储卡-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<!--用于申请调用A-GPS模块-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
<!--用于申请获取蓝牙信息进行室内定位-->
<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>
3、设置高德Key
<meta-data android:name="com.amap.api.v2.apikey" android:value="key">//开发者申请的key
</meta-data>
下面实现定位和蓝点显示:
1、声明成员变量
//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
2、初始化定位
//初始化定位
mLocationClient = new AMapLocationClient(getApplicationContext());
3、设置定位回调监听
mLocationClient.setLocationListener(new AMapLocationListener(){
@Override
public void onLocationChanged(AMapLocation aMapLocation) {
//获取定位结果
}
});
4、定位结果处理
if (aMapLocation != null) {
if (aMapLocation.getErrorCode() == 0) {
//可在其中解析amapLocation获取相应内容。
int locationType = aMapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见定位类型表
double latitude = aMapLocation.getLatitude();//获取纬度
double longitude = aMapLocation.getLongitude();//获取经度
float accuracy = aMapLocation.getAccuracy();//获取精度信息
String address = aMapLocation.getAddress();//地址,如果option中设置isNeedAddress为false,则没有此结果,网络定位结果中会有地址信息,GPS定位不返回地址。
aMapLocation.getCountry();//国家信息
aMapLocation.getProvince();//省信息
aMapLocation.getCity();//城市信息
aMapLocation.getDistrict();//城区信息
aMapLocation.getStreet();//街道信息
aMapLocation.getStreetNum();//街道门牌号信息
aMapLocation.getCityCode();//城市编码
aMapLocation.getAdCode();//地区编码
aMapLocation.getAoiName();//获取当前定位点的AOI信息
aMapLocation.getBuildingId();//获取当前室内定位的建筑物Id
aMapLocation.getFloor();//获取当前室内定位的楼层
//获取定位时间
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(aMapLocation.getTime());
df.format(date);
Log.e("TAG", "纬度:" + latitude + " 经度:" + longitude + " 地址:" + address);
} else {
//定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。
Log.e("AmapError", "location Error, ErrCode:"
+ aMapLocation.getErrorCode() + ", errInfo:"
+ aMapLocation.getErrorInfo());
}
}
7、地图
1、在xml中声明MapView控件
2、在activity中初始化MapView
3、在声明周期中调用MapView的声明周期:onCreate\onResume\onPause\onDestroy\onSaveInstanceState
8、蓝点
1、创建MyLocationStyle对象: style = new MyLocationStyle();
2、设置定位间隔时间:style.interval(2000);
3、设置圆形区域:
1、圆形区域填充色:style.radiusFillColor(Color.rgb(0, 255, 255));
2、圆形区域(以定位位置为圆心,定位半径的圆形区域)的边框颜色:style.strokeColor(Color.rgb(0, 100, 255));
3、圆形区域(以定位位置为圆心,定位半径的圆形区域)的边框宽度:style.strokeWidth(2F);
4、设置定位模式和蓝点模式:(选择其一)
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);//只定位一次。
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE) ;//定位一次,且将视角移动到地图中心点。
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW) ;//连续定位、且将视角移动到地图中心点,定位蓝点跟随设备移动。(1秒1次定位)
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);//连续定位、且将视角移动到地图中心点,地图依照设备方向旋转,定位点会跟随设备移动。(1秒1次定位)
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)默认执行此种模式。
//以下四种模式从5.1.0版本开始提供
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)默认执行此种模式。
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,定位点依照设备方向旋转,并且蓝点会跟随设备移动。
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,并且蓝点会跟随设备移动。
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,地图依照设备方向旋转,并且蓝点会跟随设备移动。
POI检索,查找位置:
1、创建PoiSearch.Query对象
query = new PoiSearch.Query(keyWord, "", cityCode);
//keyWord表示搜索字符串,
//第二个参数表示POI搜索类型,二者选填其一,选用POI搜索类型时建议填写类型代码,码表可以参考下方(而非文字)
//cityCode表示POI搜索区域,可以是城市编码也可以是城市名称,也可以传空字符串,空字符串代表全国在全国范围内进行搜索
query.setPageSize(10);// 设置每页最多返回多少条poiitem
query.setPageNum(currentPage);//设置查询页码
2、构造 PoiSearch 对象,并设置监听。
poiSearch = new PoiSearch(this, query);
poiSearch.setOnPoiSearchListener(this);
3、调用 PoiSearch 的 searchPOIAsyn() 方法发送请求。
poiSearch.searchPOIAsyn();
4、通过回调接口 onPoiSearched 解析返回的结果,将查询到的 POI 以绘制点的方式显示在地图上。
覆盖物(绘制点)
1、创建绘制点:
LatLng latLng = new LatLng(39.906901,116.397972);
final Marker marker = aMap.addMarker(new MarkerOptions().position(latLng).title("北京").snippet("DefaultMarker"));
2、设置Marker点击事件
// 定义 Marker 点击事件监听
AMap.OnMarkerClickListener markerClickListener = new AMap.OnMarkerClickListener() {
// marker 对象被点击时回调的接口
// 返回 true 则表示接口已响应事件,否则返回false
@Override
public boolean onMarkerClick(Marker marker) {
return false;
}
};
// 绑定 Marker 被点击事件
mAMap.setOnMarkerClickListener(markerClickListener);
路径规划,其中实现了驾车,骑车,以及不行等方式
1、路径规划实现
1、公共交通
aMap.clear();// 清理地图上的所有覆盖物
if (errorCode == AMapException.CODE_AMAP_SUCCESS) {
if (result != null && result.getPaths() != null) {
if (result.getPaths().size() > 0) {
BusResultListAdapter mBusResultListAdapter = new BusResultListAdapter(mContext, result);
mBusResultList.setAdapter(mBusResultListAdapter);
} else if (result != null && result.getPaths() == null) {
ToastUtil.show(mContext, R.string.no_result);
}
} else {
ToastUtil.show(mContext, R.string.no_result);
}
} else {
ToastUtil.showerror(this.getApplicationContext(), errorCode);
}
2、自驾
aMap.clear();// 清理地图上的所有覆盖物
if (errorCode == AMapException.CODE_AMAP_SUCCESS) {
if (result != null && result.getPaths() != null) {
if (result.getPaths().size() > 0) {
mDriveRouteResult = result;
final DrivePath drivePath = mDriveRouteResult.getPaths()
.get(0);
DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(
mContext, aMap, drivePath,
mDriveRouteResult.getStartPos(),
mDriveRouteResult.getTargetPos(), null);
drivingRouteOverlay.setNodeIconVisibility(false);//设置节点marker是否显示
drivingRouteOverlay.setIsColorfulline(true);//是否用颜色展示交通拥堵情况,默认true
drivingRouteOverlay.removeFromMap();
drivingRouteOverlay.addToMap();
drivingRouteOverlay.zoomToSpan();
} else if (result != null && result.getPaths() == null) {
ToastUtil.show(mContext, R.string.no_result);
}
} else {
ToastUtil.show(mContext, R.string.no_result);
}
} else {
ToastUtil.showerror(this.getApplicationContext(), errorCode);
}
3、走路
aMap.clear();// 清理地图上的所有覆盖物
if (errorCode == AMapException.CODE_AMAP_SUCCESS) {
if (result != null && result.getPaths() != null) {
if (result.getPaths().size() > 0) {
mWalkRouteResult = result;
final WalkPath walkPath = mWalkRouteResult.getPaths()
.get(0);
WalkRouteOverlay walkRouteOverlay = new WalkRouteOverlay(
this, aMap, walkPath,
mWalkRouteResult.getStartPos(),
mWalkRouteResult.getTargetPos());
walkRouteOverlay.removeFromMap();
walkRouteOverlay.addToMap();
walkRouteOverlay.zoomToSpan();
} else if (result != null && result.getPaths() == null) {
ToastUtil.show(mContext, R.string.no_result);
}
} else {
ToastUtil.show(mContext, R.string.no_result);
}
} else {
ToastUtil.showerror(this.getApplicationContext(), errorCode);
}
4、骑车
aMap.clear();// 清理地图上的所有覆盖物
if (errorCode == AMapException.CODE_AMAP_SUCCESS) {
if (result != null && result.getPaths() != null) {
if (result.getPaths().size() > 0) {
mRideRouteResult = result;
final RidePath ridePath = mRideRouteResult.getPaths()
.get(0);
RideRouteOverlay rideRouteOverlay = new RideRouteOverlay(
this, aMap, ridePath,
mRideRouteResult.getStartPos(),
mRideRouteResult.getTargetPos());
rideRouteOverlay.removeFromMap();
rideRouteOverlay.addToMap();
rideRouteOverlay.zoomToSpan();
} else if (result != null && result.getPaths() == null) {
ToastUtil.show(mContext, R.string.no_result);
}
} else {
ToastUtil.show(mContext, R.string.no_result);
}
} else {
ToastUtil.showerror(this.getApplicationContext(), errorCode);
}
2、路径规划之监听中接受数据
需要复制的文件:(需修改包引用)
1、overlay包下所有类
2、com\amap\map3d\demo\util包下:
AMapUtil.java
ChString.java
ToastUtil.java
3、res\drawable-hdpi下:
amap_bus.png
amap_car.png
amap_end.png
amap_man.png
amap_ride.png
amap_start.png
amap_through.png
dir1.png-dir16.png
4、res\values下strings.xml中:<string name="no_result">对不起,没有搜索到相关数据!</string>
至此,简单的定位以及简单的路径规划介绍完毕,下面附上完整代码:
Xml布局代码:
<LinearLayout android:id="@+id/li" android:weightSum="10" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/city" android:hint="城市" android:layout_weight="2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <EditText android:id="@+id/content" android:hint="具体位置" android:layout_weight="6" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/search" android:text="搜索" android:layout_weight="2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <com.amap.api.maps.MapView android:id="@+id/map" android:layout_below="@+id/li" android:layout_width="match_parent" android:layout_height="match_parent"/>
JAVA代码:
package feng.jiyun.com.gaodeactivity; import android.location.Location; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import com.amap.api.maps.AMap; import com.amap.api.maps.MapView; import com.amap.api.maps.model.LatLng; import com.amap.api.maps.model.Marker; import com.amap.api.maps.model.MarkerOptions; import com.amap.api.maps.model.MyLocationStyle; import com.amap.api.services.core.AMapException; import com.amap.api.services.core.LatLonPoint; import com.amap.api.services.core.PoiItem; import com.amap.api.services.poisearch.PoiResult; import com.amap.api.services.poisearch.PoiSearch; import com.amap.api.services.route.BusRouteResult; import com.amap.api.services.route.DrivePath; import com.amap.api.services.route.DriveRouteResult; import com.amap.api.services.route.RideRouteResult; import com.amap.api.services.route.RouteSearch; import com.amap.api.services.route.WalkRouteResult; import java.util.ArrayList; import feng.jiyun.com.gaodeactivity.overlay.DrivingRouteOverlay; import feng.jiyun.com.gaodeactivity.overlay.ToastUtil; public class MainActivity extends AppCompatActivity implements View.OnClickListener, PoiSearch.OnPoiSearchListener, RouteSearch.OnRouteSearchListener { private MapView map; private AMap amap; MyLocationStyle myLocationStyle; private EditText city; private EditText content; private Button search; private PoiSearch.Query query; private PoiSearch searchs; private RouteSearch routeSearch; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(savedInstanceState); } private void initView(Bundle savedInstanceState) { map = (MapView) findViewById(R.id.map); map.onCreate(savedInstanceState); amap = map.getMap(); myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType,默认也会执行此种模式。 myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。 myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,定位点依照设备方向旋转,并且蓝点会跟随设备移动。 amap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style amap.getUiSettings().setMyLocationButtonEnabled(true); amap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。 city = (EditText) findViewById(R.id.city); city.setOnClickListener(this); content = (EditText) findViewById(R.id.content); content.setOnClickListener(this); search = (Button) findViewById(R.id.search); search.setOnClickListener(this); //路径规划 amap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker marker) { Location myLocation = amap.getMyLocation(); String s = myLocation.toString(); //2、获取终点经纬度 LatLng position = marker.getPosition(); LatLonPoint from = new LatLonPoint(myLocation.getLatitude(),myLocation.getLongitude()); Log.e("TAG",myLocation.getLatitude()+" "+myLocation.getLongitude()); LatLonPoint to = new LatLonPoint(position.latitude,position.longitude); RouteSearch.FromAndTo fat = new RouteSearch.FromAndTo(from,to); RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(fat,RouteSearch.DRIVING_MULTI_STRATEGY_FASTEST_SHORTEST_AVOID_CONGESTION,null,null,""); routeSearch = new RouteSearch(MainActivity.this); routeSearch.setRouteSearchListener(MainActivity.this); routeSearch.calculateDriveRouteAsyn(query); return false; } }); } @Override protected void onDestroy() { super.onDestroy(); //在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图 map.onDestroy(); } @Override protected void onResume() { super.onResume(); //在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图 map.onResume(); } @Override protected void onPause() { super.onPause(); //在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制 map.onPause(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态 map.onSaveInstanceState(outState); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.search: submit(); break; } } private void submit() { // validate String cityString = city.getText().toString().trim(); if (TextUtils.isEmpty(cityString)) { Toast.makeText(this, "请输入城市", Toast.LENGTH_SHORT).show(); return; } String contentString = content.getText().toString().trim(); if (TextUtils.isEmpty(contentString)) { Toast.makeText(this, "请输入具体位置", Toast.LENGTH_SHORT).show(); return; } // TODO validate success, do something query = new PoiSearch.Query(contentString,"",cityString); query.setPageSize(10);// 设置每页最多返回多少条poiitem query.setPageNum(1);//设置查询页码 searchs = new PoiSearch(this, query); searchs.setOnPoiSearchListener(this); searchs.searchPOIAsyn(); } @Override public void onPoiSearched(PoiResult poiResult, int i) { ArrayList<PoiItem> pois = poiResult.getPois(); amap.clear(); for(PoiItem item:pois){ LatLonPoint latLonPoint = item.getLatLonPoint(); LatLng lat = new LatLng(latLonPoint.getLatitude(),latLonPoint.getLongitude()); MarkerOptions options = new MarkerOptions().position(lat).title(item.toString()).snippet("hello"); amap.addMarker(options); } } @Override public void onPoiItemSearched(PoiItem poiItem, int i) { } @Override public void onBusRouteSearched(BusRouteResult busRouteResult, int i) { Log.e("TAG","onBusRouteSearched"); } @Override public void onDriveRouteSearched(DriveRouteResult result, int errorCode) { amap.clear();// 清理地图上的所有覆盖物 if (errorCode == AMapException.CODE_AMAP_SUCCESS) { if (result != null && result.getPaths() != null) { if (result.getPaths().size() > 0) { DrivePath drivePath = result.getPaths().get(0); DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(MainActivity.this, amap, drivePath, result.getStartPos(), result.getTargetPos(), null); drivingRouteOverlay.setNodeIconVisibility(false);//设置节点marker是否显示 drivingRouteOverlay.setIsColorfulline(true);//是否用颜色展示交通拥堵情况,默认true drivingRouteOverlay.removeFromMap(); drivingRouteOverlay.addToMap(); drivingRouteOverlay.zoomToSpan(); } else if (result != null && result.getPaths() == null) { ToastUtil.show(MainActivity.this, R.string.no_result); } } else { ToastUtil.show(MainActivity.this, R.string.no_result); } } else { ToastUtil.showerror(this.getApplicationContext(), errorCode); } } @Override public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) { Log.e("TAG","onWalkRouteSearched"); } @Override public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) { Log.e("TAG","onRideRouteSearched"); } }
写的不好,请见谅,如发现问题请及时更正笔者