| 
 | 
	
 
 
  Windows phone 8 的应用除了可以直接从开始菜单以及应用列表中打开外,还可以通过其他的方式打开。照片中心、音乐+视频中心提供扩展支持应用从此启动。另外,我们还可以通过文件关联、URI关联的方式启动应用。 
  快速导航: 
    一、扩展音乐+视频中心 
    二、扩展照片中心 
    三、文件关联以及SD卡访问 
    四、URI关联 
    五、启动我的其他应用和启动内置应用 
 
一、扩展音乐+视频中心 
 
1)在音乐+视频中心启动应用 
  扩展音乐+视频中心第一步就是要保证应用可以从音乐+视频中心启动,我们需要手工修改 Windows Phone 的应用清单文件,在WMAppManifest.xml文件上右键,选择打开方式,用XML文本编辑器打开,我们需要设置App 节点下 HubType 值为1,代码如下: 
 
 
[XML]  
 
 
 
...... 
 
 
2)更新历史记录、最新上市列表 
  应用集成到音乐+视频中心后,我们可以更新音乐+视频中心的历史记录列表、历史记录正在播放图块、最新上市列表等,下面代码描述了更新的方式。 
 
 
[C#] 
 
 
        //根据song构建MediaHistoryItem(媒体项目信息) 
private MediaHistoryItem getMediaHistoryItem(Song song) 
{ 
MediaHistoryItem mediaHistoryItem = new MediaHistoryItem(); 
//当前歌曲专辑的缩略图 
mediaHistoryItem.ImageStream = song.Album.GetThumbnail(); 
mediaHistoryItem.Source = string.Empty; 
//音乐名,会显示在缩略图上 
mediaHistoryItem.Title = song.Name; 
mediaHistoryItem.PlayerContext.Add("KeySring", song.Name); 
return mediaHistoryItem; 
} 
//更新历史记录列表中的正在播放 
private void updatePlaying(Song song) 
{ 
MediaHistory.Instance.NowPlaying = getMediaHistoryItem(song); 
} 
//更新历史记录列表 
private void updateHistoryList(Song song) 
{ 
MediaHistory.Instance.WriteRecentPlay(getMediaHistoryItem(song)); 
} 
//更新最新上市列表 
private void updateNewList(Song song) 
{ 
MediaHistory.Instance.WriteAcquiredItem(getMediaHistoryItem(song)); 
} 
 
  我们除了可以对媒体库的音乐进行更新历史记录和最新上市列表外,也可以自定义其他音乐。这样非媒体库的的音乐也可以更新。但是可能会存在一些问题。下面代码演示了把安装文件夹的音乐播放出来,并更新正在播放列表。 
 
[C#] 
 
 
//从安装文件夹读取专辑缩略图 
StreamResourceInfo jpgStreamResourceInfo = Application.GetResourceStream(new Uri("myImg.jpg", UriKind.Relative)); 
MediaHistoryItem mediaHistoryItem = new MediaHistoryItem(); 
//当前歌曲专辑的缩略图 
mediaHistoryItem.ImageStream = jpgStreamResourceInfo.Stream; 
mediaHistoryItem.Source = string.Empty; 
//音乐名,会显示在缩略图上 
mediaHistoryItem.Title = "我的音乐"; 
mediaHistoryItem.PlayerContext.Add("KeySring", "我的音乐"); 
//准备播放 
mediaElement1.Source = new Uri("1.mp3", UriKind.Relative); 
mediaElement1.Play(); 
//更新音乐视频中心的正在播放,非媒体库音乐貌似要重启手机才可以看到效果,不知道是不是BUG。 
MediaHistory.Instance.NowPlaying = mediaHistoryItem; 
 
3)从历史记录和最新上市启动时的播放处理 
  当用户在音乐+视频中心点击对应项目时,则会自动启动我们的应用,这个时候我们需要进行一些处理,来确定播放哪一个音乐。我们这里的处理逻辑仅仅考虑媒体库中存在的音乐。 
 
[C#] 
 
 
 protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) 
{ 
//从音乐视频中心启动时,播放相应项。 
MediaLibrary library = new MediaLibrary(); 
Song _playingSong = null; 
if (NavigationContext.QueryString.ContainsKey("KeySring")) 
{ 
String songToPlay = NavigationContext.QueryString["KeySring"]; 
foreach (Song song in library.Songs) 
{ 
if (songToPlay == song.Name) 
{ 
_playingSong = song; 
break; 
} 
} 
if (_playingSong != null) 
MediaPlayer.Play(_playingSong); 
} 
base.OnNavigatedTo(e); 
} 
 
   
 
二、扩展照片中心 
  某些时候,用户可能希望直接从照片中心启动与照片处理相关的应用,或者在浏览照片时随手美化渲染照片,或者共享上传到网络、发送到其他应用,这个时候,我们就需要对照片中心进行扩展,扩展之后我们的应用就可以在这里直接启动。 
 
1)相关扩展点介绍 
  1.照片中心:扩展之后用户可以直接在照片中心启动您的应用。如下图: 
 
 
  2.扩展共享选取器:可以从“共享”链接启动应用,并提供将用户的照片共享到其他位置、网络,或者电子邮件。效果如下图: 
 
     
 
 
  3.扩展照片编辑选取器:可以从“编辑”链接启动应用并允许用户编辑他们的照片,如果没有应用扩展此处,则打开内置照片编辑,否则弹出选择页面。效果如下图: 
 
 
  4.扩展富媒体应用:可如果照片是用当前应用保存或者修改后的,则照片会显示特殊的打开链接,富媒体并不是指对照片本身编辑,而是包含图片文字说明等,以及用于网络交互等富编辑,比如微博应用。效果如下图: 
 
    
 
 
  5.扩展照片应用选取器:这个扩展仅仅在WP7中被支持,以后版本已经弃用。相当于WP8中的编辑以及富编辑。 
 
