天天看點

【Android】3.8 定位圖層展示

分類:C#、Android、VS2015、百度地圖應用; 建立日期:2016-01-27

一、簡介

Android定位SDK v6.2.2(全球定位支援)提供GPS、基站、Wi-Fi等多種定位方式,适用于室、内外多種定位場景:定位精度高(GPS精度10m,基站精度240m,Wi-Fi精度27m)、覆寫率廣(移動、聯通、電信全覆寫,基站覆寫率99%,WIFI覆寫率99%)、網絡定位請求流量小(0.3K/次)、定位速度快(IP定位速度小于0.2S,正常環境下網絡定位速度在1s以内)。

具體内容請參看百度官網的“開發指南”,網址:

http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/v5-0

1、使用定位

使用百度定位SDK擷取相應的位置資訊,然後利用地圖SDK中的接口,您可以在地圖上展示實時位置資訊,核心代碼如下:

protected override void OnCreate(Bundle savedInstanceState)

{

……

// 開啟定位圖層

mBaiduMap.MyLocationEnabled = true;

// 定位初始化

mLocationClient = new LocationClient(this);

mLocationClient.RegisterLocationListener(this);

InitLocation(); //詳見源代碼

mLocationClient.Start();

}

2、設定AndroidManifest.xml

在application标簽中聲明service元件,每個app需要擁有自己單獨的定位service

<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote">

</service>

【重要提醒】

定位SDKv3.1版本之後,以下權限已不需要,請取消聲明,否則将由于Android 5.0多帳戶系統加強權限管理而導緻應用安裝失敗。

<uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE"></uses-permission>

3、使用綜合定位功能

綜合定位功能指的根據使用者實際需求,傳回使用者目前位置的基礎定位服務。包含GPS和網絡定位(Wi-Fi和基站定位)功能。基本定位功能同時還支援結合定位結果的反地理編碼功能,離線定位,位置提醒功能和位置語義化功能。

第一步,初始化LocationClient類

此處需要注意:LocationClient類必須在主線程中聲明。需要Context類型的參數。

LocationClient類是定位SDK的核心類,具體方法詳見類參考。

第二步,配置定位SDK參數

設定定位參數包括:定位模式(高精度定位模式,低功耗定位模式和僅用裝置定位模式),傳回坐标類型,是否打開GPS,是否傳回位址資訊、位置語義化資訊、POI資訊等等。

第三步,實作BDLocationListener接口

BDLocationListener接口有1個方法需要實作: 1.接收異步傳回的定位結果,參數是BDLocation類型參數。

BDLocation類封裝了定位SDK的定位結果,在BDLocationListener的onReceive方法中擷取。通過該類使用者可以擷取error code,位置的坐标,精度半徑等資訊。具體方法請參考類參考。

擷取error code:見官網說明。

第四步,開始定位。

開啟:mLocationClient.start();

start:啟動定位SDK。 stop:關閉定位SDK。調用start之後隻需要等待定位結果自動回調即可。

開發者定位場景如果是單次定位的場景,在收到定位結果之後直接調用stop函數即可。

如果stop之後仍然想進行定位,可以再次start等待定位結果回調即可。

如果開發者想按照自己邏輯請求定位,可以在start之後按照自己的邏輯請求locationclient.requestLocation()函數,會主動觸發定位SDK内部定位邏輯,等待定位回調即可。

4、位置提醒使用

位置提醒最多提醒3次,3次過後将不再提醒。 假如需要再次提醒,或者要修改提醒點坐标,都可通過函數SetNotifyLocation()來實作。

5、需要注意的問題

l 定位SDK必須注冊GPS和網絡的使用權限。

l 使用定位SDK請盡量保證網絡連接配接通暢(GPS定位方式不需要連網,但如果需要位址資訊、位置語義化、POI等資訊都需要聯網的)。目前離線功能已經支援擷取上述資訊,但離線定位不是百分百都能定位成功的。

l 百度官網強烈建議您設定自己的prodName,并保管好,這樣友善百度為您提供更好的定位服務。

l 若需要傳回的定位結果裡包含位址資訊,請保證網絡連接配接。因為GPS是本地擷取的定位位置,在某些情況下有可能不帶位址資訊。

l 定位SDK可以傳回bd09、bd09ll、gcj02三種類型坐标,若需要将定位點的位置通過百度Android地圖 SDK進行地圖展示,請傳回bd09ll,将無偏差的疊加在百度地圖上。

l 有的移動裝置鎖屏後為了省電會自動關閉網絡連接配接,此時網絡定位模式的定位失效。此外,鎖屏後移動裝置若進入cpu休眠,定時定位功能也失效。若需要實作在cpu休眠狀态仍需定時定位,可以用AlarmManager 實作1個cpu可叫醒的timer,定時請求定位。

二、運作截圖

簡介:介紹定位圖層的基本用法

詳述:

(1)可自定義更換位置圖示;

(2)支援定位三态效果顯示(普通态、跟随态、羅盤态);

(3)百度地圖SDK從2.0.0版本起,将定位功能進行了分離,具體使用方法請見定位SDK;

(4)定位SDK開發指南詳見http://developer.baidu.com/map/geosdk-android.htm;

為了截圖友善,本示例仍然用模拟器來示範,與真機的差別僅是模拟時需要手工添加模拟的定位位置。如果在真機上運作,必須去掉模拟的定位位置代碼(詳見源代碼中的說明),否則就無法實際定位了。

【Android】3.8 定位圖層展示

三、設計步驟

在上一節例子的基礎上,隻需要再增加下面的步驟即可。

1、添加demo08_location.xml檔案

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

    <com.baidu.mapapi.map.TextureMapView
        android:id="@+id/bmapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginTop="80dip"
        android:background="#D000"
        android:minWidth="100dip"
        android:orientation="vertical"
        android:padding="2dp" >

        <RadioGroup
            android:id="@+id/radioGroup"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="定位icon" >

            <RadioButton
                android:id="@+id/defaulticon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="true"
                android:text="預設圖示" >
            </RadioButton>

            <RadioButton
                android:id="@+id/customicon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="自定義圖示" >
            </RadioButton>
        </RadioGroup>
    </LinearLayout>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginRight="25dp"
        android:layout_marginTop="10dip" />

</RelativeLayout>      

2、添加Demo08Location.cs檔案

在SrcSdkDemos檔案夾下添加該檔案,然後将其内容改為下面的代碼:

using Android.App;
using Android.Content.PM;
using Android.OS;
using Android.Util;
using Android.Widget;
using Com.Baidu.Location;
using Com.Baidu.Mapapi.Map;
using Com.Baidu.Mapapi.Model;
using System.Collections.Generic;
using System.Text;

namespace BdMapV371Demos.SrcSdkDemos
{
    /// <summary>
    /// 此demo用來展示如何結合定位SDK實作定位,并使用MyLocationOverlay繪制定位位置,同時展示如何使用自定義圖示繪制并點選時彈出泡泡
    /// </summary>
    [Activity(ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden, Label = "@string/demo_name_location", ScreenOrientation = ScreenOrientation.Sensor)]
    public class Demo08Location : Activity, IBDLocationListener
    {
        LocationClient mLocationClient;
        TextureMapView mMapView;
        BaiduMap mBaiduMap;
        bool isFirstLoc = true;// 是否首次定位

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.demo08_location);
            Button requestLocButton = FindViewById<Button>(Resource.Id.button1);
            MyLocationConfiguration.LocationMode mCurrentMode = MyLocationConfiguration.LocationMode.Normal;
            BitmapDescriptor mCurrentMarker=null;
            requestLocButton.Text = "普通";
            requestLocButton.SetBackgroundColor(Android.Graphics.Color.YellowGreen);
            requestLocButton.Click += delegate
            {
                if (mCurrentMode.Equals(MyLocationConfiguration.LocationMode.Normal))
                {
                    requestLocButton.Text = "跟随";
                    mCurrentMode = MyLocationConfiguration.LocationMode.Following;
                    mBaiduMap.SetMyLocationConfigeration(
                        new MyLocationConfiguration(mCurrentMode, true, mCurrentMarker));
                }
                else if (mCurrentMode.Equals(MyLocationConfiguration.LocationMode.Compass))
                {
                    requestLocButton.Text = "普通";
                    mCurrentMode = MyLocationConfiguration.LocationMode.Normal;
                    mBaiduMap.SetMyLocationConfigeration(
                        new MyLocationConfiguration(mCurrentMode, true, mCurrentMarker));
                }
                else if (mCurrentMode.Equals(MyLocationConfiguration.LocationMode.Following))
                {
                    requestLocButton.Text = "羅盤";
                    mCurrentMode = MyLocationConfiguration.LocationMode.Compass;
                    mBaiduMap.SetMyLocationConfigeration(
                        new MyLocationConfiguration(mCurrentMode, true, mCurrentMarker));
                }
            };

            RadioGroup group = FindViewById<RadioGroup>(Resource.Id.radioGroup);
            group.SetBackgroundColor(Android.Graphics.Color.YellowGreen);

            group.CheckedChange += (sender, args) =>
            {
                int checkedId = args.CheckedId;
                if (checkedId == Resource.Id.defaulticon)
                {
                    // 傳入null則恢複預設圖示
                    mCurrentMarker = null;
                    mBaiduMap.SetMyLocationConfigeration(
                        new MyLocationConfiguration(mCurrentMode, true, null));
                }
                if (checkedId == Resource.Id.customicon)
                {
                    // 修改為自定義marker
                    mCurrentMarker = BitmapDescriptorFactory
                            .FromResource(Resource.Drawable.icon_geo);
                    mBaiduMap.SetMyLocationConfigeration(
                        new MyLocationConfiguration(mCurrentMode, true, mCurrentMarker));
                }
            };

            // 地圖初始化
            mMapView = FindViewById<TextureMapView>(Resource.Id.bmapView);
            mBaiduMap = mMapView.Map;
            mBaiduMap.SetMapStatus(MapStatusUpdateFactory.NewLatLng(MainActivity.HeNanUniversity));

            // 開啟定位圖層
            mBaiduMap.MyLocationEnabled = true;
            // 定位初始化
            mLocationClient = new LocationClient(this);
            mLocationClient.RegisterLocationListener(this);
            InitLocation();
            mLocationClient.Start();
        }
        private void InitLocation()
        {
            LocationClientOption option = new LocationClientOption();
            //可選,預設高精度,設定定位模式,高精度,低功耗,僅裝置
            option.SetLocationMode(LocationClientOption.LocationMode.HightAccuracy);
            //可選,預設gcj02,設定傳回的定位結果坐标系
            //其中:bd09為墨卡托平面坐标[機關:米],gcj02為經緯度坐标[機關:度]
            option.CoorType = "bd09ll";
            int span = 1000;
            //可選,預設0,即僅定位一次,設定發起定位請求的間隔需要大于等于1000ms才是有效的
            option.ScanSpan = span;
            //可選,設定是否需要位址資訊,預設不需要
            option.SetIsNeedAddress(true);
            //可選,預設false,設定是否使用gps
            option.OpenGps = true;
            //可選,預設false,設定是否當gps有效時按照1S1次頻率輸出GPS結果
            option.LocationNotify = true;
            //可選,預設false,設定是否需要位置語義化結果,可以在BDLocation.GetLocationDescribe裡得到,結果類似于“在北京天安門附近”
            option.SetIsNeedLocationDescribe(true);
            //可選,預設false,設定是否需要POI結果,可以在BDLocation.GetPoiList裡得到
            option.SetIsNeedLocationPoiList(true);
            //可選,預設true,定位SDK内部是一個SERVICE,并放到了獨立程序,設定是否在stop的時候殺死這個程序,預設不殺死  
            option.IsIgnoreKillProcess =  false;
            //可選,預設false,設定是否收集CRASH資訊,預設收集
            option.IsIgnoreCacheException=false;
            //可選,預設false,設定是否需要過濾gps仿真結果,預設需要
            option.EnableSimulateGps = false;
            mLocationClient.LocOption = option;
        }

        //實作接口
        public void OnReceiveLocation(BDLocation p0)
        {
            // map view 銷毀後不再處理新接收的位置
            if (p0 == null || mMapView == null) return;

            #region 模拟位置
            //注意:在手機上運作應注釋掉這段代碼,否則定位就沒有意義了
            p0 = new BDLocation();
            p0.LocationDescribe = "模拟的位置,目的是為了在模拟器中檢視運作效果";
            p0.Radius = 50;
            p0.Latitude = MainActivity.HeNanUniversity.Latitude;
            p0.Longitude = MainActivity.HeNanUniversity.Longitude;
            #endregion 模拟位置

            MyLocationData locData = new MyLocationData.Builder()
                    .Accuracy(p0.Radius)
                    // 此處設定開發者擷取到的方向資訊,順時針0-360
                    .Direction(100).Latitude(p0.Latitude)
                    .Longitude(p0.Longitude).Build();
            mBaiduMap.SetMyLocationData(locData);
            if (isFirstLoc)
            {
                isFirstLoc = false;
                LatLng ll = new LatLng(p0.Latitude, p0.Longitude);
                MapStatusUpdate u = MapStatusUpdateFactory.NewLatLng(ll);
                mBaiduMap.AnimateMapStatus(u);
            }

            //Receive Location
            StringBuilder sb = new StringBuilder(256);
            sb.AppendLine("time : "+p0.Time);
            sb.AppendLine("error code : "+p0.LocType);
            sb.AppendLine("latitude : "+p0.Latitude);
            sb.AppendLine("lontitude : "+p0.Longitude);
            sb.AppendLine("radius : "+p0.Radius);
            switch(p0.LocType)
            {
                case BDLocation.TypeGpsLocation:
                    // GPS定位結果
                    sb.AppendLine("speed : " + p0.Speed);// 機關:公裡/每小時
                    sb.AppendLine("satellite : " + p0.SatelliteNumber);
                    sb.AppendLine("height : " + p0.Altitude);// 機關:米
                    sb.AppendLine("direction : " + p0.Direction);// 機關度
                    sb.AppendLine("addr : " + p0.AddrStr);
                    sb.AppendLine("describe : gps定位成功");
                    break;
                case BDLocation.TypeNetWorkLocation:
                    // 網絡定位結果
                    sb.AppendLine("網絡定位結果(addr) : " + p0.AddrStr);
                    //營運商資訊
                    sb.AppendLine("營運商資訊(operationers) : " + p0.Operators);
                    sb.AppendLine("describe : 網絡定位成功");
                    break;
                case BDLocation.TypeOffLineLocation:
                    // 離線定位結果
                    sb.AppendLine("describe : 離線定位成功,離線定位結果也是有效的");
                    break;
                case BDLocation.TypeServerError:
                    sb.AppendLine("describe : 服務端網絡定位失敗,可以回報IMEI号和大體定位時間到[email protected],會有人追查原因");
                    break;
                case BDLocation.TypeNetWorkException:
                    sb.AppendLine("describe : 網絡不同導緻定位失敗,請檢查網絡是否通暢");
                    break;
                case BDLocation.TypeCriteriaException:
                    sb.AppendLine("describe : 無法擷取有效定位依據導緻定位失敗,一般是由于手機的原因,處于飛行模式下一般會造成這種結果,可以試着重新開機手機");
                    break;
            }
            sb.AppendLine("locationdescribe: "+p0.LocationDescribe);// 位置語義化資訊
            var list = p0.PoiList;// POI資料
            if (list != null)
            {
                sb.AppendLine("poilist size = : "+list.Count);
                foreach (Poi p in list)
                {
                    sb.AppendLine();
                    sb.AppendFormat("poi= : {0} {1} {2}",p.Id,p.Name,p.Rank);
                }
            }
            Log.Debug("BaiduLocationApiDem", sb.ToString());
        }

        protected override void OnPause()
        {
            mMapView.OnPause();
            base.OnPause();
        }

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

        protected override void OnDestroy()
        {
            // 退出時銷毀定位
            mLocationClient.Stop();
            // 關閉定位圖層
            mBaiduMap.MyLocationEnabled = false;
            mMapView.OnDestroy();
            mMapView = null;
            base.OnDestroy();
        }
    }
}      

3、修改MainActivity.cs

在MainActivity.cs檔案的demos字段定義中,去掉【示例8】下面的注釋。

運作觀察結果。

轉載于:https://www.cnblogs.com/rainmj/p/5181429.html