天天看點

協定激活(uwp)

為應用程式注冊協定後,可以通過URI來激活目前應用程式,并且還可以在激活應用程式的URI中附加上參數,應用程式在完成激活操作的過程中可以根據URI傳遞的參數來做出相應的處理。

協定URI是以協定名稱開頭,後面緊跟一個英文冒号。冒号後面的内容可以根據實際情況來定義,是可選的。假設某個應用程式注冊了名為"topic"的協定,那麼要激活該應用程式的話,可以使用Launcher類的LaunchUriAsync方法啟動,傳入方法參數的URI為:

topic:
           

帶參數的URI可以這樣寫:

topic:12345
           

冒号後面的所有内容都可以視為附加參數,參數的格式沒有特殊要求,因為當應用程式被激活後,該URI會被傳遞到應用程式中進行處理,是以對URI的分析和處理都可以由開發者自行控制。

在App類中重寫的OnActivated方法中,根據方法參數的Kind屬性的值來判斷應用程式是否由協定URI激活。如果屬性的值為ActivationKind.Protocol,則表明應用程式确實是通過協定相關的URI激活的。

下面将通過示例來示範一下如何為應用程式自定義協定資訊。該示例注冊一個名為"color"的協定,當通過該協定相關的URI激活應用程式後,應用程式會分析URI中所指定的的RGB顔色值,導航到一個應用頁面,頁面中有一個矩形,程式将使用URI傳遞的RGB值來填充該矩形。

App類中重寫的OnActivated方法實作如下,以響應協定激活行為:

protected override void OnActivated(IActivatedEventArgs args)
        {
            base.OnActivated(args);
            if (args.Kind == ActivationKind.Protocol)
            {
                ProtocolActivatedEventArgs protoarg = args as ProtocolActivatedEventArgs;
                //分析URI
                Uri actUri = protoarg.Uri;
                //擷取查詢字元串
                string q = actUri.Query;
                //去掉查詢字元串前面的"?"
                q = q.Replace("?", "");
                //通過正規表達式來查找URI參數中的key -value對
                Regex r = new Regex(@"((?<key>[^&=]+)=(?<value>[^&=]+))+");
                MatchCollection matches = r.Matches(q);
                IDictionary<string, string> dic = new Dictionary<string, string>();
                //将識别出來的各組key-value對存入字典對象中
                foreach (Match match in matches)
                {
                    string _key = match.Groups["key"].Value;
                    string _value = match.Groups["value"].Value;
                    dic.Add(_key,_value);
                }
                //導航到顯示顔色效果的頁面
                Frame rootFrame = Window.Current.Content as Frame;
                if (rootFrame is null)
                {
                    rootFrame = new Frame();
                    Window.Current.Content = rootFrame;
                }
                else
                {
                    //清除後退導航堆棧
                    rootFrame.BackStack.Clear();
                }
                //導航并傳遞參數
                rootFrame.Navigate(typeof(ShowColorPage),dic);
                Window.Current.Activate();
            }
        }
           

由args.Kind屬性确認應用程式的激活行為是通過協定URI完成的,之後需要将方法參數轉換為ProtocolActivatedEventArgs,ProtocolActivatedEventArgs類公開了一個Uri屬性,激活應用程式所使用的的URI被傳遞到該屬性中。

本例中使用的協定URI的格式如下:

color:?r=100&g=50&b=70
           

之是以在參數前面加上一個"?“符号,是為了讓Uri類的Query屬性能夠分析出查詢字元串,URI的查詢字元串一般都是以”?"開頭的,如http://abc.com/?cid=200。

但是,在處理URI的參數時要把“?”去掉,這樣一來,随後的正規表達式就可以正确地比對出r=100,g=50,b=70這三段字元了,即:

//去掉查詢字元串前面的"?"
                q = q.Replace("?", "");
                //通過正規表達式來查找URI參數中的key -value對
                Regex r = new Regex(@"((?<key>[^&=]+)=(?<value>[^&=]+))+");
                MatchCollection matches = r.Matches(q);
           

當正規表達式比對完成後,将分析出來的字元串添加到一個字典對象中。

//将識别出來的各組key-value對存入字典對象中
                foreach (Match match in matches)
                {
                    string _key = match.Groups["key"].Value;
                    string _value = match.Groups["value"].Value;
                    dic.Add(_key,_value);
                }
           

由于指定的正規表達式中命名了兩個組:key和value,當比對=成功後,每一段字元串中名為key的分組中的值為"r",value分組的值則為100。最終字典對象中的内容為:

r:100
g:50
b:70
           

分析完成後,會導航到ShowColorPage頁面,并把該字典對象作為導航參數傳遞。接下來需要完成ShowColorPage頁面。其XAML如下:

<Grid>
        <Rectangle Width="200" Height="250">
            <Rectangle.Fill>
                <SolidColorBrush x:Name="sldBrush"/>
            </Rectangle.Fill>
        </Rectangle>
    </Grid>
           

背景代碼中,重寫OnNavigatedTo方法,如下:

protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            IDictionary<string, string> dic = e.Parameter as Dictionary<string, string>;
            if (dic != null)
            {
                //讀出各個顔色通道的值
                byte r, g, b;
                if (!byte.TryParse(dic["r"],out r))
                {
                    r = 0;
                }
                if (!byte.TryParse(dic["g"],out g))
                {
                    g = 0;
                }
                if (!byte.TryParse(dic["b"],out b))
                {
                    b = 0;
                }
                //修改畫刷的顔色
                sldBrush.Color = Color.FromArgb(255,r,g,b);
            }
        }
           

最後,在項目清單檔案中,聲明協定擴充項,應用程式才會在安裝時自動向作業系統注冊協定。打開清單檔案(Package.appxmanifest),在Application節點下輸入以下XML:

<Extensions>
        <uap:Extension Category="windows.protocol">
          <uap:Protocol Name="color"/>
        </uap:Extension>
      </Extensions>
           

Protocol元素的Name特性指定協定的名字為"color"。

建立另一個uwp項目用來啟動該協定,以啟動目标用戶端:

<Grid>
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="10">
            <TextBox x:Name="tb" MinWidth="200" MinHeight="100"/>
            <Button Content="啟動目标用戶端" Tapped="Button_Tapped"/>
        </StackPanel>
    </Grid>
           

按鈕Tapped事件處理程式:

private async void Button_Tapped(object sender, TappedRoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(tb.Text))
            {
                return;
            }
            await Launcher.LaunchUriAsync(new Uri(tb.Text));
        }
           

運作效果:uwp,協定激活示例