編輯:關於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()
{
// 獲得所有熱門城市
ArrayList offlineCityList = 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;
...
}
}
詳解Android之圖片加載框架Fresco基本使用(二)
PS:最近看到很多人都開始寫年終總結了,時間過得飛快,又到年底了,又老了一歲。學習內容:1.進度條2.縮放3.ControllerBuilder,ControllerLi
android_app開發集成mob短信驗證碼功能
一.前言現在的app基本上都需要用到短信功能,注冊時或者有消息通知時需要給用戶發送一條短信,但是對於個人開發者來說,去買第三方的短信服務實在是有點奢侈,很好的是mob為我
Android 自定義view實現水波紋動畫效果
在實際的開發中,很多時候還會遇到相對比較復雜的需求,比如產品妹紙或UI妹紙在哪看了個讓人興奮的效果,興致高昂的來找你,看了之後目的很明確,當然就是希望你能給她;在這樣的關
詳解Android中通過Intent類實現組件間調用的方法
Intent是Android中用來調用其它組件的類,通過Intent,我們可以非常方便的調用Activity,Broadcast Receiver和Service。Int