Android 百度地图 SDK v3.0.0 (四) 离线地图功能介绍

转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/37758097

一直认为地图应用支持离线地图非常重要啊。我等移动2G屌丝,流量不易。且用且珍惜。

对于官方开发指南对于离线地图的教程,提供了两种方案:

第一。手动导入,先将从官网下载的离线包解压,把vmp目录拷入SD卡根目录下的BaiduMapSDK目录内。

好吧,我表示不能接受,无视了。

第二,接口下载方法例如以下:mOffline.start(cityid);还比較靠谱,就是没具体介绍。

今天。我们主要对另外一种方式进行具体介绍,然后集成到我们的已经集成了定位方向传感器的地图中,假设你还不了解:Android百度地图 SDK v3.0.0 (三) 加入覆盖物Marker与InfoWindow的使用

效果图:
为了方便。我又加入了个菜单button~能够看到能够对下载位置的保存,支持多个等待下载,已经取消下载等。

最主要当然是,下载过后,仅仅须要定位的流量(甚至不用)就能非常好的使用咱们的地图拉~

顺便提一下:本来想搞个线程池,支持多个同一时候下载,这块可能非常多不注意会有一些问题,可是百度地图公开出来的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> searchCity(java.lang.String cityName) 依据城市名搜索该城市离线地图记录
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就完工了:
@Override
public 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;
	...
	}	
}	

好了,关于百度地图,眼下就用到这么多~~假设后期有别的需求。还会继续更新~


注:开发人员key须要换成自己申请的,不清楚申请的请看第一篇博客的。




版权声明:本文博客原创文章。博客,未经同意,不得转载。

posted on 2015-07-20 18:01  gcczhongduan  阅读(561)  评论(0编辑  收藏  举报