Android中集成高德地图SDK实现地图定位和导航功能(二)
我们接着上一篇文章开始继续实现android中集成高德地图的SDK实现地图 定位,搜索,导航的功能
如何让地图在手机上实现呢?
1.配置AndroidManifest 中的权限申请
可以参考官方文档
<!--允许访问网络,必选权限--><uses-permission android:name="android.permission.INTERNET" /><!--允许获取精确位置,实时导航为必选--><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><!--允许获取粗略位置,实时导航为必选--><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><!--允许获取设备和运营商信息,用于问题排查和网络定位(无gps情况下的定位),若需网络定位功能则必选--><uses-permission android:name="android.permission.READ_PHONE_STATE" /><!--允许获取网络状态,用于网络定位(无gps情况下的定位),若需网络定位功能则必选--><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><!--允许获取wifi网络信息,用于网络定位(无gps情况下的定位),若需网络定位功能则必选--><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><!--允许获取wifi状态改变,用于网络定位(无gps情况下的定位),若需网络定位功能则必选--><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><!--后台获取位置信息,若需后台定位或持续导航则必选--><uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /><!--用于申请调用A-GPS模块,卫星定位加速--><uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /><!--允许写入扩展存储,用于写入缓存定位数据--><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!--用于用户链接蓝牙时,在导航组件页面的蓝牙连接提醒,建立链接后开发者可选用蓝牙通道进行tts播报--><uses-permission android:name="android.permission.BLUETOOTH" /><!--用与导航状态中保持屏幕常亮--><uses-permission android:name="android.permission.WAKE_LOCK"/><!--允许写设备缓存,用于问题排查--><uses-permission android:name="android.permission.WRITE_SETTINGS" /><!--允许读设备等信息,用于问题排查--><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
android6.0以后需要动态申请权限 这里我就不做详细解释了
设置高德地图的key
在androidMainfest文件的appliation 标签中添加之前在高的开发者平台上的key,代码如下
<meta-dataandroid:name="com.amap.api.v2.apikey"android:value="这个地方就是你之前申请的key" />
我的key是ba63b…
初始化地图控件
首先要先新创建一个承载地图的Activiy,然后初始化MapView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".activity.GaodeMapActivity"android:orientation="vertical"><com.amap.api.maps.MapViewandroid:id="@+id/gaode_map"android:layout_width="match_parent"android:layout_height="match_parent"tools:layout_editor_absoluteX="16dp"tools:layout_editor_absoluteY="39dp"></com.amap.api.maps.MapView></LinearLayout>
然后再Activity中初始化地图空,这边需要了解到Activity生命周期和这个地图绑定到一起
public class GaodeMapActivity extends AppCompatActivity {private static final String TAG = "GaodeMapActivity";private MapView mapView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_gaode_map);// 这一步操作就设置高德地图中的隐私合规,不然可能会出现地图无法正确加载的问题MapsInitializer.updatePrivacyShow(this,true,true);MapsInitializer.updatePrivacyAgree(this,true);//初始化地图控件mapView = (MapView) findViewById(R.id.gaode_map);//这个地方需要捕获下异常,不然会出现编译不过的情况try {mLocationClient = new AMapLocationClient(GaodeMapActivity.this);}catch (Exception e) {Log.e(TAG, e.getMessage());}mapView.onCreate(savedInstanceState);if (aMap == null) {//展示地图aMap = mapView.getMap();Log.i(TAG,"展示地图");}@Overrideprotected void onDestroy() {super.onDestroy();mapView.onDestroy();}@Overrideprotected void onResume() {super.onResume();mapView.onResume();}@Overrideprotected void onPause() {super.onPause();mapView.onPause();}@Overridepublic void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) {super.onSaveInstanceState(outState, outPersistentState);//在activity保存时,同时也保存地图mapView.onSaveInstanceState(outState);}
效果如上图所示,这就完成了第一步地图的展示
2.定位蓝点
参考官方文档
完整的GaodeActivity的代码如下 因为是一个demo,所以代码写的比较潦草,多多担待
private static final String TAG = "GaodeMapActivity";private MapView mapView;private AMap aMap = null;private double lat;private double lon;public AMapLocationClient mLocationClient = null;public AMapLocationClientOption mLocationOption = null;private Button btn_search;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_gaode_map);btn_search = findViewById(R.id.btn_search);//这地方就是下面要讲的搜索导航功能btn_search.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Intent intent = new Intent(GaodeMapActivity.this, SearchActivity.class);startActivity(intent);}});MapsInitializer.updatePrivacyShow(this,true,true);MapsInitializer.updatePrivacyAgree(this,true);//初始化地图控件mapView = (MapView) findViewById(R.id.gaode_map);try {mLocationClient = new AMapLocationClient(GaodeMapActivity.this);}catch (Exception e) {Log.e(TAG, e.getMessage());}//设置定位回调监听mLocationClient.setLocationListener(mLocationListener);mapView.onCreate(savedInstanceState);if (aMap == null) {//展示地图aMap = mapView.getMap();Log.i(TAG,"展示地图");}MyLocationStyle myLocationStyle;myLocationStyle = new MyLocationStyle();myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE); //持续定位//设置连续定位模式下定位间隔myLocationStyle.interval(2000);myLocationStyle.strokeWidth(20f);aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
//aMap.getUiSettings().setMyLocationButtonEnabled(true);设置默认定位按钮是否显示,非必需设置。aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);myLocationStyle.showMyLocation(true);}public AMapLocationListener mLocationListener = new AMapLocationListener() {@Overridepublic 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);//定位时间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信息lat = amapLocation.getLatitude();lon = amapLocation.getLongitude();Log.v("pcw","lat : "+lat+" lon : "+lon);// 设置当前地图显示为当前位置aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lon), 15));MarkerOptions markerOptions = new MarkerOptions();markerOptions.position(new LatLng(lat, lon));markerOptions.title("当前位置");markerOptions.visible(true);BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_background));markerOptions.icon(bitmapDescriptor);aMap.addMarker(markerOptions);} else {//显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。Toast.makeText(GaodeMapActivity.this,amapLocation.getErrorCode() + ", errInfo:"+ amapLocation.getErrorInfo(), Toast.LENGTH_SHORT).show();}}}};@Overrideprotected void onDestroy() {super.onDestroy();mapView.onDestroy();}@Overrideprotected void onResume() {super.onResume();mapView.onResume();}@Overrideprotected void onPause() {super.onPause();mapView.onPause();}@Overridepublic void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) {super.onSaveInstanceState(outState, outPersistentState);//在activity保存时,同时也保存地图mapView.onSaveInstanceState(outState);}
实现后的效果如下
3.实现搜索功能
1.首先我们要创建一个搜索的Activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".activity.SearchActivity"android:orientation="vertical"><EditTextandroid:id="@+id/search_edit"android:layout_width="match_parent"android:layout_height="wrap_content"/><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/search_rv"android:layout_width="match_parent"android:layout_height="match_parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintTop_toBottomOf="@+id/search_edit"app:layout_constraintVertical_bias="1.0"tools:layout_editor_absoluteX="-51dp"/>
</LinearLayout>
搜索item 的布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="18dp"android:orientation="vertical"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="城市"android:textSize="18sp"android:id="@+id/search_adapter_text"/></LinearLayout>
3.要有一个Adapter 来给Recyclerview展示数据
public class RvAdapter extends RecyclerView.Adapter<RvAdapter.ViewHolder> implements View.OnClickListener {private final ArrayList<Tip> list;private final Context context;private final RecyclerView rv;private OnItemClickListener mOnItemClickListener;public RvAdapter(ArrayList<Tip> list, Context context, RecyclerView rv) {this.list = list;this.context = context;this.rv = rv;}@Overridepublic void onClick(View view) {int position = rv.getChildAdapterPosition(view);//程序执行到此,会去执行具体实现的onItemClick()方法if (mOnItemClickListener != null) {mOnItemClickListener.onItemClick(rv, view, position, list.get(position));Log.i("TAG", "onClick: "+position);}}public interface OnItemClickListener{void onItemClick(RecyclerView recyclerView,View view, int position,Tip data);}public void setmOnItemClickListener(OnItemClickListener clickListener) {this.mOnItemClickListener = clickListener;}public void setData(List<Tip> list) {if (list != null) {this.list.clear();this.list.addAll(list);notifyDataSetChanged();Log.i("TAG", "setData: "+ list);}}@Overridepublic RvAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {//View view = LayoutInflater.from(context).inflate(R.layout.search_item, parent ,false);View view = View.inflate(context, R.layout.search_item, null);view.setOnClickListener(this);return new ViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {Tip tip = list.get(position);holder.textView.setText(tip.getName());Log.i("TAG", "onBindViewHolder: getName= "+tip.getName());}@Overridepublic int getItemCount() {return list.size();}static class ViewHolder extends RecyclerView.ViewHolder{private TextView textView;public ViewHolder(@NonNull View itemView) {super(itemView);textView = itemView.findViewById(R.id.search_adapter_text);}}
4.下面就是SearchActivty 的代码
public class SearchActivity extends AppCompatActivity implements Inputtips.InputtipsListener, TextWatcher,RvAdapter.OnItemClickListener {private RvAdapter rvAdapter;private Inputtips inputtips;private AMapNavi aMapNavi;private EditText editText;private RecyclerView recyclerView;private ArrayList<Tip> list = new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_search);editText = findViewById(R.id.search_edit);editText.addTextChangedListener(this);recyclerView = (RecyclerView) findViewById(R.id.search_rv);LinearLayoutManager layoutManager = new LinearLayoutManager(SearchActivity.this, RecyclerView.VERTICAL, false);recyclerView.setLayoutManager(layoutManager);rvAdapter = new RvAdapter(list,SearchActivity.this,recyclerView);rvAdapter.setmOnItemClickListener(this);recyclerView.setAdapter(rvAdapter);inputtips = new Inputtips(this,(InputtipsQuery) null);inputtips.setInputtipsListener(this);}@Overridepublic void onGetInputtips(List<Tip> list, int i) {Log.i("Tag","onGetInputtips data = "+list);rvAdapter.setData(list);}@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {InputtipsQuery inputtipsQuery = new InputtipsQuery(String.valueOf(charSequence),null);inputtipsQuery.setCityLimit(true);inputtips.setQuery(inputtipsQuery);inputtips.requestInputtipsAsyn();}@Overridepublic void afterTextChanged(Editable editable) {}@Overridepublic void onItemClick(RecyclerView parent, View view, int postion, Tip data) {}
这就完成了搜索功能,效果如下图
4.导航功能
官方文档参考
1.我们需要通过AmapNaviPage来启动,他是一个单例模式
//导航参数对象(起点,途径,终点,导航方式)DRIVER是导航方式(驾驶,步行...当前为驾驶)ROUTE会计算路程选择AmapNaviParams params = new AmapNaviParams(null, null, poi, AmapNaviType.DRIVER, AmapPageType.ROUTE);//传递上下文和导航参数AmapNaviPage.getInstance().showRouteActivity(getApplicationContext(), params, null);
2.声明定位 service 组件需在 AndroidManifest.xml 中声明定位 service 组件。请在application标签中声明service 组件,添加如下代码:
<service android:name="com.amap.api.location.APSService"/>
3.还要再AndroidMainfest 中声明导航组件的Activity
<activityandroid:name="com.amap.api.navi.AmapRouteActivity"android:theme="@android:style/Theme.NoTitleBar"android:configChanges="orientation|keyboardHidden|screenSize|navigation" />
然后附上完整的SearchActivity的代码
public class SearchActivity extends AppCompatActivity implements Inputtips.InputtipsListener, TextWatcher,RvAdapter.OnItemClickListener {private RvAdapter rvAdapter;private Inputtips inputtips;private AMapNavi aMapNavi;private EditText editText;private RecyclerView recyclerView;private ArrayList<Tip> list = new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_search);editText = findViewById(R.id.search_edit);editText.addTextChangedListener(this);recyclerView = (RecyclerView) findViewById(R.id.search_rv);LinearLayoutManager layoutManager = new LinearLayoutManager(SearchActivity.this, RecyclerView.VERTICAL, false);recyclerView.setLayoutManager(layoutManager);rvAdapter = new RvAdapter(list,SearchActivity.this,recyclerView);rvAdapter.setmOnItemClickListener(this);recyclerView.setAdapter(rvAdapter);inputtips = new Inputtips(this,(InputtipsQuery) null);inputtips.setInputtipsListener(this);//这是隐私合规接口,如果不加,可能出现地图加载不出来的问题NaviSetting.updatePrivacyShow(this, true, true);NaviSetting.updatePrivacyAgree(this, true);try {//这个地方也许捕获一下异常,不然编译不过去aMapNavi = AMapNavi.getInstance(this);}catch (Exception e){Log.e("TAG", e.getMessage());}if (aMapNavi!=null) {//设置内置语音播报aMapNavi.setUseInnerVoice(true, false);}}@Overridepublic void onGetInputtips(List<Tip> list, int i) {Log.i("Tag","onGetInputtips data = "+list);rvAdapter.setData(list);}@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {InputtipsQuery inputtipsQuery = new InputtipsQuery(String.valueOf(charSequence),null);inputtipsQuery.setCityLimit(true);inputtips.setQuery(inputtipsQuery);inputtips.requestInputtipsAsyn();}@Overridepublic void afterTextChanged(Editable editable) {}@Overridepublic void onItemClick(RecyclerView parent, View view, int postion, Tip data) {Log.i("TAG", "onItemClick: 点击了"+postion+"条");//得到点击的坐标LatLonPoint point = data.getPoint();Log.i("Tag", "坐标为"+point);//得到经纬度Poi poi = new Poi(data.getName(), new LatLng(point.getLatitude(), point.getLongitude()), data.getPoiID());//导航参数对象(起点,途径,终点,导航方式)DRIVER是导航方式(驾驶,步行...当前为驾驶)ROUTE会计算路程选择AmapNaviParams params = new AmapNaviParams(null, null, poi, AmapNaviType.DRIVER, AmapPageType.ROUTE);//传递上下文和导航参数AmapNaviPage.getInstance().showRouteActivity(getApplicationContext(), params, null);}
}
下面附上实现效果图
这个地方还要插一句 需要在AndroidMainfest 的 applcation 中添加 这样一段代码不然会点击开始导航会出现奔溃 详情请参考 为啥要添加下面的代码
android:allowNativeHeapPointerTagging="false"
这就是以上所有的内容,如有前期准备工作搞不定的请参考我的上一篇:Android中集成高德地图SDK实现地图定位和导航功能(一)
Android中集成高德地图SDK实现地图定位和导航功能(二)相关推荐
- Android中集成高德地图SDK实现地图定位和导航功能(一)
一.前期准备工作 1.在高德地图开发者平创建一个自己的项目 名称和应用类型随便填 2.添加Key 1.添加key 2.获取SHA1值 2.1.使用windwos+R 输入cmd 打开控制窗口 输入 w ...
- Android中集成高德API
1.创建一个项目 2.注册高德开发用户,并来到控制台,点击应用管理->我的应用,然后创建新应用 地址:https://lbs.amap.com/ 3. 点击添加 获取SHA1代码(我这里使用的是 ...
- 基于百度地图sdk的地图app开发(七)——导航和模拟导航
这是基于百度地图sdk的地图app开发系列博客第七篇 代码仓库位置:https://github.com/YanhuiLu89/lmap.git 上一篇 基于百度地图sdk的地图app开发(六)--路 ...
- Android中集成Jpush实现推送消息通知与根据别名指定推送附示例代码下载
场景 经常会有后台服务向Android推送消息通知的情况. 实现 首先在Android Studio中新建一个Android应用 在Project根目录的build.gradle中配置了jcenter ...
- Android中集成第三方库的方法和问题
Android中集成第三方库的方法和问题 声明: 1. 本文參考了网上同学们的现有成果,在此表示感谢,參考资料在文后有链接. 2. 本文的重点在第三部分,是在开发中遇到的问题及解决的方法.第一,第二部 ...
- Vue中集成高德地图API实现定位与自定义样式信息窗体
场景 若依前后端分离版手把手教你本地搭建环境并运行项目: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108465662 在上面 ...
- Android 整合高德地图SDK实现 地图预览,定位,模拟导航
一.准备工作 1. 到高德地图官方网申请key: 我的应用 | 高德控制台 2. 申请key方法请参考:获取Key-创建工程-开发指南-Android 地图SDK | 高德地图API 3. 出现的问题 ...
- Android 高德地图黑屏定位,Android Fragment集成高德地图黑屏的问题解决方案
官方给的3.0Map的集成api说了: MapView 是 Android View 类的一个子类,它可以帮助您在 Android View 中放置地图,它是应用程序和窗口部件的基本构建类.MapVi ...
- Android开发知识(十)快速接入高德地图SDK(地图+定位+标记+路线规划+搜索)
文章目录 申请接入流程 显示高德地图 显示定位 Marker 显示地图标记 Route 路线规划 Search 搜索 申请接入流程 1.首先到 [ 高德地图API官网] 申请注册帐号 2.进入控制台, ...
最新文章
- matlab实现图像的高斯滤波
- linux系统适合电脑小白吗,linux小白说说用linux的感受
- Apache Flink 在实时金融数据湖的应用
- ios学习--TableView详细解释
- wcf:rest_REST:管理多对多关系
- pytorch中的torch.rand(),torch.randn(),torch.randerm()的关系
- 创建触发器,将数据库中表的修改记录进日志表
- python找房源_python抓取链家房源信息(二)
- mysql replace的弊端_MySQL谨慎使用replace into
- 解析JavaScript模拟事件的注意要点
- 通过帮网友解答问题训练同学们使用awk,sed案例
- 数据库之DB2数据库备份
- MAC中LateX出字体问题
- 屏蔽百度搜索右边的热点和广告推广
- Asp.Net MVC4.0 官方教程 入门指南之八--为Movie模型和库表添加字段
- 【强烈推荐收藏】坚持3个月爆肝华为机试108题C++全解(适合新手入门,就业必刷套题)
- gitLab数据备份和迁移
- 西门子1200 PLC CRC效验程序功能块
- 如何使用N1盒子实现自动撸豆
- 百度无法爬取Github Pages静态网站解决方案