2)扩展照片中心 
  扩展照片中心需要编辑清单文件,右键点击WMAppManfiest.xml 文件,选择打开方式,在弹出窗口中选择XML文本编辑器打开。在 Tokens 元素之后,在 Extensions 元素内添加如下代码: 
 
[XML] 
 
 
     
 
 
 
 
3)扩展照片查看器 
  上面已经介绍过了图片查看器的相关扩展点,下面我们通过代码演示如何实现这些扩展。首先,每个扩展点都需要清单文件的支持,下面我们需要在同样的位置添加 Extensions项。代码如下: 
 
[XML] 
 
 
     
 
 
 
 
 
 
 
 
 
 
 
    在清单文件支持这些扩展之后,当用户通过扩展启动应用,照片中心默认启动我们应用的MainPage.xaml,同时通过URI参数告诉我们是哪张图片,该做什么处理。下面我们通过在MainPage.xaml中解析URI参数来实现接受相关处理参数信息。如果您的应用有专门的页面处理,则需要实现URI映射,URI映射请看这里。 
[XAML] 
 
 
         
 
 
 
 
 
 
[C#] 
 
 
        Picture selectedPicture; 
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) 
{ 
IDictionary queryStrings = this.NavigationContext.QueryString; 
if (!queryStrings.ContainsKey("Action")) 
{ 
textBlock1.Text = "无来源"; 
} 
else 
{ 
string action = queryStrings["Action"]; 
switch (action) 
{ 
case "ShareContent": textBlock1.Text = "共享选取器"; 
break; 
case "RichMediaEdit": textBlock1.Text = "富媒体应用"; 
break; 
case "EditPhotoContent": textBlock1.Text = "照片编辑选取器"; 
break; 
} 
MediaLibrary library = new MediaLibrary(); 
if (queryStrings.ContainsKey("FileId")) selectedPicture = library.GetPictureFromToken(queryStrings["FileId"]); 
else if (queryStrings.ContainsKey("token")) selectedPicture = library.GetPictureFromToken(queryStrings["token"]); 
else return; 
BitmapImage bitmapFromPhoto = new BitmapImage(); 
bitmapFromPhoto.SetSource(selectedPicture.GetImage()); 
image1.Source = bitmapFromPhoto; 
} 
base.OnNavigatedTo(e); 
} 
//保存图片 
private void Button_Click_1(object sender, RoutedEventArgs e) 
{ 
MediaLibrary library = new MediaLibrary(); 
library.SavePicture(selectedPicture.Name, selectedPicture.GetImage()); 
} 
 
4)扩展方式总结 
  上面我们发现通过照片查看器启动的URI中都有一个Action参数,还有一个参数要么是FileId,要么是token。下面列表归纳一下: 
 
