zoukankan      html  css  js  c++  java
  • 与众不同 windows phone (38)

    [源码下载]


    与众不同 windows phone (38) - 8.0 关联启动: 使用外部程序打开一个文件或URI, 关联指定的文件类型或协议



    作者:webabcd


    介绍
    与众不同 windows phone 8.0 之 关联启动

    • 使用外部程序打开一个文件
    • 使用外部程序打开一个 Uri
    • 关联指定的文件类型
    • 关联指定的协议



    示例
    1、演示如何使用外部程序打开一个文件
    AssociationLaunching/LaunchFile.xaml

    <phone:PhoneApplicationPage
        x:Class="Demo.AssociationLaunching.LaunchFile"
        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"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d"
        shell:SystemTray.IsVisible="True">
    
        <Grid Background="Transparent">
            <StackPanel>
                
                <TextBlock Name="lblMsg" Margin="0 0 0 10" />
    
                <Button Content="打开一个 .log 文件" Name="btnLaunchFile" Click="btnLaunchFile_Click" />
                
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>

    AssociationLaunching/LaunchFile.xaml.cs

    /*
     * 演示如何使用外部程序打开一个文件
     */
    
    using System;
    using System.Windows;
    using Microsoft.Phone.Controls;
    using Windows.Storage;
    using System.IO;
    using System.Text;
    
    namespace Demo.AssociationLaunching
    {
        public partial class LaunchFile : PhoneApplicationPage
        {
            public LaunchFile()
            {
                InitializeComponent();
            }
    
            private async void btnLaunchFile_Click(object sender, RoutedEventArgs e)
            {
                // 在 ApplicationData 的根目录下写一个 myLog.log 文件
                StorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
                StorageFile storageFile = await applicationFolder.CreateFileAsync("myLog.log", CreationCollisionOption.ReplaceExisting);
                using (Stream stream = await storageFile.OpenStreamForWriteAsync())
                {
                    byte[] content = Encoding.UTF8.GetBytes("hello webabcd");
                    await stream.WriteAsync(content, 0, content.Length);
                }
    
                // 启动与 .log 类型文件关联的默认应用程序,来打开指定的文件
                Windows.System.Launcher.LaunchFileAsync(storageFile);
            }
        }
    }


    2、演示如何使用外部程序打开一个 Uri(自定义协议)
    AssociationLaunching/LaunchUri.xaml

    <phone:PhoneApplicationPage
        x:Class="Demo.AssociationLaunching.LaunchUri"
        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"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d"
        shell:SystemTray.IsVisible="True">
    
        <Grid Background="Transparent">
            <StackPanel>
    
                <TextBlock Name="lblMsg" Margin="0 0 0 10" />
    
                <Button Content="启动一个协议名为 webabcd 的 uri" Name="btnLaunchUri" Click="btnLaunchUri_Click" />
    
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>

    AssociationLaunching/LaunchUri.xaml.cs

    /*
     * 演示如何使用外部程序打开一个 Uri(自定义协议)
     */
    
    using System.Windows;
    using Microsoft.Phone.Controls;
    using Windows.Networking.Proximity;
    
    namespace Demo.AssociationLaunching
    {
        public partial class LaunchUri : PhoneApplicationPage
        {
            public LaunchUri()
            {
                InitializeComponent();
            }
    
            private void btnLaunchUri_Click(object sender, RoutedEventArgs e)
            {
                // 使用外部程序打开指定的 Uri(自定义协议,注意这里没有“//”)
                Windows.System.Launcher.LaunchUriAsync(new System.Uri("webabcd:hello webabcd"));
    
    
    
                // nfc 方式启用另一台 wp nfc 设备打开指定的 Uri(需要在 manifest 中声明 ID_CAP_NETWORKING 和 ID_CAP_PROXIMITY)
                ProximityDevice nfcDevice = ProximityDevice.GetDefault();
                if (nfcDevice != null)
                {
                    long Id = nfcDevice.PublishUriMessage(new System.Uri("webabcd:hello webabcd"));
                }
            }
        }
    }


    3、演示如何关联指定的文件类型(即用本程序打开指定类型的文件)
    AssociationLaunching/FileTypeAssociation.xaml

    <phone:PhoneApplicationPage
        x:Class="Demo.AssociationLaunching.FileTypeAssociation"
        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"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d"
        shell:SystemTray.IsVisible="True">
    
        <Grid Background="Transparent">
            <StackPanel>
                
                <TextBlock Name="lblMsg" TextWrapping="Wrap" />
                
                <TextBlock TextWrapping="Wrap" Margin="0 10 0 0">
                    <Run>本程序可以打开 .log 类型的文件</Run>
                    <LineBreak />
                    <Run>测试方法:通过 LaunchFile.xaml 打开一个 .log 类型的文件</Run>
                </TextBlock>
                
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>

    AssociationLaunching/FileTypeAssociation.xaml.cs

    /*
     * 演示如何关联指定的文件类型(即用本程序打开指定类型的文件)
     * 
     * 
     * 由于配置为 NavUriFragment="fileToken=%s",所以本 app 打开某类型的文件会通过 /FileTypeAssociation?fileToken=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 启动
     * 相关的 UriMapper 参见 MyUriMapper.cs
     * 
     * 
     * 注:
     * 需要在 manifest 中增加类似如下的配置
     *  <Extensions>
          <!--
              NavUriFragment="fileToken=%s" 的意思是:
              1、某 app 启动外部程序打开 .xxx 文件时会传递文件的 token
              2、如果最终是由本 app 打开 .xxx 文件,则本 app 会通过 /FileTypeAssociation?fileToken=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 启动
          -->
          <FileTypeAssociation TaskID="_default" Name="myFileTypeAssociation" NavUriFragment="fileToken=%s">
            <Logos>
              <!--相关类型的文件显示在电子邮件附件中的图标,33x33 像素,其会显示在白色的背景前-->
              <Logo Size="small" IsRelative="true">Assets/AppIcon_33x33.png</Logo>
              <!--相关类型的文件显示在 Office 中心列表视图中的图标,69x69 像素,其会显示在白色的背景前-->
              <Logo Size="medium" IsRelative="true">Assets/AppIcon_69x69.png</Logo>
              <!--相关类型的文件显示在浏览器下载中的图标,176x176 像素,其会显示在白色的背景前-->
              <Logo Size="large" IsRelative="true">Assets/AppIcon_176x176.png</Logo>
            </Logos>
            <SupportedFileTypes>
              <!--关联的文件类型列表-->
              <FileType ContentType="text/plain">.log</FileType>
              <FileType ContentType="application/rar">.rar</FileType>
            </SupportedFileTypes>
          </FileTypeAssociation>
        </Extensions>
     */
    
    using System;
    using System.Collections.Generic;
    using System.Windows.Navigation;
    using Microsoft.Phone.Controls;
    using Windows.Phone.Storage.SharedAccess;
    using Windows.Storage;
    using Windows.Storage.Streams;
    using System.IO;
    using System.Text;
    
    namespace Demo.AssociationLaunching
    {
        public partial class FileTypeAssociation : PhoneApplicationPage
        {
            public FileTypeAssociation()
            {
                InitializeComponent();
            }
    
            protected async override void OnNavigatedTo(NavigationEventArgs e)
            {
                IDictionary<string, string> queryStrings = this.NavigationContext.QueryString;
    
                if (queryStrings.ContainsKey("fileToken"))
                {
                    // 获取需要打开的文件的 token
                    string fileToken = queryStrings["fileToken"];
                    // 保存需要打开的文件到本 app 的 ApplicationData
                    await SharedStorageAccessManager.CopySharedFileAsync(ApplicationData.Current.LocalFolder, "myLog2.log", NameCollisionOption.ReplaceExisting, fileToken);
                    // 获取文件的文件名称
                    string fileName = SharedStorageAccessManager.GetSharedFileName(fileToken);
    
                    lblMsg.Text = "fileName: " + fileName;
                    lblMsg.Text += Environment.NewLine;
    
                    // 获取 ApplicationData 中指定的文件
                    StorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
                    StorageFile storageFile = await applicationFolder.GetFileAsync("myLog2.log");
    
                    // 显示文件内容
                    IRandomAccessStreamWithContentType accessStream = await storageFile.OpenReadAsync();
                    using (Stream stream = accessStream.AsStreamForRead((int)accessStream.Size))
                    {
                        byte[] content = new byte[stream.Length];
                        await stream.ReadAsync(content, 0, (int)stream.Length);
    
                        lblMsg.Text += Encoding.UTF8.GetString(content, 0, content.Length);
                    }
                }
    
                base.OnNavigatedTo(e);
            }
        }
    }


    4、演示如何关联指定的协议(即用本程序处理指定的协议)
    AssociationLaunching/ProtocolAssociation.xaml

    <phone:PhoneApplicationPage
        x:Class="Demo.AssociationLaunching.ProtocolAssociation"
        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"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d"
        shell:SystemTray.IsVisible="True">
    
        <Grid Background="Transparent">
            <StackPanel>
    
                <TextBlock Name="lblMsg" TextWrapping="Wrap" />
    
                <TextBlock TextWrapping="Wrap" Margin="0 10 0 0">
                    <Run>本程序可以处理 webabcd 协议</Run>
                    <LineBreak />
                    <Run>测试方法:通过 LaunchUri 打开一个名为 webabcd 的协议</Run>
                </TextBlock>
                
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>

    AssociationLaunching/ProtocolAssociation.xaml.cs

    /*
     * 演示如何关联指定的协议(即用本程序处理指定的协议)
     * 
     * 
     * 由于配置为 NavUriFragment="encodedLaunchUri=%s",所以本 app 打开某协议会通过 /Protocol?encodedLaunchUri=webabcd:xxxxxxxxxx 启动
     * 相关的 UriMapper 参见 MyUriMapper.cs
     * 
     * 
     * 注:
     * 需要在 manifest 中增加类似如下的配置
     *  <Extensions>
          <!--
              Name 是协议名称,对于本例来说协议的示例为“webabcd:hello webabcd”,注意其没有“//”
          -->
          <Protocol TaskID="_default" Name="webabcd" NavUriFragment="encodedLaunchUri=%s" />
        </Extensions>
     */
    
    using System.Collections.Generic;
    using System.Windows.Navigation;
    using Microsoft.Phone.Controls;
    
    namespace Demo.AssociationLaunching
    {
        public partial class ProtocolAssociation : PhoneApplicationPage
        {
            public ProtocolAssociation()
            {
                InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                // 显示协议的详细信息
                IDictionary<string, string> queryStrings = this.NavigationContext.QueryString;
                if (queryStrings.ContainsKey("protocol"))
                {
                    lblMsg.Text = queryStrings["protocol"];
                }
    
                base.OnNavigatedTo(e);
            }
        }
    }


    自定义 UriMapper,用于处理当本 app 由文件打开或协议打开或镜头扩展打开或图片扩展打开时,导航到相关的处理页面
    MyUriMapper.cs

    /*
     * 自定义 UriMapper,用于处理当本 app 由文件打开或协议打开或镜头扩展打开或图片扩展打开时,导航到相关的处理页面
     * 
     * 注:
     * 要使此 UriMapper 有效,需要在 App.xaml.cs 中增加 RootFrame.UriMapper = new Demo.MyUriMapper();
     */
    
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Windows.Navigation;
    using Windows.Phone.Storage.SharedAccess;
    
    namespace Demo
    {
        public class MyUriMapper : UriMapperBase
        {
            public override Uri MapUri(Uri uri)
            {
                string tempUrl = HttpUtility.UrlDecode(uri.ToString());
    
                // 由文件启动本 app 时会通过 /FileTypeAssociation?fileToken=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 启动
                if (tempUrl.StartsWith("/FileTypeAssociation"))
                {
                    // 获取 fileToken
                    int fileTokenIndex = tempUrl.IndexOf("fileToken=") + 10;
                    string fileToken = tempUrl.Substring(fileTokenIndex);
    
                    // 获取相关的文件名
                    string fileName = SharedStorageAccessManager.GetSharedFileName(fileToken); // myLog.log
    
                    // 获取相关的文件名的扩展名
                    string fileType = Path.GetExtension(fileName);
    
                    // 根据文件类型的不同导航到不同的处理页面
                    switch (fileType)
                    {
                        case ".log":
                            return new Uri("/AssociationLaunching/FileTypeAssociation.xaml?fileToken=" + fileToken, UriKind.Relative);
                        default:
                            return new Uri("/MainPage.xaml", UriKind.Relative);
                    }
                }
                // 由协议启动本 app 时会通过 /Protocol?encodedLaunchUri=webabcd:xxxxxxxxxx 启动
                else if (tempUrl.StartsWith("/Protocol"))
                {
                    // 获取协议的详细信息
                    int protocolIndex = tempUrl.IndexOf("encodedLaunchUri=") + 17;
                    string protocol = tempUrl.Substring(protocolIndex);
    
                    // 导航到处理 webabcd 协议的处理页面
                    return new Uri("/AssociationLaunching/ProtocolAssociation.xaml?protocol=" + protocol, UriKind.Relative);
                }
                // 由镜头扩展启动本 app 时会通过 /MainPage.xaml?Action=ViewfinderLaunch 启动
                else if (tempUrl.Contains("Action=ViewfinderLaunch"))
                {
                    return new Uri("/CameraAndPhoto/LensExtensibility.xaml?fromLens=true", UriKind.Relative);
                }
                // 由图片扩展之“共享...”启动本 app 时会通过 /MainPage.xaml?Action=ShareContent&FileId={xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} 启动
                else if (tempUrl.Contains("Action=ShareContent"))
                {
                    string fileId = tempUrl.Substring(tempUrl.IndexOf("FileId=") + 7).Replace("{", "").Replace("}", "");
                    return new Uri("/CameraAndPhoto/PhotoExtensibility.xaml?type=share&token=" + fileId, UriKind.Relative);
                }
                // 由图片扩展之“编辑...”启动本 app 时会通过 /MainPage.xaml?Action=EditPhotoContent&FileId={xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} 启动
                else if (tempUrl.Contains("Action=EditPhotoContent"))
                {
                    string fileId = tempUrl.Substring(tempUrl.IndexOf("FileId=") + 7).Replace("{", "").Replace("}", "");
                    return new Uri("/CameraAndPhoto/PhotoExtensibility.xaml?type=edit&token=" + fileId, UriKind.Relative);
                }
                // 由图片扩展之“自动上传”启动本 app 时会通过 /MainPage.xaml?Action=ConfigurePhotosUploadSettings 启动
                else if (tempUrl.Contains("Action=ConfigurePhotosUploadSettings"))
                {
                    return new Uri("/CameraAndPhoto/PhotoAutoUpload.xaml?fromConfig=true", UriKind.Relative);
                }
                // 在锁屏设置界面,如果将本 app 设置为背景提供程序,则锁屏界面上会有一个名为“打开应用”的按钮,点击后会通过 /MainPage.xaml?WallpaperSettings=1 启动本 app
                else if (tempUrl.Contains("WallpaperSettings=1"))
                {
                    return new Uri("/Others/LockScreen.xaml?WallpaperSettings=1", UriKind.Relative);
                }
    
                return uri;
            }
        }
    }

    将此 app 的 UriMapper 设置为我们自定义的 UriMapper
    App.xaml.cs

    private void InitializePhoneApplication()
    {
        // 设置本 app 的 UriMapper
        RootFrame.UriMapper = new Demo.MyUriMapper();
    }



    OK
    [源码下载]

  • 相关阅读:
    Ext.FormPanel-----FieldSet的用法
    DAO层,Service层,Controller层、View层
    PageProxy分页的实现
    Layout布局(补充)
    Ext--Layout(布局)
    DirectEvents用法
    Linq的使用
    字符串注入攻击
    winform(C#)里弹出“确定”“取消”对话框
    C#的数组
  • 原文地址:https://www.cnblogs.com/webabcd/p/3464613.html
Copyright © 2011-2022 走看看