Xamarin.Android之定位


一、前言

打開我們手中的應用,可以發現越來越多的應用使用了定位,從而使我們的生活更加方便,所以本章我們將學習如何在Xamarin中進行定位的開發。

 

 

二、准備工作

因為我們的虛擬機是運行在電腦本地的,自然就沒法進行定位了,但是我們可以借助DDMS這個工具幫助我們去調試。

 

首先要確定你的Android SDK所在的目錄,讀者可以通過以下方式找到:

工具-》選項

 

然后讀者打開該文件夾下的tools文件夾,我們就可以看到里面有很多以bat結果的文件,這個時候我們打開名為ddms.bat的文件后,將會看到如下界面:

 

通過這里我們就可以手動發送GPS位置信息了。

 

注:項目還需要以下權限

 

三、正文

 

1.監聽GPS位置的變化

本節中我們將會學習如何獲取位置管理器,並通過位置管理器去獲取不同的定位提供器,之所有會有多個位置提供器是因為我們的手機不僅僅只能靠GPS定位,同時也能夠根據基站以及網絡定位,當然精准度,耗電量都各自不同,這就給我們提供了比較靈活的方式去控制,下面我們打開新建項目的MainActivity.cs文件並在OnCreate中寫入下面的代碼:

1         protected override void OnCreate(Bundle bundle)
2         {
3             base.OnCreate(bundle);
4             SetContentView(Resource.Layout.Main);
5             LocationManager lm = (LocationManager)GetSystemService(LocationService);
6         }

 

 

在Android中有許多的服務都是通過這種方式去獲取,所以讀者一定要有這樣的習慣,而不是跟本地開發一樣都是直接調用某個類就可以了,這里我們需要通過GetSystemService獲取指定名稱的服務,例如我們這里的定位管理器,有了定位管理器之后,我們就可以通過它獲取定位提供器、監聽位置變化等。下面為了能夠非常明顯看出變化,我們將監聽GPS位置信息變化,並通過TOAST顯示出來,首先我們讓MainActivity實現ILocationListener接口中的方法,並在OnLocationChanged中寫入如下代碼:

1         public void OnLocationChanged(Location location)
2         {
3             String s = String.Format("{0}   {1}", location.Longitude, location.Latitude);
4             Toast.MakeText(ApplicationContext, s, ToastLength.Short).Show();
5         }

 

 

最后我們還需要通過位置管理器將其注冊,只需要在OnCreate的最后寫入如下代碼即可:

1 lm.RequestLocationUpdates(LocationManager.GpsProvider, 5000, 500f, this);

該方法的大致意思就是跟蹤GPS位置的變化,並且每5秒刷新一次,同時兩次的位置的間隔要在500米,按照筆者的實際測試來看並不會每5秒調用你的方法一次,而是需要同時滿足,所以后面讀者會發現即使修改了GPS位置也不會顯示變化,這是因為變動的位置太小所致。

 

我們通過DDMS改變GPS位置后將可以看到如下的提示:

 

 

2.獲取位置提供器

我們已經知道了位置提供器是有多個的,但是實際情況並不是所有提供器我們都可以使用的,有些可能是關閉的,有些可能是開啟的,那么我們就需要知道當前有哪些位置提供器是可用的,只需要通過位置提供器就可以辦到,具體的代碼如下所示:

 1     [Activity(Label = "LocationStudy", MainLauncher = true, Icon = "@drawable/icon")]
 2     public class MainActivity : ListActivity
 3     {
 4         protected override void OnCreate(Bundle bundle)
 5         {
 6             base.OnCreate(bundle);
 7             LocationManager lm = (LocationManager)GetSystemService(LocationService);
 8             IList<String> list = lm.GetProviders(true);
 9             ListAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, list);
10         }
11 }

 

 

運行成功后我們就可以看到當前開啟的位置提供器有哪些了,下面是筆者虛擬的截圖:

 

接下來我們就可以從中選擇一個位置提供器,並通過位置提供器的GetProvider方法獲取,除了利用上面的方式還可以獲取指定位置提供器,比如的代碼將獲取三種不同的位置提供器:

1             LocationProvider lpGps = lm.GetProvider(LocationManager.GpsProvider);
2             LocationProvider lpNet = lm.GetProvider(LocationManager.NetworkProvider);
3             LocationProvider lpPsv = lm.GetProvider(LocationManager.PassiveProvider);

 

 

上面這些方式在實際中都會比較麻煩,所以下面我們還要介紹另一種獲取位置提供器的方式,它是基於條件的,通過我們的條件,位置管理器會選擇一個最佳的位置管理器給我們,比如下面的代碼,我們將會獲得符合這個條件的位置提供器:

 1             LocationManager lm = (LocationManager)GetSystemService(LocationService);
 2             Criteria cri = new Criteria();
 3             //精確度
 4             cri.Accuracy = Accuracy.Coarse;
 5             //耗能
 6             cri.PowerRequirement = Power.Low;
 7             //海拔精度
 8             cri.AltitudeRequired = false;
 9             //方向准確度
