編輯:關於Android編程
一直覺得地圖應用支持離線地圖很重要啊,我等移動2G屌絲,流量不易,且用且珍惜。
對於官方開發指南對於離線地圖的教程,提供了兩種方案:
第一,手動導入,先將從官網下載的離線包解壓,把vmp文件夾拷入SD卡根目錄下的BaiduMapSDK文件夾內。好吧,我表示不能接受,無視了。
第二,接口下載方法如下:mOffline.start(cityid);還比較靠譜,就是沒詳細介紹。
今天,我們主要對第二種方式進行詳細介紹,然後集成到我們的已經集成了定位方向傳感器的地圖中,如果你還不了解:Android百度地圖 SDK v3.0.0 (三) 添加覆蓋物Marker與InfoWindow的使用
效果圖: 為了方便,我又添加了個菜單按鈕~可以看到能夠對下載位置的保存,支持多個等待下載,已經取消下載等。最主要當然是,下載過後,只需要定位的流量(甚至不用)就能很好的使用咱們的地圖拉~ 順便提一下:本來想搞個線程池,支持多個同時下載,這塊可能很多不注意會有一些問題,但是百度地圖公開出來的start(cityCode)不管我怎麼嘗試(嘗試了多個離線地圖實例都不行),每次同時都只能下載一個。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; } }
/** * 初始化離線地圖 */ 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() { // 獲得所有熱門城市 ArrayListofflineCityList = mOfflineMap .getHotCityList(); // 手動添加了西安 MKOLSearchRecord xian = new MKOLSearchRecord(); xian.cityID = 233; xian.cityName = 西安市; offlineCityList.add(xian); // 獲得所有已經下載的城市列表 ArrayList 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); } }
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); } } }); }
/** * 熱門城市地圖列表的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; } }
@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; ... } }
PS:最近看到很多人都開始寫年終總結了,時間過得飛快,又到年底了,又老了一歲。學習內容:1.進度條2.縮放3.ControllerBuilder,ControllerLi
一.前言現在的app基本上都需要用到短信功能,注冊時或者有消息通知時需要給用戶發送一條短信,但是對於個人開發者來說,去買第三方的短信服務實在是有點奢侈,很好的是mob為我
在實際的開發中,很多時候還會遇到相對比較復雜的需求,比如產品妹紙或UI妹紙在哪看了個讓人興奮的效果,興致高昂的來找你,看了之後目的很明確,當然就是希望你能給她;在這樣的關
Intent是Android中用來調用其它組件的類,通過Intent,我們可以非常方便的調用Activity,Broadcast Receiver和Service。Int