Android实现百度离线地图+gps定位

  • 关于
  • 效果图
    • 第一步,添加百度地图jar包及引用
    • 第二步,下载离线地图功能
    • 第三步,GPS定位+地图展示

关于

  这段时间,因为公司项目需求,要在内网下实现地图展示及个人定位上报功能,一开始接到这个需求比较懵逼也以为实现起来很简单,结果…我以为的离线地图和实际的百度提供的离线地图功能相差甚远。一开始是想着将离线地图通过后台copy至接口或者资源复制,但是因为种种原因离线地图没显示出来,现在想来应该是地图加载页面写的有问题或者就是缓存问题,这个等有时间研究下吧,项目太着急,只能先这样了。然后离线地图的下载则是直接copy的demo里面的离线地图下载,定位则是通过gps,至于基站没有考虑的原因之一是公司的测试手机么得手机卡。

效果图

图1 离线地图展示 图2 GPS定位

第一步,添加百度地图jar包及引用

  考虑到篇幅原因,我就直接把我之前百度地图使用基本配置的教程放上去,这里只需要参考其中配置地图引用的部分就好了,因为是离线地图估计百度地图的key可能不大需要,毕竟是离线地图使用鉴权也没必要Android关于百度地图的开发心得(笔记一(配置与基本使用))

第二步,下载离线地图功能

  这一部分是直接拿demo上的下载功能,他的下载功能及查看效果如下:

  直接贴代码了,新建一个activity页面,这里我是起的TestActivity:

public class TestActivity extends AppCompatActivity implements MKOfflineMapListener{private MKOfflineMap mOffline = null;private TextView cidView;private TextView stateView;private EditText cityNameView;// 已下载的离线地图信息列表private ArrayList<MKOLUpdateElement> localMapList = null;private LocalMapAdapter lAdapter = null;private LinearLayout mCityList;private LinearLayout mLocalMap;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);mOffline = new MKOfflineMap();mOffline.init(this);initView();}private void initView() {cidView = (TextView) findViewById(R.id.cityid);cityNameView = (EditText) findViewById(R.id.city);stateView = (TextView) findViewById(R.id.state);mCityList = (LinearLayout) findViewById(R.id.citylist_layout);mLocalMap = (LinearLayout) findViewById(R.id.localmap_layout);ListView hotCityList = (ListView) findViewById(R.id.hotcitylist);ArrayList<String> hotCities = new ArrayList<String>();final ArrayList<String> hotCityNames = new ArrayList<String>();// 获取热闹城市列表ArrayList<MKOLSearchRecord> records1 = mOffline.getHotCityList();if (records1 != null) {for (MKOLSearchRecord r : records1) {//V4.5.0起,保证数据不溢出,使用long型保存数据包大小结果hotCities.add(r.cityName + "(" + r.cityID + ")" + "   --" + this.formatDataSize(r.dataSize));hotCityNames.add(r.cityName);}}ListAdapter hAdapter = (ListAdapter) new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, hotCities);hotCityList.setAdapter(hAdapter);hotCityList.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {cityNameView.setText(hotCityNames.get(i));}});ListView allCityList = (ListView) findViewById(R.id.allcitylist);// 获取所有支持离线地图的城市ArrayList<String> allCities = new ArrayList<String>();final ArrayList<String> allCityNames = new ArrayList<String>();ArrayList<MKOLSearchRecord> records2 = mOffline.getOfflineCityList();if (records2 != null) {for (MKOLSearchRecord r : records2) {//V4.5.0起,保证数据不溢出,使用long型保存数据包大小结果allCities.add(r.cityName + "(" + r.cityID + ")" + "  --" + this.formatDataSize(r.dataSize));allCityNames.add(r.cityName);}}ListAdapter aAdapter = (ListAdapter) new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, allCities);allCityList.setAdapter(aAdapter);allCityList.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {cityNameView.setText(allCityNames.get(i));}});mLocalMap.setVisibility(View.GONE);mCityList.setVisibility(View.VISIBLE);// 获取已下过的离线地图信息localMapList = mOffline.getAllUpdateInfo();if (localMapList == null) {localMapList = new ArrayList<MKOLUpdateElement>();}ListView localMapListView = (ListView) findViewById(R.id.localmaplist);lAdapter = new LocalMapAdapter();localMapListView.setAdapter(lAdapter);}/*** 切换至城市列表** @param view*/public void clickCityListButton(View view) {mLocalMap.setVisibility(View.GONE);mCityList.setVisibility(View.VISIBLE);}/*** 切换至下载管理列表** @param view*/public void clickLocalMapListButton(View view) {mLocalMap.setVisibility(View.VISIBLE);mCityList.setVisibility(View.GONE);}/*** 搜索离线城市** @param view*/public void search(View view) {ArrayList<MKOLSearchRecord> records = mOffline.searchCity(cityNameView.getText().toString());if (records == null || records.size() != 1) {Toast.makeText(this, "不支持该城市离线地图", Toast.LENGTH_SHORT).show();return;}cidView.setText(String.valueOf(records.get(0).cityID));}/*** 开始下载** @param view*/public void start(View view) {int cityid = Integer.parseInt(cidView.getText().toString());mOffline.start(cityid);clickLocalMapListButton(null);Toast.makeText(this, "开始下载离线地图. cityid: " + cityid, Toast.LENGTH_SHORT).show();updateView();}/*** 暂停下载** @param view*/public void stop(View view) {int cityid = Integer.parseInt(cidView.getText().toString());mOffline.pause(cityid);Toast.makeText(this, "暂停下载离线地图. cityid: " + cityid, Toast.LENGTH_SHORT).show();updateView();}/*** 删除离线地图** @param view*/public void remove(View view) {int cityid = Integer.parseInt(cidView.getText().toString());mOffline.remove(cityid);Toast.makeText(this, "删除离线地图. cityid: " + cityid, Toast.LENGTH_SHORT).show();updateView();}/*** 更新状态显示*/public void updateView() {localMapList = mOffline.getAllUpdateInfo();if (localMapList == null) {localMapList = new ArrayList<MKOLUpdateElement>();}lAdapter.notifyDataSetChanged();}@Overrideprotected void onPause() {super.onPause();int cityid = Integer.parseInt(cidView.getText().toString());MKOLUpdateElement temp = mOffline.getUpdateInfo(cityid);if (temp != null && temp.status == MKOLUpdateElement.DOWNLOADING) {mOffline.pause(cityid);}}/*** V4.5.0起,保证数据不溢出,使用long型保存数据包大小结果*/public String formatDataSize(long size) {String ret = "";if (size < (1024 * 1024)) {ret = String.format("%dK", size / 1024);} else {ret = String.format("%.1fM", size / (1024 * 1024.0));}return ret;}@Overrideprotected void onDestroy() {super.onDestroy();// 退出时,销毁离线地图模块mOffline.destroy();}@Overridepublic void onGetOfflineMapState(int type, int state) {switch (type) {case MKOfflineMap.TYPE_DOWNLOAD_UPDATE:MKOLUpdateElement update = mOffline.getUpdateInfo(state);// 处理下载进度更新提示if (update != null) {stateView.setText(String.format("%s : %d%%", update.cityName, update.ratio));updateView();}break;case MKOfflineMap.TYPE_NEW_OFFLINE:// 有新离线地图安装Log.d("OfflineDemo", String.format("add offlinemap num:%d", state));break;case MKOfflineMap.TYPE_VER_UPDATE:// 版本更新提示// MKOLUpdateElement e = mOffline.getUpdateInfo(state);break;default:break;}}/*** 离线地图管理列表适配器*/public class LocalMapAdapter extends BaseAdapter {@Overridepublic int getCount() {return localMapList.size();}@Overridepublic Object getItem(int index) {return localMapList.get(index);}@Overridepublic long getItemId(int index) {return index;}@Overridepublic View getView(int index, View view, ViewGroup arg2) {MKOLUpdateElement e = (MKOLUpdateElement) getItem(index);view = View.inflate(TestActivity.this, R.layout.offline_localmap_list, null);initViewItem(view, e);return view;}void initViewItem(View view, final MKOLUpdateElement e) {Button display = (Button) view.findViewById(R.id.display);Button remove = (Button) view.findViewById(R.id.remove);TextView title = (TextView) view.findViewById(R.id.title);TextView update = (TextView) view.findViewById(R.id.update);TextView ratio = (TextView) view.findViewById(R.id.ratio);ratio.setText(e.ratio + "%");title.setText(e.cityName);if (e.update) {update.setText("可更新");} else {update.setText("最新");}if (e.ratio != 100) {display.setEnabled(false);} else {display.setEnabled(true);}remove.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View arg0) {mOffline.remove(e.cityID);updateView();}});display.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.putExtra("customStyle", true);intent.putExtra("x", e.geoPt.longitude);intent.putExtra("y", e.geoPt.latitude);intent.putExtra("level", 13.0f);intent.setClass(TestActivity.this, MapTypeDemo.class);startActivity(intent);}});}}}

