动手实验
实验4:应用栏和媒体捕获
2012年9月
简介
Windows运行时中的Windows.Media.Capture命名空间包含一系列类,它们为捕获媒体并将其纳入Windows应用商店应用提供便利。尤其是CameraCaptureUI类使得从网络摄像头拍照和捕获视频变得轻而易举。CameraCaptureUI甚至可以处理包含两个摄像头的设备(一个前置,一个后置),并为在两者之间进行切换提供简单、直观的用户界面。
在本实验中,您将通过允许用户拍摄他们喜爱的食谱创作的照片和视频并与其他应用程序进行共享来增强Contoso Cookbook的功能。您也将添加应用栏以提供这些功能的快捷方式并学习如何将弹出菜单纳入应用栏命令。
目标
本实验将向您展示如何:
- 在Windows应用商店应用中实现应用栏。
- 向应用栏添加命令和菜单。
- 使用Windows运行时拍摄照片。
- 使用Windows运行时捕获视频。
- 使用共享合约共享照片和视频。
系统要求
您需要下列软件完成本实验:
- Microsoft Windows 8
- Microsoft Visual Studio 2012
设置
您必须执行以下步骤来准备本实验的计算机:
1、安装Microsoft Windows 8。
2、安装Microsoft Visual Studio 2012。
练习
本动手实验包含以下练习:
1、添加应用栏
2、添加照片捕获
3、添加视频捕获
完成本实验的预计时间:30至40分钟。
练习1:添加应用栏
在我们添加允许Contoso Cookbook用户捕获和共享照片及视频的功能前,我们需要对用户界面进行修改以提供对上述功能的访问。应用栏是完成这项工作的完美的工具。
任务1 – 安装Callisto
在我们添加应用栏之前,我们需要安装Callisto控件套件。Callisto是一个由Tim Heuer领导的社区项目,它包含针对Windows应用商店应用的有用的控件,这些控件使用XAML,包括一个菜单控件和一个弹出窗口控件。我们将在接下来的任务中使用这些控件。
1、在Visual Studio中打开您在实验3中完成的ContosoCookbook项目。如果您尚未完成实验3或希望从一个参考副本开始,您可以在开始材料中找到实验已完成的版本。
2、访问http://visualstudiogallery.msdn.microsoft.com/0526563b-7a48-4b17-a087-a35cea701052并单击Download按钮以下载Callisto.vsix。
3、运行Callisto.vsix并按照屏幕上的说明完成库的安装。
4、返回Visual Studio。在解决方案管理器中,右键单击References并使用Add Reference命令在项目中添加对Callisto的引用。您将在Windows Extensions下找到它。
任务2 – 在项-明细页面添加应用栏
现在我们准备在项-明细页面添加应用栏。我们将为照片和视频捕获在应用栏中增加一个Brag按钮,我们将使用弹出菜单让用户在二者之间进行选择。
1、打开ItemDetailPage.xaml并向<Page.Resources>部分添加以下语句。
XAML
<Style x:Key="BragAppBarButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}"> <Setter Property="AutomationProperties.AutomationId" Value="BragAppBarButton"/> <Setter Property="AutomationProperties.Name" Value="Brag"/> <Setter Property="Content" Value=""/> </Style>
2、在<Page.Resources>部分之后添加以下语句。
XAML
<Page.BottomAppBar> <AppBar x:Name="PageAppBar" Padding="10,0,10,0"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="50*"/> <ColumnDefinition Width="50*"/> </Grid.ColumnDefinitions> <StackPanel x:Name="LeftCommands" Orientation="Horizontal" Grid.Column="0" HorizontalAlignment="Left"> <Button x:Name="BragButton" HorizontalAlignment="Left" Style="{StaticResource BragAppBarButtonStyle}" Click="OnBragButtonClicked" /> </StackPanel> <StackPanel x:Name="RightCommands" Orientation="Horizontal" Grid.Column="1" HorizontalAlignment="Right"> </StackPanel> </Grid> </AppBar> </Page.BottomAppBar>
注意:在应用栏中声明的按钮(或称为“命令”)从您在之前步骤中声明的BragAppBarButtonStyle样式获得外观。StandardStyles.xaml由Visual Studio在项目的Common文件夹中创建,它包含为大约30个不同类型的应用栏命令预定义的样式。如果您检查这些样式,您将会发现命令表面的符号用xE10F等十六进制值指定。这些符号是Segoe UI Symbol字符集中的字符代码。如果想为您的命令找到炫酷的图标,启动Windows 8字符映射表应用程序,在字体列表下拉框中选择Segoe UI Symbol并滚动至底部。您将会立刻找到这些图标!
3、打开ItemDetailPage.xaml.cs并添加以下using语句。
C#
using Callisto.Controls; using Windows.ApplicationModel.DataTransfer;
4、现在向ItemDetailPage类添加以下方法。
C#
private void OnBragButtonClicked(object sender, RoutedEventArgs e) { // Create a menu containing two items var menu = new Menu(); var item1 = new MenuItem { Text = "Photo" }; item1.Tapped += OnCapturePhoto; menu.Items.Add(item1); var item2 = new MenuItem { Text = "Video" }; item2.Tapped += OnCaptureVideo; menu.Items.Add(item2); // Show the menu in a Flyout anchored to the Brag button var flyout = new Flyout(); flyout.Placement = PlacementMode.Top; flyout.HorizontalAlignment = HorizontalAlignment.Left; flyout.HorizontalContentAlignment = HorizontalAlignment.Left; flyout.PlacementTarget = BragButton; flyout.Content = menu; flyout.IsOpen = true; } private void OnCapturePhoto (object sender, TappedRoutedEventArgs e) { DataTransferManager.ShowShareUI(); } private void OnCaptureVideo(object sender, TappedRoutedEventArgs e) { DataTransferManager.ShowShareUI(); }
注意:DataTransfer.DataTransferManager.ShowShareUI方法显示共享用户界面,该用户界面与您在超级按钮中选择共享超级按钮时出现的界面相同。您为Photo和Video命令引出了事件处理程序以显示共享用户界面。
任务3 – 测试结果
让我们查看应用栏的运行情况。
1、按F5运行应用程序。
2、点击某个食谱并转到项-明细页面。
3、通过从屏幕底部向上轻扫,用鼠标右键单击或按Windows徽标键+Z以显示应用栏。
4、验证应用栏包含Brag命令,点击它将显示弹出菜单,如图1所示。
图1 项-明细页面的应用栏
5、在菜单中点击Photo命令并验证共享窗格将会出现。
6、返回Visual Studio并停止调试。
练习2:添加照片捕获
拍照的用户界面已经就位。现在让我们修改代码以允许用户拍摄照片并与其他应用程序进行共享。Windows运行时的Windows.Media.Capture命名空间包含名称为CameraCaptureUI的类,它为摄像头硬件提供了一个高层次的接口。它使得与摄像头的交互变得非常简单。
任务1 – 使用CameraCaptureUI捕获图片
CameraCaptureUI包含CaptureFileAsync方法,它能够迅速完成拍照的工作。让我们在Contoso Cookbook中使用它。目前您位于项-明细页面,让我们修改页面中的共享代码使其能够共享捕获的照片和食谱。
1、打开ItemDetailPage.xaml.cs并在文件顶部添加以下using语句。
C#
using Windows.Media.Capture; using Windows.Storage;
2、向ItemDetailPage类添加以下字段。
C#
private StorageFile _photo; // Photo file to share
3、找到您在之前练习中添加的OnCapturePhoto方法。
4、修改后的方法如下所示。请务必在第一行添加async关键字,这是必须的,因为我们在方法中使用了C# 的await关键字。
C#
private async void OnCapturePhoto(object sender, TappedRoutedEventArgs e) { var camera = new CameraCaptureUI(); var file = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo); if (file != null) { _photo = file; DataTransferManager.ShowShareUI(); } }
5、用以下方法替换在之前实验中向ItemDetailPage.xaml.cs添加的OnDataRequested方法。
C#
void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args) { var request = args.Request; var item = (RecipeDataItem)this.flipView.SelectedItem; request.Data.Properties.Title = item.Title; if (_photo != null) { request.Data.Properties.Description = "Recipe photo"; var reference = Windows.Storage.Streams.RandomAccessStreamReference.CreateFromFile(_photo); request.Data.Properties.Thumbnail = reference; request.Data.SetBitmap(reference); _photo = null; } else { request.Data.Properties.Description = "Recipe ingredients and directions"; // Share recipe text var recipe = "\r\nINGREDIENTS\r\n"; recipe += String.Join("\r\n", item.Ingredients); recipe += ("\r\n\r\nDIRECTIONS\r\n" + item.Directions); request.Data.SetText(recipe); // Share recipe image var reference = RandomAccessStreamReference.CreateFromUri(new Uri(item.ImagePath.AbsoluteUri)); request.Data.Properties.Thumbnail = reference; request.Data.SetBitmap(reference); } }
6、按F5运行应用程序并点击某个食谱以转到项-明细页面。
7、显示应用栏并点击Brag按钮。然后点击菜单中的Photo。发生了什么?
8、返回Visual Studio并停止调试。
任务2 – 启用网络摄像头访问
Windows应用商店应用必须具有访问网络摄像头的权限。该权限来自应用程序清单,应用程序清单包含应用程序的元数据。因此,下一步将编辑Contoso Cookbook的清单以表明它需要访问摄像头。
1、In Solution Explorer, double-click Package.appxmanifest to open it for editing.
2、在解决方案管理器中双击Package.appxmanifest打开并对其进行编辑。
3、转到功能选项卡并选中Webcam复选框,如图2所示。
图2 在应用程序清单中启用网络摄像头访问
任务3 – 测试结果
现在网络摄像头访问已启用,让我们来捕获照片。
1、按F5运行应用程序并点击某个食谱以转到项-明细页面。
2、显示应用栏并点击Brag按钮。在菜单中选择Photo,如果被问及应用程序是否可以使用网络摄像头,单击Allow。
3、当摄像头捕获界面出现时,点击屏幕以进行拍照。
4、在屏幕右下角点击OK以接收照片。
5、当共享用户界面出现时,选择一个共享目标,例如Share Target Sample 应用程序。
6、确认您刚捕获的照片被共享目标接收。
7、返回Visual Studio并停止调试。
练习3: 添加视频捕获
Contoso Cookbook用户现在可以拍照并与其他应用程序共享照片。在本练习中您也将添加对视频捕获的支持。您将修改传递给CaptureFileAsync的参数以表明您需要捕获视频而不是照片,并使用CameraCaptureUI的VideoSettings属性表明捕获的格式。
任务1 – 使用CameraCaptureUI捕获视频
您可以使用与捕获照片一样的CaptureFileAsync方法捕获视频。让我们修改之前引入的OnCaptureVideo方法以进行演示。
1、打开ItemDetailPage.xaml.cs并向ItemDetailPage类添加以下字段。
C#
private StorageFile _video; // Video file to share
2、找到在练习1中向ItemDetailPage.xaml.cs添加的OnCaptureVideo方法。
3、修改后的方法如下所示。请务必再次在第一行添加async关键字,这是必须的,因为我们在方法中使用了C#的 await关键字。
C#
private async void OnCaptureVideo(object sender, TappedRoutedEventArgs e) { var camera = new CameraCaptureUI(); camera.VideoSettings.Format = CameraCaptureUIVideoFormat.Wmv; var file = await camera.CaptureFileAsync(CameraCaptureUIMode.Video); if (file != null) { _video = file; DataTransferManager.ShowShareUI(); } }
4、在OnDataRequested方法中添加一个else-if子句,因此应用程序可以同时共享视频和照片。
C#
void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args) { var request = args.Request; var item = (RecipeDataItem)this.flipView.SelectedItem; request.Data.Properties.Title = item.Title; if (_photo != null) { request.Data.Properties.Description = "Recipe photo"; var reference = Windows.Storage.Streams.RandomAccessStreamReference.CreateFromFile(_photo); request.Data.Properties.Thumbnail = reference; request.Data.SetBitmap(reference); _photo = null; } else if (_video != null) { request.Data.Properties.Description = "Recipe video"; List<StorageFile> items = new List<StorageFile>(); items.Add(_video); request.Data.SetStorageItems(items); _video = null; } else { request.Data.Properties.Description = "Recipe ingredients and directions"; // Share recipe text var recipe = "\r\nINGREDIENTS\r\n"; recipe += String.Join("\r\n", item.Ingredients); recipe += ("\r\n\r\nDIRECTIONS\r\n" + item.Directions); request.Data.SetText(recipe); // Share recipe image var reference = RandomAccessStreamReference.CreateFromUri(new Uri(item.ImagePath.AbsoluteUri)); request.Data.Properties.Thumbnail = reference; request.Data.SetBitmap(reference); } }
5、转到应用程序清单的功能部分并选择Microphone复选框。这是必要的,因为当您使用摄像头捕获视频时,CameraCaptureUI也需要使用麦克风。
任务2 – 测试结果
现在让我们测试您刚增加的代码。
1、按F5运行应用程序并点击某个食谱以转到项-明细页面。
2、显示应用栏,点击Brag按钮并从菜单中选择Video。
3、如果被问及应用程序是否可以使用网络摄像头和麦克风,单击Allow。
4、当摄像头捕获界面出现时,点击屏幕以开始捕获视频。
5、几秒钟后再次点击屏幕以停止捕获视频。
6、在屏幕右下角点击OK以接收视频。
7、当共享用户界面出现时,选择一个共享目标,例如Share Target Sample 应用程序。
8、确认您刚捕获的视频被共享目标接收。
9、返回Visual Studio并停止调试。
总结
在一些平台上,在应用程序中包含照片和视频捕获功能很困难,因为需要在设备层与摄像头交互。Windows运行时通过在CameraCaptureUI类中提供核心用户界面和逻辑,使媒体捕获变得异常简单。在Contoso Cookbook中,我们对图像和视频文件除了进行共享外没有做任何其他事情。然而您可以方便地使用Windows.Storage命名空间的类型将这些文件保存到文件系统并允许用户创建食谱图片和视频库。
您也许并未注意到,当您在清单中选中Webcam 和 Microphone复选框时,操作系统已为您做了很酷的工作。如果您运行该应用程序,然后选择设置超级按钮并选择权限(Permissions),您将会发现权限页面现在包含一个启用和禁用摄像头和麦克风的切换开关。用户可以禁用应用中的摄像头和麦克风,并且您不需要为此编写一行代码。