这是我刚刚完成的用于 Windows Phone 8 的 Shaker Torch/Flash 灯的完整解决方案。请记住在 WMAppManifest.xml 中设置相机和麦克风设备上限。摇动以打开/关闭。它使用 ShakeGestures 库来捕捉震动。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using Microsoft.Phone.Controls;
using ShakeGestures;
using Windows.Phone.Media.Capture;
namespace ShakerTorch
{
public partial class MainPage : PhoneApplicationPage
{
#region Initialisation
private AudioVideoCaptureDevice _captureDevice;
private bool _flashOn;
private const CameraSensorLocation _sensorLocation = CameraSensorLocation.Back;
public MainPage()
{
InitializeComponent();
ShakeGesturesHelper.Instance.ShakeGesture += OnShake;
ShakeGesturesHelper.Instance.MinimumRequiredMovesForShake = 5;
ShakeGesturesHelper.Instance.Active = true;
InitialiseCaptureDevice();
}
#endregion
private async void InitialiseCaptureDevice()
{
_captureDevice = await GetCaptureDevice();
}
private void OnShake(object sender, ShakeGestureEventArgs e)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
switch (e.ShakeType)
{
case ShakeType.X:
{
_shakeStatusTextBlock.Text = string.Format("Left and right ({0})", e.ShakeType);
_shakeStatusTextBlock.Foreground = new SolidColorBrush(Colors.Red);
break;
}
case ShakeType.Y:
{
_shakeStatusTextBlock.Text = string.Format("Forward and backwards ({0})", e.ShakeType);
_shakeStatusTextBlock.Foreground = new SolidColorBrush(Colors.Green);
break;
}
case ShakeType.Z:
{
_shakeStatusTextBlock.Text = string.Format("Up and down ({0})", e.ShakeType);
_shakeStatusTextBlock.Foreground = new SolidColorBrush(Colors.Blue);
break;
}
}
ToggleFlash();
});
}
private void ToggleFlash()
{
try
{
IReadOnlyList<object> supportedCameraModes =
AudioVideoCaptureDevice.GetSupportedPropertyValues(_sensorLocation,
KnownCameraAudioVideoProperties.VideoTorchMode);
//ToDo Don't like this line. Simplify....
if (supportedCameraModes.ToList().Contains((UInt32) VideoTorchMode.On))
{
if (!_flashOn)
{
_captureDevice.SetProperty(KnownCameraAudioVideoProperties.VideoTorchMode, VideoTorchMode.On);
_captureDevice.SetProperty(KnownCameraAudioVideoProperties.VideoTorchPower,
AudioVideoCaptureDevice.GetSupportedPropertyRange(_sensorLocation,
KnownCameraAudioVideoProperties
.VideoTorchPower)
.Max);
_contentGrid.Background = new SolidColorBrush(Colors.White);
_flashOn = true;
}
else
{
_captureDevice.SetProperty(KnownCameraAudioVideoProperties.VideoTorchMode, VideoTorchMode.Off);
_contentGrid.Background = null;
_flashOn = false;
}
}
}
catch (Exception ex)
{
_shakeStatusTextBlock.Text = "The flash cannot be controlled on this device.";
}
}
private async Task<AudioVideoCaptureDevice> GetCaptureDevice()
{
AudioVideoCaptureDevice captureDevice =
await
AudioVideoCaptureDevice.OpenAsync(_sensorLocation,
AudioVideoCaptureDevice.GetAvailableCaptureResolutions(_sensorLocation)
.First());
return captureDevice;
}
}
}
和 Xaml...
<phone:PhoneApplicationPage
x:Class="ShakerTorch.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="_layoutRootGrid" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- LOCALIZATION NOTE:
To localize the displayed strings copy their values to appropriately named
keys in the app's neutral language resource file (AppResources.resx) then
replace the hard-coded text value between the attributes' quotation marks
with the binding clause whose path points to that string name.
For example:
Text="{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}"
This binding points to the template's string resource named "ApplicationTitle".
Adding supported languages in the Project Properties tab will create a
new resx file per language that can carry the translated values of your
UI strings. The binding in these examples will cause the value of the
attributes to be drawn from the .resx file that matches the
CurrentUICulture of the app at run time.
-->
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="_titleStackPanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="_titleTextBlock" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
<TextBlock x:Name="_pageNameTextBlock" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="_contentGrid" Grid.Row="1" Margin="12,0,12,0">
<TextBlock x:Name="_shakeStatusTextBlock" Text="Shake me..." FontSize="36" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<!--Uncomment to see an alignment grid to help ensure your controls are
aligned on common boundaries. The image has a top margin of -32px to
account for the System Tray. Set this to 0 (or remove the margin altogether)
if the System Tray is hidden.
Before shipping remove this XAML and the image itself.-->
<!--<Image Source="/Assets/AlignmentGrid.png" VerticalAlignment="Top" Height="800" Width="480" Margin="0,-32,0,0" Grid.Row="0" Grid.RowSpan="2" IsHitTestVisible="False" />-->
</Grid>
</phone:PhoneApplicationPage>