| 扩展点 | 清单文件中的扩展名称 | URI启动关联地址 | 支持的平台 |  | 照片中心 | Photos_Extra_Hub |   | WP7\WP8 |  | 共享选取器 | Photos_Extra_Share | /MainPage.xaml?Action=ShareContent&FileId=[GUID] | WP7\WP8 |  | 富媒体应用 | Photos_Rich_Media_Edit | /MainPage.xaml?Action=RichMediaEdit&token=[GUID] | WP8 |  | 照片编辑选取器 | Photos_Extra_Image_Editor | /MainPage.xaml?Action=EditPhotoContent&FileId=[GUID] | WP8 |  | 照片应用选取器 | Photos_Extra_Viewer | /MainPage.xaml?token=[GUID] | WP7 |      
 
三、文件关联以及SD卡访问 
  文件关联,顾名思义,就类似于Windows系统中注册默认的启动程序一样。我们也可以注册我们的应用为某些后缀名文件的默认启动程序。之前我们讲过,一个应用可访问的存储位置只有安装文件夹、本地文件夹、媒体库这三个位置,但是我们可以通过注册文件关联的方式,只要是关联的文件,就算在其他位置我们也有可能访问的到,这个文件可能来自于SD卡,也可能来自于其他应用。 
 
1. 如何注册文件关联 
  要处理特定的文件类型,请在应用清单文件中注册文件关联。同样我们还是需要右键打开方式,选择Xml文本编辑器的方式打开WMAppManifest.xml文件。必须在Tokens节点后,添加 Extensions 节点,在Extensions中我们定义了关联的文件后缀名,已经文件的大中小型徽标。代码如下: 
 
[XML] 
 
 
     
 
 
 
medium33x33.png 
medium69x69.png 
large176x176.png 
 
 
 
.myfile3 
.myfile2 
 
 
 
 
2. 侦听文件启动 
  当用户通过SD卡或者其他应用打开您所关联的文件类型时,系统将启动您的应用,并发送如下格式的URI: 
    /FileTypeAssociation?fileToken=[GUID]  
 
  但是我们发现这个URI并不能直接关联到我们应用的某个页面,所以现在我们需要定义一个URI映射来处理这个特殊的URL。把它转换成标准URI来引导MainPage.xaml。 
 
注册URI转换: 
  首先,我们需要定义一个UriMapper,实现URI转换的逻辑。新建类文件AssociationUriMapper.cs,输入代码如下: 
 
[C#] 
 
 
 public class AssociationUriMapper : UriMapperBase 
{ 
public override Uri MapUri(Uri uri) 
{ 
string tempUri = System.Net.HttpUtility.UrlDecode(uri.ToString()); 
//验证Uri,是否为文件关联引发 
if (tempUri.StartsWith("/FileTypeAssociation?fileToken=")) 
{ 
string fileToke = tempUri.Substring(31); 
//整理成规范URL,回发到MainPage.xaml 
return new Uri("/MainPage.xaml?fileToke=" + fileToke, UriKind.Relative); 
} 
return uri; 
} 
} 
 
  然后,我们需要在App.cs的InitializePhoneApplication方法中注册我们的URI转换类。添加方式如下图: 
 
 
  下面,我们将要把侦听到的文件识别为文本文件,并显示出来,代码如下: 
 
[C#] 
 
 
protected async override void OnNavigatedTo(NavigationEventArgs e) 
{ 
//获取URI参数 
IDictionary queryStrings = NavigationContext.QueryString; 
if (queryStrings.ContainsKey("fileToke")) 
{ 
var fileToke = queryStrings["fileToke"]; 
//获取文件名 
var fileName = SharedStorageAccessManager.GetSharedFileName(fileToke); 
//本地文件夹 
var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; 
//将文件拷贝到本地文件夹同名文件中 
var file = await SharedStorageAccessManager.CopySharedFileAsync(localFolder, fileName, NameCollisionOption.ReplaceExisting, fileToke); 
var stream = await file.OpenAsync(FileAccessMode.Read); 
StreamReader s = new StreamReader(stream.AsStream(), System.Text.Encoding.Unicode); 
var fileText = s.ReadToEnd(); 
MessageBox.Show("文件名:" + fileName + "\n内容:" + fileText); 
} 
base.OnNavigatedTo(e); 
} 
 
3. 启动关联文件 
  当第三方应用想打开关联文件时,自己本身并不想实现解析文件的逻辑,则可以自动启动我们的应用来打开。 
 
 
[C#] 
 
 
//初始化文件列表 
private async void filesInit() 
{ 
//本地文件夹 
var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; 
var files = await localFolder.GetFilesAsync(); 
listboxFiles.ItemsSource = files.Where(x => x.Name.EndsWith(".myfile1") || x.Name.EndsWith(".myfile2")); 
} 
//打开选择的文件,跳转到关联文件的应用 
private async void Button_Click_2(object sender, RoutedEventArgs e) 
{ 
StorageFile file = listboxFiles.SelectedItem as StorageFile; 
if (file == null) return; 
//启动指定文件关联的应用去打开文件 
Windows.System.Launcher.LaunchFileAsync(file); 
} 
 
  通过图示显示运行的效果: 
 
   
 
 
 
4. 访问SD卡 
  如果在SD卡中有我们关联的文件类型,我们同样可以主动遍历去访问它。实现访问SD卡并读取文件文本类容的代码如下: 
 
[XAML] 
 
 
         
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
[C#] 
 
 
        protected override void OnNavigatedTo(NavigationEventArgs e) 
{ 
filesInit(); 
base.OnNavigatedTo(e); 
} 
//初始化文件列表,只包含可识别文件 
private async void filesInit() 
{ 
//获取插入手机的SD卡集合,一般最多一张SD卡。 
var externalStorageDevices = await ExternalStorage.GetExternalStorageDevicesAsync(); 
//获取集合第一张SD卡 
ExternalStorageDevice sdCard = externalStorageDevices.FirstOrDefault(); 
if (sdCard == null) 
{ 
MessageBox.Show("并没有发现SD卡,请检查SD卡是否插好。"); 
return; 
} 
//获取根目录下全部文件 
var files = await sdCard.RootFolder.GetFilesAsync(); 
listboxFiles.ItemsSource = files.Where(x => x.Name.EndsWith(".myfile1") || x.Name.EndsWith(".myfile2")); 
} 
//打开文件列表选择的文件 
private async void Button_Click_1(object sender, RoutedEventArgs e) 
{ 
ExternalStorageFile file = listboxFiles.SelectedItem as ExternalStorageFile; 
if (file == null) return; 
//读取文件 
var stream = await file.OpenForReadAsync(); 
StreamReader s = new StreamReader(stream, System.Text.Encoding.Unicode); 
var fileText = s.ReadToEnd(); 
MessageBox.Show("文件名:" + file.Name + "\n内容:" + fileText); 
} 
 
   
 
四、URI关联 
  设想这样的应用场景,我们在应用A中,想利用应用B的功能。我们自己不想实现同样的功能是因为B已经做得相当成熟了,没有必要重复实现。比如:我们单击一个电话号码,就想直接打开拨号软件开始拨打电话;单击一个电子邮件,直接打开电子邮件的应用去编写邮件,单击一个视频名,就可以打开视频播放器播放该视频。这个时候,都需要利用URI关联的功能。 
 
1. 注册URI关联 
  URI关联的注册同样也需要编辑清单文件,右键点击WMAppManfiest.xml 文件,选择打开方式,在弹出窗口中选择XML文本编辑器打开。在 Tokens 元素之后,在 Extensions 元素内添加如下代码: 
 
[XML] 
 
 
     
 
 
 
 
  注册好后,第三方应用可以通过如下URI导航到我们的应用: 
  testuri:[参数部分] 
 
2. 侦听URI 
  注册好了URI关联后,系统中其他应用所有前缀为testuri的URI请求都被我们的应用捕获,我们还需要定义一个URI转换来让MainPage.xaml获取。 
 
[C#] 
 
 
    class AssociationUriMapper : UriMapperBase 
{ 
private string tempUri; 
public override Uri MapUri(Uri uri) 
{ 
tempUri = System.Net.HttpUtility.UrlDecode(uri.ToString()); 
//验证Uri,是否为已注册的关联 
if (tempUri.StartsWith("/Protocol?encodedLaunchUri=testuri:")) 
{ 
string uriMsg = tempUri.Substring(35); 
return new Uri("/MainPage.xaml?Msg=" + uriMsg, UriKind.Relative); 
} 
return uri; 
} 
} 
 
  我们还需要在InitializePhoneApplication 方法中注册URI转换 
 
[C#] 
 
 
        /* 在App InitializePhoneApplication 方法中,我们需要注册URI转换 */ 
// 请勿向此方法中添加任何其他代码 
private void InitializePhoneApplication() 
{ 
if (phoneApplicationInitialized) 
return; 
// 创建框架但先不将它设置为 RootVisual;这允许初始 
// 屏幕保持活动状态,直到准备呈现应用程序时。 
RootFrame = new PhoneApplicationFrame(); 
RootFrame.Navigated += CompleteInitializePhoneApplication; 
//我们插入的代码部分!!! 
//注册我们的URI转换 
RootFrame.UriMapper = new AssociationUriMapper(); 
// 处理导航故障 
RootFrame.NavigationFailed += RootFrame_NavigationFailed; 
// 在下一次导航中处理清除 BackStack 的重置请求, 
RootFrame.Navigated += CheckForResetNavigation; 
// 确保我们未再次初始化 
phoneApplicationInitialized = true; 
} 
 
  在MainPage.xaml中处理URI关联请求,代码如下: 
 
[C#] 
 
 
        protected override void OnNavigatedTo(NavigationEventArgs e) 
{ 
IDictionary queryStrings = NavigationContext.QueryString; 
if (queryStrings.ContainsKey("Msg")) MessageBox.Show("来自URI关联调用方信息:\n" + queryStrings["Msg"]); 
base.OnNavigatedTo(e); 
} 
 
3. 启动URI 
  调用方是如何启动这个关联URI呢?代码如下: 
 
[C#] 
 
 
        private async void Button_Click_1(object sender, RoutedEventArgs e) 
{ 
var c = await Windows.System.Launcher.LaunchUriAsync(new System.Uri("testuri:"+textbox1.Text)); 
} 
 
  最后,我们看看演示效果: 
 
   
 
 
   
 
 
 五、启动我的其他应用和启动内置应用 
 
1. 启动我的其他应用 
  我的应用是指发布者ID一样的应用,我们可以在清单文件里面设置这个ID,下面的代码展示了启动我发布的应用列表中第二个应用。 
 
[C#] 
 
 
        //启动我发布的其他应用 
private void Button_Click_1(object sender, RoutedEventArgs e) 
{ 
//查询本机其他与当前应用发行者ID相同的其他应用 
IEnumerable apps = Windows.Phone.Management.Deployment.InstallationManager.FindPackagesForCurrentPublisher(); 
//启动第二个应用 
apps.Skip(1).First().Launch(string.Empty); 
} 
 
2. 启动内置应用 
  内置应用指WP8手机系统本身自带的应用,我们可以通过固定的方式启动它们。下面代码演示了如何使用。 
 
[C#] 
 
 
        //启动内置应用 
private void Button_Click_2(object sender, RoutedEventArgs e) 
{ 
//打开IE访问百度 
//Windows.System.Launcher.LaunchUriAsync(new Uri("http://www.baidu.com")); 
//打开内置邮箱发送邮件 
//Windows.System.Launcher.LaunchUriAsync(new Uri("mailto:username@163.com")); 
//呼叫手机 
//Windows.System.Launcher.LaunchUriAsync(new Uri("tel:13900000000")); 
//启动Wi-Fi 设置 
//Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings-wifi:")); 
//其他的 
//ms-settings-accounts:         启动帐户设置应用。 
//ms-settings-airplanemode:     启动飞行模式设置应用。 
//ms-settings-bluetooth:        启动蓝牙设置应用。 
//ms-settings-cellular:         启动手机网络设置应用。 
//ms-settings-emailandaccounts: 启动电子邮件和帐户设置应用。 
//ms-settings-location:         启动位置设置应用。 
//ms-settings-lock:             启动锁屏设置应用。 
//ms-settings-wifi:             启动 Wi-Fi 设置应用。 
 
//启动 Windows Phone 商店 并显示特定应用的详细信息页面。 
//Windows.System.Launcher.LaunchUriAsync(new Uri("zune:navigate?appid=fdf05477-814e-41d4-86cd-25d5a50ab2d8"));   
//启动 商店 并显示调用应用的查看页面。 
//Windows.System.Launcher.LaunchUriAsync(new Uri("zune:reviewapp")); 
//启动 商店 并显示特定应用的查看页面 
//Windows.System.Launcher.LaunchUriAsync(new Uri("zune:reviewapp?appid=appfdf05477-814e-41d4-86cd-25d5a50ab2d8")); 
//启动 商店 并搜索 
//Windows.System.Launcher.LaunchUriAsync(new Uri("zune:search?keyword=关键字&publisher=发布者名称&contenttype=app")); 
} 
 
   
 
 
作者:[Lipan] 
出处:[http://www.iyunv.com/lipan/] 
版权声明:本文的版权归作者与博客园共有。转载时须注明原文出处以及作者,并保留原文指向型链接,不得更改原文内容。否则作者将保留追究其法律责任。 
 
 
《上一篇:Windows phone 8 学习笔记 通信 
系列目录 
下一篇:Windows phone 8 学习笔记 图块与通知》 |   
 
 
 
 | 
  
 |