Android 百度地圖 SDK v3.0.0 (四) 引入離線地圖功能

jopen 8年前發布 | 37K 次閱讀 Android開發 移動開發

轉載請標明出處: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> 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需要換成自己申請的,不清楚申請的請看第一篇博客的。


百度地圖相關博客視頻版本已經上線:Android中百度地圖的使用期待您的支持。

博主部分視頻已經上線,如果你不喜歡枯燥的文本,請猛戳(初錄,期待您的支持):

1、Android 自定義控件實戰 電商活動中的刮刮卡

2、Android自定義控件實戰  打造Android流式布局和熱門標簽

3、Android智能機器人“小慕”的實現

4、高仿QQ5.0側滑

5、高仿微信5.2.1主界面及消息提醒





百度地圖相關博客視頻版本已經上線:Android中百度地圖的使用期待您的支持。

博主部分視頻已經上線,如果你不喜歡枯燥的文本,請猛戳(初錄,期待您的支持):

1、Android 自定義控件實戰 電商活動中的刮刮卡

2、Android自定義控件實戰  打造Android流式布局和熱門標簽

3、Android智能機器人“小慕”的實現

4、高仿QQ5.0側滑

5、高仿微信5.2.1主界面及消息提醒


來自: http://blog.csdn.net//lmj623565791/article/details/37758097

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!