  对应的item布局 offline_localmap_list.xml:

<?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="match_parent"android:orientation="horizontal"android:padding="10dip"><TextViewandroid:id="@+id/title"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="已下载城市 " /><TextViewandroid:id="@+id/update"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text=""android:textColor="#FF0000" /><TextViewandroid:id="@+id/ratio"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="" /><Buttonandroid:id="@+id/display"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="查看" /><Buttonandroid:id="@+id/remove"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"android:text="删除" /></LinearLayout>

  这里下载地图,我是将北京市的和我自己现在在的地方-南京市下载下来,因为一般如果定位失败都会默认展示北京的地图…所以一般下载两个地图就够了。

第三步,GPS定位+地图展示

  新增布局文件activity_letter_report.xml:

<?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"android:orientation="vertical"><!--这个是复用的标题栏,你可以直接去掉--><include layout="@layout/title_bar"/><com.baidu.mapapi.map.MapViewandroid:id="@+id/mapView"android:layout_width="match_parent"android:layout_height="match_parent"></com.baidu.mapapi.map.MapView></LinearLayout>

  修改LetterReportActivity.java,第一步,定义控件以及变量

private MapView mapView;
private BaiduMap mBaiduMap;
//自带定位管理,用于获取系统定位服务
private LocationManager lm;
//百度地图控件,用于覆盖点
private BitmapDescriptor bitmap;
//用于获取gps提供
private String privoderLc= "";

  在oncreate中实例化:

 lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);mapView = (MapView) findViewById(R.id.mapView);//初始化地图initMaps();Criteria criteria = new Criteria();criteria.setAccuracy(Criteria.ACCURACY_COARSE);criteria.setAccuracy(Criteria.ACCURACY_FINE);privoderLc = lm.getBestProvider(criteria, true);//初始化权限以及获取信息initMapGps();

  编写initMaps()方法:

 private void initMaps() {if (mBaiduMap == null)mBaiduMap = mapView.getMap();//获取地图实例View child = mapView.getChildAt(1);if (child != null && (child instanceof ImageView || child instanceof ZoomControls)) {child.setVisibility(View.GONE);}// 构建地图状态MapStatus.Builder builder = new MapStatus.Builder();// 默认 天安门LatLng center = new LatLng(39.915071, 116.403907);// 默认 11级float zoom = 11.0f;builder.target(center).zoom(zoom);MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(builder.build());// 设置地图状态mBaiduMap.setMapStatus(mapStatusUpdate);}

先初始化加载北京的离线地图,这样如果gps定位失败了也有默认地图展示。
  initMapGps()方法中

 private void initMapGps() {//初始化检测权限checkLocation();//更新定位信息updataLocation();}

  编写权限申请checkLocation()

private void checkLocation() {//这里用的是郭老师的权限请求框架PermissionX.init(this)        .permissions(Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION)/*  .onExplainRequestReason((scope, deniedList) -> {scope.showRequestReasonDialog(deniedList,"以下权限是必须权限","确定","取消");})*///   .onForwardToSettings((scope, deniedList) -> scope.showForwardToSettingsDialog(deniedList,"您需要去应用程序设置当中手动开启权限","去设置","暂不开启")).request(new RequestCallback() {@SuppressLint("MissingPermission")@Overridepublic void onResult(boolean allGranted, List<String> grantedList, List<String> deniedList) {if (allGranted){if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 20*1000, 0, listener);}}else {ToastUtils.show("请开启定位权限!");}}});}

  编写对应的定位监听器:

private LocationListener listener = new LocationListener(){@Overridepublic void onLocationChanged(Location location) {//    Log.e("GPS定位",location.getLatitude()+"|||"+location.getLongitude()+"||");}@Overridepublic void onStatusChanged(String provider, int status, Bundle extras) {}@Overridepublic void onProviderEnabled(String provider) {}@Overridepublic void onProviderDisabled(String provider) {ToastUtils.show("定位不可用");}};

  编写updataLocation()方法更新地图定位:

@SuppressLint("MissingPermission")private void updataLocation() {if (privoderLc !=null){ //防止手机关闭定位服务导致奔溃Location location=lm.getLastKnownLocation(privoderLc);if (location != null){Log.e("GPS定位",location.getLatitude()+"|||"+location.getLongitude()+"||");//将GPS坐标转换成百度坐标,不然显示在地图上会有偏差CoordinateConverter converter  = new CoordinateConverter().from(CoordinateConverter.CoordType.GPS).coord(new LatLng(location.getLatitude(),location.getLongitude()));         Log.e("坐标转换",desLatLng.latitude+"|||"+desLatLng.longitude+"||");if (mBaiduMap == null)mBaiduMap = mapView.getMap();//获取地图实例     LatLng center = converter.convert();if (bitmap == null) {//定位的红色mark点,在百度地图开发平台有bitmap = BitmapDescriptorFactory.fromResource(R.mipmap.icon_openmap_mark);}//准备 marker option 添加 marker 使用OverlayOptions markerOptions = new MarkerOptions().icon(bitmap).position(center);//清空之前的markermBaiduMap.clear();//获取添加的 marker 这样便于后续的操作mBaiduMap.addOverlay(markerOptions);//定义地图状态MapStatus mMapStatus = new MapStatus.Builder().target(center).zoom(18).build();//定义MapStatusUpdate对象,以便描述地图状态将要发生的变化MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);//改变地图状态mBaiduMap.setMapStatus(mMapStatusUpdate);}else {lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener);ToastUtils.show("定位信息获取异常");}}else {ToastUtils.show("请打开手机定位");}}

下一篇将会写一篇关于将gps经纬度转换成实际地址的文章,有时间的话,本篇文章到此就结束了,有问题欢迎批评指正,喜欢的也请点个赞噢

Android实现百度离线地图+gps定位相关推荐

  1. 新版手机离线地图GPS定位程序

    新版手机离线地图GPS定位程序 新版手机离线地图GPS定位程序是运行WindowsMobile操作系统手机上的一款应用程序,它的作用是为手机用户提供离线地图服务.也就是说不需要网络,不需要手机信号,不 ...

  2. web百度离线地图开发(详细教程)2019

    web百度离线地图开发(详细教程) 需求情景 主要参考 开发步骤 一.JS API文件下载 二.修改API文件 1.屏蔽ak验证 2.设置引用本地资源路径 3.下载本地资源 4.引用本地资源 三.加载 ...

  3. vue2+百度离线地图实现多车辆行驶动态轨迹

    vue2+百度离线地图实现行驶多车辆动态轨迹 实现多多车辆实时轨迹监控,每个10秒监测一次接口,进行动态追加.(前端实现,如果数量庞大的车辆移动,很消耗性能) 百度离线地图引入方法查看: vue项目实 ...

  4. vue整合百度离线地图api3.0

    文章目录 前言 一.场景 二.操作步骤 1.引入3.0js文件 2.创建map_load.js 3.修改bmap_offline_api_v3.0_min.js文件 3.1屏蔽ak验证 3.2加载mo ...

  5. 百度离线地图添加右键菜单

    最近在做百度离线地图相关开发,一个右键菜单功能真是折腾的够呛. 将在线api  demo代码原样copy到离线版中,无效,调用的是浏览器的右键菜单. 找了一大堆的资料,屏蔽浏览器右键菜单也罢,还有其他 ...

  6. Vue-cli3实现web百度离线地图(v3.0)开发

    需求 实现基于Vue-cli3的web百度离线地图(v3.0)开发 Vue-cli3,目录如下,注意:需要把地图相关的文件放在public下,vue-cli2需要放在static下!!! 参考 主要参 ...

  7. QT实现加载百度离线地图

    在Qt中加载百度地图需要用到网络浏览器,在此采用webEngine模块,然后用webchannel进行qt与HTML/JavaScript的交互. 需求描述:软件加载百度地图,用鼠标在地图上选点,并进 ...

  8. 百度离线地图开发,node实现地图瓦片下载

    最近有个Web项目要用离线地图,项目是在内网环境,找了很多资料,踩了很多坑,好在已经实现了,下面把资料整理一下. 首先是百度离线地图开发包,原文地址是http://www.xiaoguo123.com ...

  9. 如何用百度离线API调用百度离线地图

    这里以广西南宁市为例,说明如何用百度离线API调用百度离线地图. 首先,点击视图左上方的地图类型按钮选择百度地图(如果没有该项请点击"更多"选项),然后在视图右上方选择广西省南宁市 ...

  10. 百度离线地图示例之三:矢量图

    前言介绍: 主要是基于v3.0的API版本进行的离线,纯内网可操作,基本上实现了现有90%以上的功能点,能兼容jpg和png格式的瓦片图层,实现了原生和基于Vue两个版本(包含常用的55个示例),文末 ...

最新文章

  1. 成为优秀高级程序员的10个要点(转)
  2. 网络风行者(KSpider)的规则体系结构
  3. 配置web site 在IIS 6.0
  4. HuggingFace BERT源码详解:基本模型组件实现
  5. sqlserver还原到mysql_SQLSERVER完整数据库还原(简单恢复模式)
  6. 浅谈第三方电子支付平台测试方法的研究
  7. 大数据可视化需注意什么问题
  8. C++ Primer 5th Edition(英文版)kindle.mobi
  9. 高级程序员的思维模式
  10. swift声明属性为某个类型同时遵循某协议
  11. 爬虫实战【12】使用cookie登陆豆瓣电影以及获取单个电影的所有短评
  12. python爬取好友微信地区_python爬取微信信息--显示性别/地域/词云(附代码)
  13. GoogleChrome禁止访问端口解决
  14. Day10_GY39
  15. Android 手机模拟游戏手柄(USB,C#,winio)
  16. Windows 程式设计书籍
  17. mysql创建零件供应商表_● 建立一个供应商、零件数据库。其中“供应商”表 S(Sno,Sname,Zip,City)分别表示: 供应商代码、 供应 - 赏学吧...
  18. 牛客网--字节跳动面试题--雀魂启动
  19. 小程序逆向加密步骤小结
  20. css3-------变换/过渡/动画

热门文章

  1. android mtk wifi 移植,【搬运】 MTK手机移植ROM及修复部分bug教程(含跨CPU)
  2. 【模拟考勤打卡程序vim报错分享】
  3. vue.cli项目封装全局axios,封装请求,封装公共的api和调用请求的全过程
  4. java下拉刷新上拉加载_使用PullToRefresh实现下拉刷新和上拉加载
  5. 联想·云计算中心运维服务(1+X中级)教材出版
  6. ajax中php写法,jQuery中AJAX写法
  7. 小米路由器显示DNS服务器设置错误,小米路由器dns异常怎么修复
  8. linux中oracle中文乱码问题
  9. 手机版qq邮箱一直连接服务器失败,手机qq邮箱网页版无法登录 求高手 QQ邮箱登不上去 显示找不到服务器15?请问我咋用不...
  10. arcgis里面如何删除标记_ArcGIS技术篇——标记符号制作