Windows phone 8 学习笔记(7) 设备(转)
本節主要涉及到 Windows phone 8 手機支持的各類設備,包括相機、設備狀態,振動裝置等。還有各類感應器,包括磁力計、加速度器和陀螺儀。通過設備狀態可以獲取內存、硬件、電源、鍵盤等狀態;通過相機捕獲照片和視頻;各類感應器幫助我們獲取設備的運動狀態等。
快速導航:
一、設備狀態
二、相機
三、羅盤傳感器
四、加速度計
五、陀螺儀
六、如何振動手機
一、設備狀態
通過DeviceStatus 類我們可以確定設備的相關狀態信息,比如內存大小啊,固件版本啊,還有是否部署了物理鍵盤等信息,以及與電源的相關信息,當前是電池還是外部電源等。
我們通過下面的代碼展示如何獲取這些信息。
[C#]
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
var timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 10);
timer.Tick += new EventHandler((a, b) =>
{
//當前內存使用了多少字節
var x = Microsoft.Phone.Info.DeviceStatus.ApplicationCurrentMemoryUsage;
textblock1.Text = "當前內存:" + convert(x);
//高峰時內存使用了多少字節
var y = Microsoft.Phone.Info.DeviceStatus.ApplicationPeakMemoryUsage;
textblock2.Text = "峰值內存:" + convert(y);
});
timer.Start();
textblock3.Text = "設備制造商名:"+ DeviceStatus.DeviceManufacturer;
textblock4.Text = "設備名:" + DeviceStatus.DeviceName;
textblock5.Text = "固件版本:"+ DeviceStatus.DeviceFirmwareVersion;
textblock6.Text = "硬件版本:"+ DeviceStatus.DeviceHardwareVersion;
textblock7.Text = "物理內存大小:"+convert( DeviceStatus.DeviceTotalMemory);
textblock8.Text = "應用進程可分配最大額外內存:" + convert(DeviceStatus.ApplicationMemoryUsageLimit);
textblock9.Text ="是否包含硬件鍵盤:"+ DeviceStatus.IsKeyboardPresent.ToString();
textblock10.Text = "是否部署硬件鍵盤:" + DeviceStatus.IsKeyboardDeployed.ToString();
textblock11.Text = "電源狀態:" + DeviceStatus.PowerSource.ToString();
//關閉或部署鍵盤時
DeviceStatus.KeyboardDeployedChanged += new EventHandler((a, b) => {
textblock9.Text = "鍵盤變更,是否包含硬件鍵盤:" + DeviceStatus.IsKeyboardPresent.ToString();
});
//設備電源變更時
DeviceStatus.PowerSourceChanged += new EventHandler((a, b) =>
{
textblock11.Text = "電源狀態變更:" + DeviceStatus.PowerSource.ToString();
});
base.OnNavigatedTo(e);
}
private string convert(long x)
{
return Math.Round(x / (1024.0 * 1024.0), 2) + "M";
}
二、相機
有兩個類可以調用相機,分別是PhotoCamera和PhotoCaptureDevice,一般如果要支持WP7以及對相機基本調用則使用前者,后者用于相機的高級捕獲。
1.PhotoCamera
我們首先通過PhotoCamera來訪問相機,我們可以實現一個具備拍照功能的基本相機,包含自動對焦、閃光燈、分辨率調整等功能,下面代碼演示了如何使用。
[XAML]
<Grid x:Name="LayoutRoot" Background="Transparent"><Canvas x:Name="canvas1" Margin="0,0,0,0" Tap="canvas1_Tap" Width="800" Height="480"><Canvas.Background><VideoBrush x:Name="viewfinderBrush" /></Canvas.Background><TextBlock x:Name="focusBrackets" Text="[ ]" FontSize="40" Visibility="Collapsed"/></Canvas><ListBox x:Name="listbox1" Margin="95,394,538,59" SelectionChanged="listbox1_SelectionChanged"><ListBox.ItemTemplate><DataTemplate><TextBlock Text="{Binding}"></TextBlock></DataTemplate></ListBox.ItemTemplate><ListBox.ItemContainerStyle><Style TargetType="ListBoxItem"><Setter Property="Margin" Value="0,0,10,0" /></Style></ListBox.ItemContainerStyle><ListBox.ItemsPanel><ItemsPanelTemplate><StackPanel Orientation="Horizontal"></StackPanel></ItemsPanelTemplate></ListBox.ItemsPanel></ListBox><TextBlock x:Name="textblock1" Foreground="Red" HorizontalAlignment="Left" Margin="584,22,0,0" TextWrapping="Wrap" VerticalAlignment="Top"/><TextBlock HorizontalAlignment="Left" Margin="10,394,0,0" TextWrapping="Wrap" Text="閃光燈:" VerticalAlignment="Top"/><TextBlock HorizontalAlignment="Left" Margin="273,394,0,0" TextWrapping="Wrap" Text="分辨率:" VerticalAlignment="Top"/><ListBox x:Name="listbox2" Margin="350,394,10,59" SelectionChanged="listbox2_SelectionChanged"><ListBox.ItemTemplate><DataTemplate><TextBlock Text="{Binding}"/></DataTemplate></ListBox.ItemTemplate><ListBox.ItemContainerStyle><Style TargetType="ListBoxItem"><Setter Property="Margin" Value="0,0,10,0" /></Style></ListBox.ItemContainerStyle><ListBox.ItemsPanel><ItemsPanelTemplate><StackPanel Orientation="Horizontal"/></ItemsPanelTemplate></ListBox.ItemsPanel></ListBox><Button Content="對焦" HorizontalAlignment="Left" Margin="517,410,0,0" VerticalAlignment="Top" Click="Button_Click_1"/><Button Content="拍照" HorizontalAlignment="Left" Margin="623,410,0,0" VerticalAlignment="Top" Click="Button_Click_2"/><TextBlock Width="500" x:Name="textblock2" HorizontalAlignment="Left" Margin="10,434,0,0" TextWrapping="Wrap" VerticalAlignment="Top"/></Grid>[C#]
public partial class MainPage : PhoneApplicationPage{// 構造函數public MainPage(){InitializeComponent();}PhotoCamera photoCamera;MediaLibrary library = new MediaLibrary();protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e){//判斷是否支持相機if (PhotoCamera.IsCameraTypeSupported(CameraType.Primary)){textblock1.Text = "當前取景:后置攝像頭";photoCamera = new PhotoCamera(CameraType.Primary);}else if (PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing)){textblock1.Text = "當前取景:前置攝像頭";photoCamera = new PhotoCamera(CameraType.FrontFacing);}else{textblock1.Text = "設備不支持相機";return;}textblock2.Text = "相機正在初始化中.";viewfinderBrush.SetSource(photoCamera);//相機初始化完成時photoCamera.Initialized += (a, b) =>{if (b.Succeeded){this.Dispatcher.BeginInvoke(() =>{SupportedFlashModesInit();AvailableResolutionsInit();textblock2.Text = "相機初始化完成.";});}};//有圖像可用時(拍攝完成)photoCamera.CaptureImageAvailable += (a, b) =>{this.Dispatcher.BeginInvoke(() => { textblock2.Text = "正在保存照片."; });library.SavePictureToCameraRoll(Guid.NewGuid().ToString() + ".jpg", b.ImageStream);this.Dispatcher.BeginInvoke(() => { textblock2.Text = "照片保存成功."; });};//對焦完成時photoCamera.AutoFocusCompleted += (a, b) =>{this.Dispatcher.BeginInvoke(() =>{textblock2.Text = "自動對焦完成.";focusBrackets.Visibility = Visibility.Collapsed;});};base.OnNavigatedTo(e);}/// <summary>/// 顯示支持的閃光模式/// </summary>private void SupportedFlashModesInit(){List<string> flashModes = new List<string>() { "關" };if (photoCamera.IsFlashModeSupported(FlashMode.On)) flashModes.Add("開");if (photoCamera.IsFlashModeSupported(FlashMode.Auto)) flashModes.Add("自動");if (photoCamera.IsFlashModeSupported(FlashMode.RedEyeReduction)) flashModes.Add("紅眼");listbox1.ItemsSource = flashModes;}/// <summary>/// 顯示支持的分辨率/// </summary>private void AvailableResolutionsInit(){listbox2.ItemsSource = photoCamera.AvailableResolutions;}//對焦private void Button_Click_1(object sender, RoutedEventArgs e){//是否支持自動對焦if (photoCamera.IsFocusSupported == true){try{photoCamera.Focus();}catch(Exception ex){this.Dispatcher.BeginInvoke(() => { textblock2.Text = "對焦錯誤:" + ex.Message; });}}else{this.Dispatcher.BeginInvoke(() => { textblock2.Text = "相機不支持自動對焦."; });}}//拍照private void Button_Click_2(object sender, RoutedEventArgs e){if (photoCamera != null){try{photoCamera.CaptureImage();}catch (Exception ex){this.Dispatcher.BeginInvoke(() => { textblock2.Text = "拍照錯誤:" + ex.Message; });}}}//特定點對焦private void canvas1_Tap(object sender, GestureEventArgs e){if (photoCamera == null) return;if (!photoCamera.IsFocusAtPointSupported){textblock2.Text = "不支持特定點對焦";return;}try{Point tapLocation = e.GetPosition(canvas1);focusBrackets.SetValue(Canvas.LeftProperty, tapLocation.X - 30);focusBrackets.SetValue(Canvas.TopProperty, tapLocation.Y - 28);double focusXPercentage = tapLocation.X / canvas1.Width;double focusYPercentage = tapLocation.Y / canvas1.Height;focusBrackets.Visibility = Visibility.Visible;photoCamera.FocusAtPoint(focusXPercentage, focusYPercentage);this.Dispatcher.BeginInvoke(delegate(){textblock2.Text = String.Format("針對位置 [{0:N2} , {1:N2}] 開始對焦", focusXPercentage, focusYPercentage);});}catch (Exception focusError){this.Dispatcher.BeginInvoke(delegate(){textblock2.Text ="對焦錯誤:"+ focusError.Message;focusBrackets.Visibility = Visibility.Collapsed;});}}//切換閃光燈模式private void listbox1_SelectionChanged(object sender, SelectionChangedEventArgs e){if (e.AddedItems.Count == 0) return;switch (e.AddedItems[0].ToString()){case "關":photoCamera.FlashMode = FlashMode.Off;break;case "自動":photoCamera.FlashMode = FlashMode.Auto;break;case "紅眼":photoCamera.FlashMode = FlashMode.RedEyeReduction;break;case "開":photoCamera.FlashMode = FlashMode.On;break;}textblock2.Text = "已將閃光模式設置為:" + e.AddedItems[0].ToString();}//切換分辨率private void listbox2_SelectionChanged(object sender, SelectionChangedEventArgs e){if (e.AddedItems.Count == 0) return;photoCamera.Resolution = (Size)e.AddedItems[0];textblock2.Text = "已將分辨率設置為:" + photoCamera.Resolution.ToString();}}2.PhotoCaptureDevice
PhotoCaptureDevice對相機的高級捕獲很多都是用于支持后續版本的,下面我們簡單演示下通過PhotoCaptureDevice捕獲照片并顯示出來的方法。
[XAML]
<Grid x:Name="LayoutRoot" Background="Transparent"><Canvas x:Name="canvas1" Margin="0,0,0,0" Width="800" Height="480"><Canvas.Background><VideoBrush x:Name="viewfinderBrush" /></Canvas.Background><Button Content="拍照" Canvas.Left="653" Canvas.Top="383" Click="Button_Click_1"/><Image x:Name="img1" Height="231" Canvas.Left="508" Canvas.Top="87" Width="220"/></Canvas></Grid>[C#]
public partial class MainPage : PhoneApplicationPage{// 構造函數public MainPage(){InitializeComponent();}PhotoCaptureDevice photoCaptureDevice;CameraCaptureSequence cameraCaptureSequence;MemoryStream captureStream = new MemoryStream();protected async override void OnNavigatedTo(NavigationEventArgs e){if (PhotoCaptureDevice.AvailableSensorLocations.Contains(CameraSensorLocation.Back)){var SupportedResolutions = PhotoCaptureDevice.GetAvailableCaptureResolutions(CameraSensorLocation.Back);photoCaptureDevice = await PhotoCaptureDevice.OpenAsync(CameraSensorLocation.Back, SupportedResolutions[0]);}else if (PhotoCaptureDevice.AvailableSensorLocations.Contains(CameraSensorLocation.Front)){var SupportedResolutions = PhotoCaptureDevice.GetAvailableCaptureResolutions(CameraSensorLocation.Front);photoCaptureDevice = await PhotoCaptureDevice.OpenAsync(CameraSensorLocation.Front, SupportedResolutions[0]);}else{return;}viewfinderBrush.SetSource(photoCaptureDevice);cameraCaptureSequence = photoCaptureDevice.CreateCaptureSequence(1);// Set camera properties.photoCaptureDevice.SetProperty(KnownCameraPhotoProperties.FlashMode, FlashState.On);photoCaptureDevice.SetProperty(KnownCameraGeneralProperties.PlayShutterSoundOnCapture, true);photoCaptureDevice.SetProperty(KnownCameraGeneralProperties.AutoFocusRange, AutoFocusRange.Infinity);cameraCaptureSequence.Frames[0].DesiredProperties[KnownCameraPhotoProperties.SceneMode] = CameraSceneMode.Portrait;cameraCaptureSequence.Frames[0].CaptureStream = captureStream.AsOutputStream();await photoCaptureDevice.PrepareCaptureSequenceAsync(cameraCaptureSequence);base.OnNavigatedTo(e);}public async void Capture(){await cameraCaptureSequence.StartCaptureAsync();var b = new BitmapImage();b.SetSource(captureStream);img1.Source = b;}private void Button_Click_1(object sender, RoutedEventArgs e){Capture();}}三、羅盤傳感器
羅盤傳感器用于感知地球磁場,功能主要是用于確定方向,有了它,我們可以開發類似指南針的應用。
不是每個設備都必須支持羅盤傳感器的,所以我們需要在使用前判斷設備是否支持。
[C#]
if (!Compass.IsSupported){MessageBox.Show("設備不支持羅盤");return;}如果設備支持,我們還需要判斷羅盤的精度,如果精度不高,需要提醒用戶校對精度。當羅盤獲取數據時,通過CurrentValueChanged事件處理獲取的數據。
[XAML]
<Canvas x:Name="canvas1" Background="Black" Visibility="Collapsed"><Image x:Name="image3" Canvas.Top="12" Canvas.Left="70" Source="Image/3.png"/><TextBlock TextWrapping="Wrap" Width="450" Canvas.Top="240" Text=" 您的羅盤需要校驗,請按照上圖所示的方式移動您的手機,系統將自動完成校驗過程。" /><Button Content="完成校驗" Canvas.Left="154" Canvas.Top="596" Click="Button_Click_1"/> </Canvas>[C#]
compass = new Compass(); //指定數據更新時間間隔. compass.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20); //從羅盤傳感器獲取數據時發生 compass.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<CompassReading>>(compass_CurrentValueChanged); //羅盤需要校驗時發生 compass.Calibrate += new EventHandler<CalibrationEventArgs>(compass_Calibrate);compass.Start();//從傳感器獲取新數據時發生 void compass_CurrentValueChanged(object sender, SensorReadingEventArgs<CompassReading> e) {//獲取到地球地理北極順時值偏移角度trueHeading = e.SensorReading.TrueHeading; }//羅盤需要校驗時發生 void compass_Calibrate(object sender, CalibrationEventArgs e) {Dispatcher.BeginInvoke(() =>{//羅盤需要校驗,canvas1指示用戶校驗canvas1.Visibility = Visibility.Visible;}); }
四、加速度計
加速度計用于測試某個時刻設備在空間中的姿態。它與重力相關。它的取值在分為x、y、z三個方向取值,下面我們理解下這些取值含義。我們假設設備正面向上平躺在水平桌面為參照標準:
??? x:設備左傾的趨勢越大,值越小,左傾90度時,值為-1;相反,右傾時值越大,最大為1。
??? y:設備后傾的趨勢越大,值越小,后傾90度時,值為-1;相反,前傾時值越大,最大為1。
??? z:設備下傾的趨勢越大,值越大,下傾180度(翻面了)時,值為1;正面朝上(不動)時,最為-1。
總的說來,x控制左右,y控制前后,z控制上下。下面我們在看看如何使用。?
? [C#]
//校驗設備是否支持 if (!Accelerometer.IsSupported) {MessageBox.Show("設備不支持重力感應"); }var accelerometer = new Accelerometer(); accelerometer.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20); //從加速度傳感器獲取數據時發生 accelerometer.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(accelerometer_CurrentValueChanged); accelerometer.Start();//從加速度傳感器獲取數據時發生 void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e) {//獲取到設備加速度矢量vector3 = e.SensorReading.Acceleration; }五、陀螺儀
陀螺儀用于檢測設備在空間中的旋轉趨勢。它的三個取值即為設備繞三個坐標軸的旋轉速度。
??? x:水平左右向軸的旋轉速度。
??? y:水平前后向軸的旋轉速度。
??? z:垂直上下向軸的旋轉速度。
然后我們看看如何調用陀螺儀。
[C#]
//判斷設備是否支持陀螺儀 if (!Gyroscope.IsSupported) {MessageBox.Show("設備不支持陀螺儀"); }gyroscope = new Gyroscope(); gyroscope.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20); //從陀螺儀獲取數據時發生 gyroscope.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<GyroscopeReading>>(gyroscope_CurrentValueChanged);//啟動陀螺儀,實際使用可能啟動失敗需要捕獲異常 gyroscope.Start();//從陀螺儀獲取數據是發生 void gyroscope_CurrentValueChanged(object sender, SensorReadingEventArgs<GyroscopeReading> e) {//獲取設備繞每個軸的旋轉速度var rotationRate = e.SensorReading.RotationRate; }六、如何振動手機
手機的振動可以通過一句簡單的API完成,在某些情況下可能還需要設置振動的世界,以及提前結束振動。下面代碼演示了如何操作。
[C#]
VibrateController testVibrateController = VibrateController.Default;//定義振動時間testVibrateController.Start(TimeSpan.FromSeconds(3));//在振動時間達到前停止振動testVibrateController.Stop();總結
以上是生活随笔為你收集整理的Windows phone 8 学习笔记(7) 设备(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [原]SDL开发教程
- 下一篇: 烂泥:CentOS6.5挂载window