Windows phone 8 學習筆記(7) 裝置

來源:互聯網
上載者:User
文章目錄
  • 1.PhotoCamera
  • 2.PhotoCaptureDevice

本節主要涉及到 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();

 

作者:[Lipan]
出處:[http://www.cnblogs.com/lipan/]
著作權聲明:本文的著作權歸作者與部落格園共有。轉載時須註明原文出處以及作者,並保留原文指向型連結,不得更改原文內容。否則作者將保留追究其法律責任。 《上一篇:Windows phone 8 學習筆記 多任務
系列目錄
下一篇:Windows phone 8 學習筆記 定位地圖導航》
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.