Xamarin.Forms 對應初始化和組態
控件 Map
會在每個平臺上使用原生地圖控件。 這可為使用者提供快速且熟悉的地圖體驗,但表示需要一些設定步驟才能遵守每個平臺 API 需求。
對應初始化
控件 Map
是由 Xamarin.Forms提供。對應 NuGet 套件,這應該新增至方案中的每個專案。
安裝 之後。 Xamarin.Forms對應 NuGet 套件,它必須在每個平台專案中初始化。
在 iOS 上,應該在 方法之後Xamarin.Forms.Forms.Init
叫Xamarin.FormsMaps.Init
用 方法,以AppDelegate.cs發生此問題:
Xamarin.FormsMaps.Init();
在Android上,應該在方法之後Xamarin.Forms.Forms.Init
叫Xamarin.FormsMaps.Init
用 方法,以MainActivity.cs發生此問題:
Xamarin.FormsMaps.Init(this, savedInstanceState);
在 通用 Windows 平台 (UWP) 上,這應該發生在MainPage.xaml.cs,方法是從MainPage
建構函式叫Xamarin.FormsMaps.Init
用 方法:
Xamarin.FormsMaps.Init("INSERT_AUTHENTICATION_TOKEN_HERE");
如需 UWP 上所需驗證令牌的資訊,請參閱 通用 Windows 平台。
新增 NuGet 套件並在每個應用程式內呼叫初始化方法之後, Xamarin.Forms.Maps
就可以在共用程式代碼專案中使用 API。
平台設定
在 Android 和地圖顯示之前,需要 通用 Windows 平台 (UWP) 的額外設定。 此外,在iOS、Android和UWP上,存取使用者的位置需要已授與應用程式的位置許可權。
iOS
在 iOS 上顯示地圖並與其互動不需要任何其他設定。 不過,若要存取位置服務,您必須在Info.plist 中設定下列索引鍵:
- iOS 11 和更新版本
NSLocationWhenInUseUsageDescription
– 在應用程式使用時使用位置服務NSLocationAlwaysAndWhenInUseUsageDescription
– 用於隨時使用位置服務
- iOS 10 和更早版本
NSLocationWhenInUseUsageDescription
– 在應用程式使用時使用位置服務NSLocationAlwaysUsageDescription
– 用於隨時使用位置服務
若要支援 iOS 11 和更早版本,您可以包含所有三個索引鍵: NSLocationWhenInUseUsageDescription
、 NSLocationAlwaysAndWhenInUseUsageDescription
和 NSLocationAlwaysUsageDescription
。
Info.plist 中這些索引鍵的 XML 表示如下所示。 您應該更新 string
值,以反映應用程式使用位置資訊的方式:
<key>NSLocationAlwaysUsageDescription</key>
<string>Can we use your location at all times?</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Can we use your location when your application is being used?</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Can we use your location at all times?</string>
編輯 Info.plist 檔案時,也可以在 [來源] 檢視中新增 Info.plist 專案:
然後,當應用程式嘗試存取使用者的位置時,會顯示提示,要求存取:
Android
在 Android 上顯示及與地圖互動的設定程式如下:
- 取得Google Maps API 金鑰,並將其新增至指令清單。
- 在指令清單中指定Google Play服務版本號碼。
- 在指令清單中指定 Apache HTTP 舊版連結庫的需求。
- [選擇性]在指令清單中指定WRITE_EXTERNAL_STORAGE許可權。
- [選擇性]在指令清單中指定位置許可權。
- [選擇性]要求類別中的
MainActivity
運行時間位置許可權。
如需正確設定指令清單檔的範例,請參閱 範例應用程式的AndroidManifest.xml 。
取得Google Maps API 金鑰
若要在 Android 上使用 Google Maps API ,您必須產生 API 金鑰。 若要這樣做,請遵循取得Google Maps API 金鑰中的指示。
取得 API 金鑰之後,它必須在 Properties/AndroidManifest.xml 檔案的 元素內<application>
新增:
<application ...>
<meta-data android:name="com.google.android.geo.API_KEY" android:value="PASTE-YOUR-API-KEY-HERE" />
</application>
這會將 API 金鑰內嵌至指令清單。 如果沒有有效的 API 金鑰, Map
控制件就會顯示空白方格。
注意
com.google.android.geo.API_KEY
是 API 金鑰的建議元資料名稱。 為了回溯相容性, com.google.android.maps.v2.API_KEY
可以使用元數據名稱,但只允許驗證Android地圖服務 API v2。
若要讓 APK 存取 Google Maps,您必須針對您用來簽署 APK 的每個金鑰存放區(偵錯和發行)包含 SHA-1 指紋和套件名稱。 例如,如果您使用一部計算機進行偵錯,另一部計算機產生發行 APK,則應該從第一部計算機的偵錯密鑰存放區包含 SHA-1 憑證指紋,以及第二部計算機的發行密鑰存放區中的 SHA-1 憑證指紋。 如果應用程式的 套件名稱 變更,也請記得編輯密鑰認證。 請參閱 取得Google Maps API 金鑰。
指定Google Play服務版本號碼
在 AndroidManifest.xml 的 元素內<application>
新增下列宣告:
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
這會將應用程式編譯的 Google Play 服務版本內嵌到指令清單中。
指定 Apache HTTP 舊版連結庫的需求
Xamarin.Forms如果您的應用程式以 API 28 或更新版本為目標,您必須在 AndroidManifest.xml 的 元素中<application>
新增下列宣告:
<uses-library android:name="org.apache.http.legacy" android:required="false" />
這會告訴應用程式使用已從 bootclasspath
Android 9 中移除的 Apache Http 用戶端連結庫。
指定WRITE_EXTERNAL_STORAGE許可權
如果您的應用程式以 API 22 或更低版本為目標,可能需要將許可權新增 WRITE_EXTERNAL_STORAGE
至指令清單,做為 專案的子 <manifest>
系:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
如果您的應用程式以 API 23 或更新版本為目標,則不需要這樣做。
指定位置許可權
如果您的應用程式需要存取使用者的位置,您必須藉由將 或 ACCESS_FINE_LOCATION
許可權新增ACCESS_COARSE_LOCATION
至指令清單(或兩者)來要求許可權,做為 專案的子<manifest>
系:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.myapp">
...
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
許可權 ACCESS_COARSE_LOCATION
可讓 API 使用 WiFi 或行動數據,或兩者來判斷裝置的位置。 許可權 ACCESS_FINE_LOCATION
可讓 API 使用全域定位系統(GPS)、WiFi 或行動數據,盡可能判斷確切的位置。
或者,您可以使用指令清單編輯器來新增下列許可權來啟用這些許可權:
AccessCoarseLocation
AccessFineLocation
以下螢幕快照所示:
要求運行時間位置許可權
如果您的應用程式以 API 23 或更新版本為目標,而且需要存取使用者的位置,則必須檢查它是否具有運行時間的必要許可權,並在沒有許可權時要求它。 執行下列工作即可達成這點:
在類別中
MainActivity
,新增下列欄位:const int RequestLocationId = 0; readonly string[] LocationPermissions = { Manifest.Permission.AccessCoarseLocation, Manifest.Permission.AccessFineLocation };
在 類別中
MainActivity
,新增下列OnStart
覆寫:protected override void OnStart() { base.OnStart(); if ((int)Build.VERSION.SdkInt >= 23) { if (CheckSelfPermission(Manifest.Permission.AccessFineLocation) != Permission.Granted) { RequestPermissions(LocationPermissions, RequestLocationId); } else { // Permissions already granted - display a message. } } }
如果應用程式是以 API 23 或更新版本為目標,此程式代碼會執行許可權的
AccessFineLocation
運行時間許可權檢查。 如果未授與許可權,呼叫 方法會提出RequestPermissions
許可權要求。在 類別中
MainActivity
,新增下列OnRequestPermissionsResult
覆寫:public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults) { if (requestCode == RequestLocationId) { if ((grantResults.Length == 1) && (grantResults[0] == (int)Permission.Granted)) // Permissions granted - display a message. else // Permissions denied - display a message. } else { base.OnRequestPermissionsResult(requestCode, permissions, grantResults); } }
此覆寫會處理許可權要求的結果。
此程式代碼的整體效果是當應用程式要求使用者的位置時,會顯示下列對話方塊要求權限:
通用 Windows 平台
在 UWP 上,您的應用程式必須先經過驗證,才能顯示地圖並取用地圖服務。 若要驗證您的應用程式,您必須指定地圖驗證金鑰。 如需詳細資訊,請參閱 要求地圖驗證密鑰。 然後,應該在方法呼叫中 FormsMaps.Init("AUTHORIZATION_TOKEN")
指定驗證令牌,以使用 Bing 地圖服務驗證應用程式。
注意
在UWP上,若要使用地理編碼等地圖服務,您也必須將 MapService.ServiceToken
屬性設定為驗證密鑰值。 這可以使用下列程式代碼行來完成: Windows.Services.Maps.MapService.ServiceToken = "INSERT_AUTH_TOKEN_HERE";
。
此外,如果您的應用程式需要存取使用者的位置,您必須在套件指令清單中啟用位置功能。 執行下列工作即可達成這點:
在 [方案總管] 中,按兩下 [package.appxmanifest],然後選取 [功能] 索引標籤。
在 [功能] 清單中,選取 [位置] 核取方塊。 這會將
location
裝置功能新增至套件指令清單檔案。<Capabilities> <!-- DeviceCapability elements must follow Capability elements (if present) --> <DeviceCapability Name="location"/> </Capabilities>
發行組建
UWP 版本組建使用 .NET 原生編譯,直接將應用程式編譯為機器碼。 不過,結果就是UWP上控件的 Map
轉譯器可能會連結出可執行檔。 您可以使用 App.xaml.cs 中 方法的 Forms.Init
UWP 特定多載來修正此問題:
var assembliesToInclude = new [] { typeof(Xamarin.Forms.Maps.UWP.MapRenderer).GetTypeInfo().Assembly };
Xamarin.Forms.Forms.Init(e, assembliesToInclude);
此程式代碼會將 類別所在的元件 Xamarin.Forms.Maps.UWP.MapRenderer
傳遞至 Forms.Init
方法。 這可確保 .NET 原生編譯程式不會將元件連結出可執行檔。
重要
執行發行組建時,如果無法這麼做,則會導致 Map
控件不會出現。