【Android】3.16 离线地图功能

分类:C#、Android、VS2015、百度地图应用; 创建日期:2016-02-04

一、简介

百度地图目前已经支持矢量离线地图数据的下载、更新。

使用离线地图,可满足在无网络环境下查看地图信息的需求,此外,在有离线地图的情况下,SDK会优先加载离线地图使用,减少用户流量方面的开销,为用户提供更流畅的地图服务体验。

更新离线地图增加update方法,与start方法区别开来,当检测到有城市离线包有更新,调用update方法执行更新,调用pause暂停,调用start继续

离线地图资源可通过SDK“在线下载离线包接口”下载获取。自v2.9.0起,官网不再支持地图离线包下载,所以SDK去掉“手动导入离线包接口”,SDK在线下载离线包接口仍维持不变。

二、运行截图

简介:介绍如何下载和使用离线地图。

详述:

可以搜索、下载、删除、查看离线地图。

该示例运行截图如下:

image

三、设计步骤

1、添加demo16_offline.xml文件

在layout文件夹下添加该文件,然后将代码改为下面的内容:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="50dip"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/cityid"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="131" />

        <!-- 隐藏输入法用 -->
        <LinearLayout
            android:layout_width="0px"
            android:layout_height="0px"
            android:focusable="true"
            android:focusableInTouchMode="true" />

        <EditText
            android:id="@+id/city"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="北京" />

        <Button
            android:id="@+id/search"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/button_style"
            android:text="搜索" />
    </LinearLayout>

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="50dip"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/state"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="已下载:--" />

        <Button
            android:id="@+id/start"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/button_style"
            android:text="开始" />

        <Button
            android:id="@+id/stop"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/button_style"
            android:text="停止" />

        <Button
            android:id="@+id/del"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/button_style"
            android:text="删除" />
    </LinearLayout>

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/city_list"
        android:layout_width="match_parent"
        android:layout_height="50dip"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/clButton"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/button_style"
            android:text="城市列表" />

        <Button
            android:id="@+id/localButton"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/button_style"
            android:text="下载管理" />
    </LinearLayout>

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/citylist_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="热门城市" />

        <ListView
            android:id="@+id/hotcitylist"
            android:layout_width="fill_parent"
            android:layout_height="200dip" />

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="全国" />

        <ListView
            android:id="@+id/allcitylist"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />
    </LinearLayout>

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/localmap_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="已下载城市 " />

        <ListView
            android:id="@+id/localmaplist"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>

2、添加demo16_offline_localmap_list.xml文件

在layout文件夹下添加该文件,然后将代码改为下面的内容:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:padding="10dip" >

    <TextView
        android:id="@+id/title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="已下载城市 " />

    <TextView
        android:id="@+id/update"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text=""
        android:textColor="#FF0000" />

    <TextView
        android:id="@+id/ratio"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="" />

    <Button
        android:id="@+id/display"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@drawable/button_style"
        android:text="查看" />

    <Button
        android:id="@+id/remove"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@drawable/button_style"
        android:text="删除" />

</LinearLayout>

3、添加Demo16Offline.cs文件

在SrcSdkDemos文件夹下添加该文件,然后将代码改为下面的内容:

using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using Android.Util;
using Android.Views;
using Android.Widget;
using Com.Baidu.Mapapi.Map.Offline;
using System.Collections.Generic;
namespace BdMapV371Demos.SrcSdkDemos
{
    [Activity(Label = "@string/demo_name_offline",
        ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
        ScreenOrientation = ScreenOrientation.Sensor)]
    public class Demo16Offline : Activity, IMKOfflineMapListener
    {
        private MKOfflineMap mOffline = null;
        private TextView cidView;
        private TextView stateView;
        private EditText cityNameView;

        //已下载的离线地图信息列表
        private IList<MKOLUpdateElement> localMapList = null;
        private LocalMapAdapter lAdapter = null;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.demo16_offline);

            mOffline = new MKOfflineMap();
            mOffline.Init(this);

            //【搜索】按钮--搜索需要下载的城市离线包
            var search = FindViewById<Button>(Resource.Id.search);
            search.Click += delegate
            {
                IList<MKOLSearchRecord> records = mOffline.SearchCity(cityNameView.Text);
                if (records == null || records.Count != 1)
                    return;
                cidView.Text = records[0].CityID.ToString();
            };

            //【开始】按钮--开始下载
            var start = FindViewById<Button>(Resource.Id.start);
            start.Click += delegate
            {
                int cityid = int.Parse(cidView.Text);
                mOffline.Start(cityid);
                Toast.MakeText(this, "开始下载离线地图. cityid: " + cityid, ToastLength.Short).Show();
            };

            //【停止】按钮--暂停下载
            var stop = FindViewById<Button>(Resource.Id.stop);
            stop.Click += delegate
            {
                int cityid = int.Parse(cidView.Text);
                mOffline.Pause(cityid);
                Toast.MakeText(this, "暂停下载离线地图. cityid: " + cityid, ToastLength.Short).Show();
            };

            //【删除】按钮--删除离线地图
            var del = FindViewById<Button>(Resource.Id.del);
            del.Click += delegate
            {
                int cityid = int.Parse(cidView.Text);
                mOffline.Remove(cityid);
                Toast.MakeText(this, "删除离线地图. cityid: " + cityid, ToastLength.Short).Show();
            };

            //【城市列表】按钮--切换至城市列表
            var clButton = FindViewById<Button>(Resource.Id.clButton);
            clButton.Click += delegate
            {
                LinearLayout cl = FindViewById<LinearLayout>(Resource.Id.citylist_layout);
                LinearLayout lm = FindViewById<LinearLayout>(Resource.Id.localmap_layout);
                lm.Visibility = ViewStates.Gone;
                cl.Visibility = ViewStates.Visible;
            };

            //【下载管理】按钮--切换至下载管理列表
            var localButton = FindViewById<Button>(Resource.Id.localButton);
            localButton.Click += delegate
            {
                LinearLayout cl = FindViewById<LinearLayout>(Resource.Id.citylist_layout);
                LinearLayout lm = FindViewById<LinearLayout>(Resource.Id.localmap_layout);
                lm.Visibility = ViewStates.Visible;
                cl.Visibility = ViewStates.Gone;
            };

            InitView();
        }

        private void InitView()
        {
            cidView = FindViewById<TextView>(Resource.Id.cityid);
            cityNameView = FindViewById<EditText>(Resource.Id.city);
            stateView = FindViewById<TextView>(Resource.Id.state);

            ListView hotCityList = FindViewById<ListView>(Resource.Id.hotcitylist);
            IList<string> hotCities = new List<string>();
            //获取热闹城市列表
            IList<MKOLSearchRecord> records1 = mOffline.HotCityList;
            if (records1 != null)
            {
                foreach (MKOLSearchRecord r in records1)
                {
                    hotCities.Add(string.Format("{0}({1})--{2}",
                        r.CityName, r.CityID, FormatDataSize(r.Size)));
                }
            }
            IListAdapter hAdapter = new ArrayAdapter<string>(this,
                     Android.Resource.Layout.SimpleListItem1, hotCities);
            hotCityList.Adapter = hAdapter;

            ListView allCityList = FindViewById<ListView>(Resource.Id.allcitylist);
            //获取所有支持离线地图的城市
            IList<string> allCities = new List<string>();
            IList<MKOLSearchRecord> records2 = mOffline.OfflineCityList;
            if (records1 != null)
            {
                foreach (MKOLSearchRecord r in records2)
                {
                    allCities.Add(string.Format("{0}({1})--{2}",
                        r.CityName, r.CityID, FormatDataSize(r.Size)));
                }
            }
            IListAdapter aAdapter = new ArrayAdapter<string>(this,
                     Android.Resource.Layout.SimpleListItem1, allCities);
            allCityList.Adapter = aAdapter;

            LinearLayout cl = FindViewById<LinearLayout>(Resource.Id.citylist_layout);
            LinearLayout lm = FindViewById<LinearLayout>(Resource.Id.localmap_layout);
            lm.Visibility = ViewStates.Gone;
            cl.Visibility = ViewStates.Visible;

            //获取已下过的离线地图信息
            localMapList = mOffline.AllUpdateInfo;
            if (localMapList == null)
            {
                localMapList = new List<MKOLUpdateElement>();
            }

            ListView localMapListView = FindViewById<ListView>(Resource.Id.localmaplist);
            lAdapter = new LocalMapAdapter(this);
            localMapListView.Adapter = lAdapter;

        }

        // 更新状态显示 
        public void UpdateView()
        {
            localMapList = mOffline.AllUpdateInfo;
            if (localMapList == null)
            {
                localMapList = new List<MKOLUpdateElement>();
            }
            lAdapter.NotifyDataSetChanged();
        }

        protected override void OnPause()
        {
            int cityid = int.Parse(cidView.Text);
            MKOLUpdateElement temp = mOffline.GetUpdateInfo(cityid);
            if (temp != null && temp.Status == MKOLUpdateElement.Downloading)
            {
                mOffline.Pause(cityid);
            }
            base.OnPause();
        }

        protected override void OnResume()
        {
            base.OnResume();
        }

        public string FormatDataSize(int size)
        {
            string ret = "";
            if (size < (1024 * 1024))
            {
                ret = Java.Lang.String.Format("%dK", size / 1024);
            }
            else
            {
                ret = Java.Lang.String.Format("%.1fM", size / (1024 * 1024.0));
            }
            return ret;
        }

        protected override void OnDestroy()
        {
            // 退出时,销毁离线地图模块
            mOffline.Destroy();
            base.OnDestroy();
        }

        //实现接口
        public void OnGetOfflineMapState(int type, int state)
        {
            switch (type)
            {
                case MKOfflineMap.TypeDownloadUpdate:
                    {
                        MKOLUpdateElement update = mOffline.GetUpdateInfo(state);
                        //处理下载进度更新提示
                        if (update != null)
                        {
                            stateView.Text = Java.Lang.String.Format("%s : %d%%", update.CityName,
                                update.Ratio);
                            UpdateView();
                        }
                    }
                    break;
                case MKOfflineMap.TypeNewOffline:
                    //有新离线地图安装
                    Log.Debug("OfflineDemo", string.Format("add offlinemap num:{0:d}", state));
                    break;
                case MKOfflineMap.TypeVerUpdate:
                    // 版本更新提示
                    //    MKOLUpdateElement e = mOffline.GetUpdateInfo(state);
                    break;
            }
        }

        // 离线地图管理列表适配器
        public class LocalMapAdapter : BaseAdapter
        {
            private Demo16Offline offlineDemo;

            public LocalMapAdapter(Demo16Offline offlineDemo)
            {
                this.offlineDemo = offlineDemo;
            }

            public override int Count
            {
                get { return offlineDemo.localMapList.Count; }
            }

            public override Java.Lang.Object GetItem(int index)
            {
                return offlineDemo.localMapList[index];
            }

            public override long GetItemId(int index)
            {
                return index;
            }

            public override View GetView(int index, View view, ViewGroup arg2)
            {
                MKOLUpdateElement e = (MKOLUpdateElement)GetItem(index);
                view = View.Inflate(offlineDemo,
                        Resource.Layout.demo16_offline_localmap_list, null);
                InitViewItem(view, e);
                return view;
            }

            void InitViewItem(View view, MKOLUpdateElement e)
            {
                Button display = view.FindViewById<Button>(Resource.Id.display);
                Button remove = view.FindViewById<Button>(Resource.Id.remove);
                TextView title = view.FindViewById<TextView>(Resource.Id.title);
                TextView update = view.FindViewById<TextView>(Resource.Id.update);
                TextView ratio = view.FindViewById<TextView>(Resource.Id.ratio);
                ratio.Text = e.Ratio + "%";
                title.Text = e.CityName;
                if (e.Update)
                {
                    update.Text = "可更新";
                }
                else
                {
                    update.Text = "最新";
                }
                if (e.Ratio != 100)
                {
                    display.Enabled = false;
                }
                else
                {
                    display.Enabled = true;
                }
                remove.Click += delegate
                {
                    offlineDemo.mOffline.Remove(e.CityID);
                    offlineDemo.UpdateView();
                };
                display.Click += delegate
                {
                    Intent intent = new Intent();
                    intent.PutExtra("x", e.GeoPt.Longitude);
                    intent.PutExtra("y", e.GeoPt.Latitude);
                    intent.SetClass(offlineDemo, typeof(Demo02BaseMap));
                    offlineDemo.StartActivity(intent);
                };
            }
        }
    }
}

4、修改MainActivity.cs

在MainActivity.cs文件的demos字段定义中,去掉【示例16】下面的注释。

运行观察结果。

posted @ 2016-02-04 15:12  rainmj  阅读(745)  评论(0编辑  收藏  举报