转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37758097
一直觉得地图应用支持离线地图很重要啊,我等移动2G屌丝,流量不易,且用且珍惜。
对于官方开发指南对于离线地图的教程,提供了两种方案:
第一,手动导入,先将从官网下载的离线包解压,把vmp文件夹拷入SD卡根目录下的BaiduMapSDK文件夹内。好吧,我表示不能接受,无视了。
第二,接口下载方法如下:mOffline.start(cityid);还比较靠谱,就是没详细介绍。
今天,我们主要对第二种方式进行详细介绍,然后集成到我们的已经集成了定位方向传感器的地图中,如果你还不了解:Android百度地图 SDK v3.0.0 (三) 添加覆盖物Marker与InfoWindow的使用
效果图:
为了方便,我又添加了个菜单按钮~可以看到能够对下载位置的保存,支持多个等待下载,已经取消下载等。最主要当然是,下载过后,只需要定位的流量(甚至不用)就能很好的使用咱们的地图拉~
顺便提一下:本来想搞个线程池,支持多个同时下载,这块可能很多不注意会有一些问题,但是百度地图公开出来的start(cityCode)不管我怎么尝试(尝试了多个离线地图实例都不行),每次同时都只能下载一个。
1、百度地图离线相关API介绍
a 、类 MKOfflineMap 提供地图的下载,离线地图列表的获取,已下载地图的查询等
java.util.ArrayList<MKOLUpdateElement> getAllUpdateInfo() 返回各城市离线地图更新信息
java.util.ArrayList<MKOLSearchRecord> getHotCityList() 返回热门城市列表
java.util.ArrayList<MKOLSearchRecord> getOfflineCityList() 返回支持离线地图城市列表
MKOLUpdateElement getUpdateInfo(int cityID) 返回指定城市ID离线地图更新信息
java.util.ArrayList<MKOLSearchRecord> getHotCityList() 返回热门城市列表
java.util.ArrayList<MKOLSearchRecord> getOfflineCityList() 返回支持离线地图城市列表
MKOLUpdateElement getUpdateInfo(int cityID) 返回指定城市ID离线地图更新信息
java.util.ArrayList<MKOLSearchRecord> searchCity(java.lang.String cityName) 根据城市名搜索该城市离线地图记录
boolean init(MKOfflineMapListener listener) 初使化
boolean pause(int cityID) 暂停下载指定城市ID的离线地图
boolean remove(int cityID) 删除指定城市ID的离线地图
boolean start(int cityID) 启动下载指定城市ID的离线地图
boolean init(MKOfflineMapListener listener) 初使化
boolean pause(int cityID) 暂停下载指定城市ID的离线地图
boolean remove(int cityID) 删除指定城市ID的离线地图
boolean start(int cityID) 启动下载指定城市ID的离线地图
void destroy() 销毁离线地图管理模块,不用时调用
接口 MKOfflineMapListener 离线地图事件通知接口。
void onGetOfflineMapState(int type, int state)
类 MKOLUpdateElement 和 类 MKOLSearchRecord
基本就是包含一些cityName , cityId, size 等等
API在百度的帮助文档中也很详细,下面会在代码中使用这些API。
2、离线地图城市信息的实体Bean
package com.zhy.zhy_baidu_ditu_demo00;public class OfflineMapCityBean{ private String cityName; private int cityCode; /** * 下载的进度 */ private int progress; private Flag flag = Flag.NO_STATUS; /** * 下载的状态:无状态,暂停,正在下载 * @author zhy * */ public enum Flag { NO_STATUS,PAUSE,DOWNLOADING } public Flag getFlag() { return flag; } public void setFlag(Flag flag) { this.flag = flag; } public OfflineMapCityBean() { } public OfflineMapCityBean(String cityName, int cityCode, int progress) { this.cityName = cityName; this.cityCode = cityCode; this.progress = progress; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public int getCityCode() { return cityCode; } public void setCityCode(int cityCode) { this.cityCode = cityCode; } public int getProgress() { return progress; } public void setProgress(int progress) { this.progress = progress; }}
包含了,城市名称:用于listview上的显示,城市id:用于查询下载情况,进度:更新listview下载时的显示,标志:用户开启或者取消下载时的标志。
3、离线地图的使用
在Actvity启动时,首先初始化离线地图
/** * 初始化离线地图 */ private void initOfflineMap() { mOfflineMap = new MKOfflineMap(); // 设置监听 mOfflineMap.init(new MKOfflineMapListener() { @Override public void onGetOfflineMapState(int type, int state) { switch (type) { case MKOfflineMap.TYPE_DOWNLOAD_UPDATE: // 离线地图下载更新事件类型 MKOLUpdateElement update = mOfflineMap.getUpdateInfo(state); Log.e(TAG, update.cityName + " ," + update.ratio); for (OfflineMapCityBean bean : mDatas) { if (bean.getCityCode() == state) { bean.setProgress(update.ratio); bean.setFlag(Flag.DOWNLOADING); break; } } mAdapter.notifyDataSetChanged(); Log.e(TAG, "TYPE_DOWNLOAD_UPDATE"); break; case MKOfflineMap.TYPE_NEW_OFFLINE: // 有新离线地图安装 Log.e(TAG, "TYPE_NEW_OFFLINE"); break; case MKOfflineMap.TYPE_VER_UPDATE: // 版本更新提示 break; } } }); }设置离线地图的下载监听接口,目前我们只关注type为MKOfflineMap.TYPE_DOWNLOAD_UPDATE , 此时传入的state为cityId, 然后我们通过mOfflineMap.getUpdateInfo(state);可以获得该城市的下载数据,接下来更新我们listview的数据集,最后刷新界面。
初始化数据:
private void initData() { // 获得所有热门城市 ArrayList<MKOLSearchRecord> offlineCityList = mOfflineMap .getHotCityList(); // 手动添加了西安 MKOLSearchRecord xian = new MKOLSearchRecord(); xian.cityID = 233; xian.cityName = "西安市"; offlineCityList.add(xian); // 获得所有已经下载的城市列表 ArrayList<MKOLUpdateElement> allUpdateInfo = mOfflineMap .getAllUpdateInfo(); // 设置所有数据的状态 for (MKOLSearchRecord record : offlineCityList) { OfflineMapCityBean cityBean = new OfflineMapCityBean(); cityBean.setCityName(record.cityName); cityBean.setCityCode(record.cityID); if (allUpdateInfo != null)//没有任何下载记录,返回null,为啥不返回空列表~~ { for (MKOLUpdateElement ele : allUpdateInfo) { if (ele.cityID == record.cityID) { cityBean.setProgress(ele.ratio); } } } mDatas.add(cityBean); } }
进入Activity先通过mOfflineMap.getHotCityList();获得热门城市列表,不过热门里面竟然没有西安,我手动增加了一个西安。(这里我是为了方便,有兴趣的可以列出全国支持的城市);接下来mOfflineMap.getAllUpdateInfo();获得已经下载城市的数据信息;然后就行交叉对比,设置数据源数据。
初始化listview
private void initListView() { mListView = (ListView) findViewById(R.id.id_offline_map_lv); mAdapter = new MyOfflineCityBeanAdapter(); mListView.setAdapter(mAdapter); mListView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { int cityId = mDatas.get(position).getCityCode(); if (mCityCodes.contains(cityId)) { removeTaskFromQueue(position, cityId); } else { addToDownloadQueue(position, cityId); } } }); }
为listview的item设置点击事件,第一次点击时加入下载队列,第二次点击时取消下载。
listview的适配器
/** * 热门城市地图列表的Adapter * * @author zhy * */ class MyOfflineCityBeanAdapter extends BaseAdapter { @Override public boolean isEnabled(int position) { if (mDatas.get(position).getProgress() == 100) { return false; } return super.isEnabled(position); } @Override public int getCount() { return mDatas.size(); } @Override public Object getItem(int position) { return mDatas.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { OfflineMapCityBean bean = mDatas.get(position); ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.offlinemap_item, parent, false); holder.cityName = (TextView) convertView .findViewById(R.id.id_cityname); holder.progress = (TextView) convertView .findViewById(R.id.id_progress); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.cityName.setText(bean.getCityName()); int progress = bean.getProgress(); String progressMsg = ""; // 根据进度情况,设置显示 if (progress == 0) { progressMsg = "未下载"; } else if (progress == 100) { bean.setFlag(Flag.NO_STATUS); progressMsg = "已下载"; } else { progressMsg = progress + "%"; } // 根据当前状态,设置显示 switch (bean.getFlag()) { case PAUSE: progressMsg += "【等待下载】"; break; case DOWNLOADING: progressMsg += "【正在下载】"; break; default: break; } holder.progress.setText(progressMsg); return convertView; } private class ViewHolder { TextView cityName; TextView progress; } }
适配器的代码比较简单,主要就是getView中根本bean的数据设置显示。
最后在我们主Activity增加一个菜单项,打开此Activity就完工了:
@Overridepublic boolean onOptionsItemSelected(MenuItem item){ switch (item.getItemId()) { case R.id.id_menu_map_offline: Intent intent = new Intent(MainActivity.this, OfflineMapActivity.class); startActivity(intent); break; ... } }
好了,关于百度地图,目前就用到这么多~~如果后期有别的需求,还会继续更新~
源码点击下载