與裝置硬體互動
在進行 Xamarin.Forms 跨平台應用程式開發的時候,您需要取得特定平台硬體內的許多資訊,例如:您需要取得裝置硬體的唯一識別碼、GPS定位最新資訊、電池狀態、網路連線狀況等等。
在這個章節內,開發者可以在核心PCL專案內,
- 得知裝置的電池電力、充電狀態等等 (使用
Battery Plugin
) - 檢查網路連線狀態、連線類型、可用頻寬等資訊 (使用
Connectivity Plugin
) - 取出裝置的相關資訊,如型號、作業系統等等 (使用
Device Info Plugin
)` - 取得 GPS 當時定位資訊,必且開啟手機內建的地圖應用程式來顯示 (使用
Geolocator / External Maps Plugin
) - 讓裝置硬體震動 (使用
Vibrate Plugin
)`
建立標籤式的樣板式頁面方案
- 首先,開啟您的 Visual Studio 2015
- 接著透過 Visual Studio 2015 功能表,選擇這些項目
檔案
>新增
>專案
準備新增一個專案。 - 接著,Visual Studio 2015 會顯示
新增專案
對話窗,請在這個對話窗上,進行選擇Visual C#
>Cross-Platform
>Blank Xaml App (Xamarin.Forms Portable)
- 接著,在最下方的
名稱
文字輸入盒處,輸入XFDevInfo
這個名稱,最後使用滑鼠右擊右下方的確定
按鈕。 - 當專案建立到一半,若您的開發環境還沒有建置與設定完成 Mac 電腦與 Xamarin Studio for Mac 系統,此時會看到
Xamarin Mac Agent Instructions
對話窗出現,這個對話窗是要提醒您進行與 Mac 電腦連線設定,這是因為,您無法在 Windows 作業系統進行 iOS 相關應用程式的建立與設計工作,而是需要透過 Mac 電腦安裝的 XCode 來協助您完成這些 iOS 應用程式的建立工作。不過,這不影響您繼續開發 Xamarin.Forms 的應用程式,只不過此時,您無法編譯與執行 iOS 的應用程式。 - 接著會看到
新的通用Windows專案
對話視窗,此時,您只需要按下確定
按鈕即可,此時,專案精靈會繼續完成相關平台的專案建立工作。 - 最後,整個新的 Xamarin.Forms 專案就建立完成了。
準備安裝套件
Battery Plugin
- 滑鼠右擊方案節點
XFDevInfo
,接著選擇管理方案的 NuGet 套件
- 在
NuGet - 解決方案
子標籤頁次出現後,點選瀏覽
- 請在搜尋文字輸入盒內,輸入
Xam.Plugin.Battery
,接著點選Xam.Plugin.Battery
項目;在右方點選要安裝到全部的專案內,最後,點選安裝
按鈕
Connectivity Plugin
- 滑鼠右擊方案節點
XFDevInfo
,接著選擇管理方案的 NuGet 套件
- 在
NuGet - 解決方案
子標籤頁次出現後,點選瀏覽
- 請在搜尋文字輸入盒內,輸入
Xam.Plugin.Connectivity
,接著點選Xam.Plugin.Connectivity
項目;在右方點選要安裝到全部的專案內,最後,點選安裝
按鈕
Device Info Plugin
- 滑鼠右擊方案節點
XFDevInfo
,接著選擇管理方案的 NuGet 套件
- 在
NuGet - 解決方案
子標籤頁次出現後,點選瀏覽
- 請在搜尋文字輸入盒內,輸入
Xam.Plugin.DeviceInfo
,接著點選Xam.Plugin.DeviceInfo
項目;在右方點選要安裝到全部的專案內,最後,點選安裝
按鈕
Geolocator
- 滑鼠右擊方案節點
XFDevInfo
,接著選擇管理方案的 NuGet 套件
- 在
NuGet - 解決方案
子標籤頁次出現後,點選瀏覽
- 請在搜尋文字輸入盒內,輸入
Xam.Plugin.Geolocator
,接著點選Xam.Plugin.Geolocator
項目;在右方點選要安裝到全部的專案內,最後,點選安裝
按鈕
External Maps
- 滑鼠右擊方案節點
XFDevInfo
,接著選擇管理方案的 NuGet 套件
- 在
NuGet - 解決方案
子標籤頁次出現後,點選瀏覽
- 請在搜尋文字輸入盒內,輸入
Xam.Plugin.ExternalMaps
,接著點選Xam.Plugin.ExternalMaps
項目;在右方點選要安裝到全部的專案內,最後,點選安裝
按鈕
Vibrate
- 滑鼠右擊方案節點
XFDevInfo
,接著選擇管理方案的 NuGet 套件
- 在
NuGet - 解決方案
子標籤頁次出現後,點選瀏覽
- 請在搜尋文字輸入盒內,輸入
Xam.Plugins.Vibrate
,接著點選Xam.Plugins.Vibrate
項目;在右方點選要安裝到全部的專案內,最後,點選安裝
按鈕
MainPage
- 在安裝好所有的擴充插件(Plugins),打開核心PCL 的 MainPage.xaml 檔案,將底下的 XAML 宣告定義複製到這個檔案內。
- 首先為了避免在 iOS 平台執行時候,最上方的狀態烈被遮蔽掉的問題,因此,透過
ContentPage.Padding
來定義整個頁面皆內縮 20dp。 - 這個頁面的控制項,使用了
ScrollView
版面配置來進行所有控制項的定位,因此,當螢幕無法顯示所有控制項的時候,使用者可以透過手勢滑動螢幕的操作方式,看到其他內容。 - 在這個 XAML 中,使用到的
ContentPage.Resources
功能,在這裡所宣告的內容,都可以直接在這個頁面內來引用;其中,<x:Double x:Key="TopicLabelFontSize">30</x:Double>
這個是宣告了一個Double
型別的物件,他的值為 30,在其他控制項若要參考這個物件,可以使用StaticResource
這個延伸標記功能取得這個物件值。 - 在這個頁面內,定義了大量的
Label
控制項,並且都有定義x:Name
延伸標記,而這個延伸標記是用於讓 code-behind 的C#程式碼,可以存取到這個控制項。因此,實際的處理邏輯,都存在 code-behind 程式碼內。
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XFDevInfo"
x:Class="XFDevInfo.MainPage">
<ContentPage.Padding>20</ContentPage.Padding>
<ContentPage.Resources>
<ResourceDictionary>
<x:Double x:Key="TopicLabelFontSize">30</x:Double>
<x:Double x:Key="DetailLabelFontSize">18</x:Double>
</ResourceDictionary>
</ContentPage.Resources>
<ScrollView
Orientation="Vertical"
>
<StackLayout
Orientation="Vertical"
>
<StackLayout
Orientation="Vertical"
HorizontalOptions="Start" VerticalOptions="Start"
>
<Label Text="電池狀態" FontSize="{StaticResource TopicLabelFontSize}" />
<Label x:Name="label電池狀態1" FontSize="{StaticResource DetailLabelFontSize}" />
<Label x:Name="label電池狀態2" FontSize="{StaticResource DetailLabelFontSize}" />
<Label x:Name="label電池狀態3" FontSize="{StaticResource DetailLabelFontSize}" />
</StackLayout>
<StackLayout
Orientation="Vertical"
HorizontalOptions="Start" VerticalOptions="Start"
>
<Label Text="網路狀態" FontSize="{StaticResource TopicLabelFontSize}" />
<Label x:Name="label網路狀態1" FontSize="{StaticResource DetailLabelFontSize}" />
<Label x:Name="label網路狀態2" FontSize="{StaticResource DetailLabelFontSize}" />
<Label x:Name="label網路狀態3" FontSize="{StaticResource DetailLabelFontSize}" />
<Label x:Name="label網路狀態4" FontSize="{StaticResource DetailLabelFontSize}" />
</StackLayout>
<StackLayout
Orientation="Vertical"
HorizontalOptions="Start" VerticalOptions="Start"
>
<Label Text="裝置資訊" FontSize="{StaticResource TopicLabelFontSize}" />
<Label x:Name="label裝置資訊1" FontSize="{StaticResource DetailLabelFontSize}" />
<Label x:Name="label裝置資訊2" FontSize="{StaticResource DetailLabelFontSize}" />
<Label x:Name="label裝置資訊3" FontSize="{StaticResource DetailLabelFontSize}" />
<Label x:Name="label裝置資訊4" FontSize="{StaticResource DetailLabelFontSize}" />
<Label x:Name="label裝置資訊5" FontSize="{StaticResource DetailLabelFontSize}" />
<Label x:Name="label裝置資訊6" FontSize="{StaticResource DetailLabelFontSize}" />
</StackLayout>
<StackLayout
Orientation="Vertical"
HorizontalOptions="Start" VerticalOptions="Start"
>
<Label Text="位置定位" FontSize="{StaticResource TopicLabelFontSize}" />
<Label x:Name="label位置定位1" FontSize="{StaticResource DetailLabelFontSize}" />
<Button x:Name="button位置定位" Text="位置定位" Clicked="Onbutton位置定位" />
<Button x:Name="button開啟地圖" Text="開啟地圖" Clicked="Onbutton開啟地圖" />
</StackLayout>
<StackLayout
Orientation="Vertical"
HorizontalOptions="Start" VerticalOptions="Start"
>
<Label Text="觸發震動" FontSize="{StaticResource TopicLabelFontSize}" />
<Button x:Name="button觸發震動" Text="觸發震動" Clicked="Onbutton觸發震動" />
</StackLayout>
</StackLayout>
</ScrollView>
</ContentPage>
- 請將下列 C# 程式碼複製到 MainPage.xaml.cs內。
- Init() 方法會由建構式來呼叫,其適用於透過剛剛安裝的各個插件(Plugins),進行存取,取得相關內容,並且設定到 XAML 控制項內。
- 各個插件(Plugins)使用方式其實相當簡單,首先,取得現在插件物件,這裡以電池資訊插件為例。var CrossBattery = Plugin.Battery.CrossBattery.Current;接著就可以透過 CrossBattery 物件變數,來取得更詳盡的電池資訊,底下為取得電池電力上下多少?CrossBattery.RemainingChargePercent
- 想要透過插件取得當時手機位置定位,可以透過
CrossGeolocator
取得當時的物件var fooCrossGeolocator = CrossGeolocator.Current;設定DesiredAccuracy
屬性,設定定位精準度,單位是公尺最後,透過非同步方法GetPositionAsync
,取得現在所在位置座標資訊`,方法內所傳遞過去的參數為逾時時間,單位是毫秒(1毫秒 = 1/1000 秒)position = await fooCrossGeolocator.GetPositionAsync(timeoutMilliseconds: 10000);
MainPage.xaml.cs
using Plugin.Battery;
using Plugin.Connectivity;
using Plugin.DeviceInfo;
using Plugin.ExternalMaps;
using Plugin.Geolocator;
using Plugin.Geolocator.Abstractions;
using Plugin.Vibrate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace XFDevInfo
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
Init();
}
public async void Init()
{
#region 電池資訊
var CrossBattery = Plugin.Battery.CrossBattery.Current;
label電池狀態1.Text = $"電源來源 : {CrossBattery.PowerSource}";
label電池狀態2.Text = $"充電狀態 : {CrossBattery.Status}";
label電池狀態3.Text = $"可用電力 : {CrossBattery.RemainingChargePercent}";
#endregion
#region 網路狀態
var fooCrossConnectivity = CrossConnectivity.Current;
label網路狀態1.Text = $"是否連上Internet : {fooCrossConnectivity.IsConnected}";
var fooBandwidths = fooCrossConnectivity.Bandwidths;
string fooBandwidthsString = "";
foreach (var item in fooBandwidths)
{
fooBandwidthsString += item + " ";
}
label網路狀態2.Text = $"可用頻寬 : {fooBandwidthsString}";
var fooConnectionTypes = fooCrossConnectivity.ConnectionTypes;
string fooConnectionTypesString = "";
foreach (var item in fooConnectionTypes)
{
fooConnectionTypesString += item + " ";
}
label網路狀態3.Text = $"連線類型 : {fooConnectionTypesString}";
var fooIsReachable = await fooCrossConnectivity.IsRemoteReachable("www.xamarin.com", 80, 2000);
label網路狀態4.Text = $"可否連上 Xamarin : {fooIsReachable}";
#endregion
#region 裝置資訊
var fooCrossDeviceInfo = CrossDeviceInfo.Current;
label裝置資訊1.Text = $"此裝置的ID : {fooCrossDeviceInfo.Id}";
var fooGenerateAppId = fooCrossDeviceInfo.GenerateAppId();
label裝置資訊6.Text = $"此應用程式的ID : {fooGenerateAppId}";
label裝置資訊2.Text = $"裝置的型號 : {fooCrossDeviceInfo.Model}";
label裝置資訊3.Text = $"裝置平台 : {fooCrossDeviceInfo.Platform}";
label裝置資訊4.Text = $"作業系統版本 : {fooCrossDeviceInfo.Version}";
label裝置資訊5.Text = $"作業系統版本編號 : {fooCrossDeviceInfo.VersionNumber}";
#endregion
#region 位置定位
#endregion
#region 觸發震動
#endregion
}
#region 位置定位
Position position;
async void Onbutton位置定位(object sender, EventArgs e)
{
var fooCrossGeolocator = CrossGeolocator.Current;
fooCrossGeolocator.DesiredAccuracy = 50;
position = await fooCrossGeolocator.GetPositionAsync(timeoutMilliseconds: 10000);
label位置定位1.Text = $"Lat={position.Latitude}, Lon={position.Longitude}";
}
void Onbutton開啟地圖(object sender, EventArgs e)
{
if (position != null)
{
CrossExternalMaps.Current.NavigateTo("現在位置", position.Latitude, position.Longitude);
}
}
#endregion
#region 觸發震動
void Onbutton觸發震動(object sender, EventArgs e)
{
var fooCrossVibrate = CrossVibrate.Current;
fooCrossVibrate.Vibration(1000);
}
#endregion
}
}
實際執行畫面
Android 執行結果
請在方案總管內,滑鼠右擊
XFDevInfo.Droid
專案,選擇 設定為起始專案
,接著按下 F5
開始執行。
若是要在 Visual Studio Emulator for Android 模擬器下測試 GPS 定位功能,可以點選該模擬器右邊的工具列最下方的往右雙箭頭,如下圖所示。
此時模擬器的其他工具對話窗就會顯示出來,請點選
位置
標籤頁,將地圖縮放與移動到您想要的位置,接著點選上方的 開啟與關閉定位模式
,在進入到定位模式後,點選地圖上的任一個地方,左下方就是出現一個座標點,若此時應用程式要取得當時GPS定位位置,就會取得這個位置。佈署注意事項
iOS 執行結果
請在方案總管內,滑鼠右擊
XFDevInfo.iOS
專案,選擇 設定為起始專案
,接著按下 F5
開始執行。