10             cri.BearingAccuracy = Accuracy.Low;
11             //是否花費
12             cri.CostAllowed = false;
13             //水平方向精度
14             cri.HorizontalAccuracy = Accuracy.Low;
15             //速度精度
16             cri.SpeedAccuracy = Accuracy.Low;
17             //是否具備速度能力
18             cri.SpeedRequired = false;
19             //垂直方向精度
20             cri.VerticalAccuracy = Accuracy.Low;
21             
22             //根據條件獲取最佳位置提供器
23             String pidStr = lm.GetBestProvider(cri, true);
24             LocationProvider lp = lm.GetProvider(pidStr);

通過代碼中的注釋,我們就能夠自己控制需要要素,從而獲取對應的位置提供器。位置信息不是必須要監聽從而實時確定當前的位置,我們也可以通過位置管理器的RequestSingleUpdate方法來實現只獲取一次,當然這個方法還是有點麻煩,而且還需要位置信息更新,有一個方法可以直接獲取到上一次位置更新的信息,這樣就可以避免位置信息必須要再更新一次,這就好比在你的應用打開之前,上一個應用已經更新的位置信息,那么再打開你的應用之后就不需要再重新獲取了,這個方法的調用如下所示:

1             LocationManager lm = (LocationManager)GetSystemService(LocationService);
2             Location lc = lm.GetLastKnownLocation(LocationManager.GpsProvider);

 

該方法獲取了上一次的GPS的位置信息,但在此之前沒有位置的更新的話,那么返回的位置信息可能是錯誤的,或不存在。

 

 

3.追蹤位置變化

在第一個示例中我們就利用了一種以接口的方式來接收位置更新,但是在Android中最佳的方式當然不是這樣的,我們還可以使用廣播接收器來接收這些位置更新,下面我們將學習如何使用該方式來接收位置更新,首先我們需要新建一個廣播接收器:

1     [BroadcastReceiver()]
2     public class LocationBroadCast : BroadcastReceiver
3     {
4         public override void OnReceive(Context context, Intent intent)
5         {
6             Location lc = (Location)intent.Extras.Get(LocationManager.KeyLocationChanged);
7             Toast.MakeText(context, lc.Longitude + "   " + lc.Latitude, ToastLength.Short).Show();
8         }
9 }

 

其中的內容跟第一節是一樣,利用Toast顯示更新后的位置。

 

下面我們就需要采用RequestLocationUpdates的另一個重載方法來實現注冊這個廣播接收器,代碼如下所示:

1             LocationManager lm = (LocationManager)GetSystemService(LocationService);
2             var tent = new Intent(this, typeof(LocationBroadCast));
3             var ptent = PendingIntent.GetBroadcast(this, 0, tent, PendingIntentFlags.UpdateCurrent);
4             lm.RequestLocationUpdates(LocationManager.GpsProvider, 5000, 100, ptent);

這其中筆者就不多做解釋了,只要是按照這個教程學習下來的應該會明白什么意思了。

 

 

4.臨近警告

這個概念非常容易理解,自然有了GPS定位,那么我們就可以設置一個區域,當使用者進入或離開這個區域的時候可以通知我們的APP,下面我們將上面的稍作修改既可以實現臨近警告,首先是廣播接收器:

 1     [BroadcastReceiver()]
 2     public class LocationBroadCast : BroadcastReceiver
 3     {
 4         public override void OnReceive(Context context, Intent intent)
 5         {
 6             if (intent.GetBooleanExtra(LocationManager.KeyProximityEntering, true))
 7             {
 8                 Toast.MakeText(context, "entering", ToastLength.Short).Show();
 9             }
10             else
11             {
12                 Toast.MakeText(context, "exiting", ToastLength.Short).Show();
13             }
14         }
15 }

 

這里我們通過KeyProximityEntering可以獲得當前是離開這個區域還是進入這個區域,對應的注冊部分也非常簡單:

1         protected override void OnCreate(Bundle bundle)
2         {
3             base.OnCreate(bundle);
4             LocationManager lm = (LocationManager)GetSystemService(LocationService);
5             var tent = new Intent(this, typeof(LocationBroadCast));
6             var ptent = PendingIntent.GetBroadcast(this, -1, tent, 0);
7             lm.AddProximityAlert(38.422006, -110.084095, 5000f, -1, ptent);
8         }

AddProximityAlert的前三個參數就是指定這個范圍的,第一個和第二個是定一個點,第三個則是半徑,第四個參數是超時時間,這里筆者設置為-1表示不存在超時,最后一個當然就是我們的廣播接收器了。

 

 

下節我們將學習如何在Xamarin.Android下實現SlidingMenu效果。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM