背水一戰 Windows 10 (101) - 應用間通信: 通過協議打開指定的 app 並傳遞數據以及獲取返回數據, 將本 app 沙盒內的文件共享給其他 app 使用


[源碼下載]


背水一戰 Windows 10 (101) - 應用間通信: 通過協議打開指定的 app 並傳遞數據以及獲取返回數據, 將本 app 沙盒內的文件共享給其他 app 使用



作者:webabcd


介紹
背水一戰 Windows 10 之 應用間通信

  • 通過協議打開指定的 app 並傳遞數據以及獲取返回數據
  • 將本 app 沙盒內的文件共享給其他 app 使用



示例
1、演示如何通過協議打開指定的 app 並傳遞數據以及獲取返回數據
App.xaml.cs

        protected override void OnActivated(IActivatedEventArgs args)
        {
            // 通過可返回結果的協議激活應用程序時(參見 App2AppCommunication/LaunchUriForResults.xaml.cs 中的示例)
            if (args.Kind == ActivationKind.ProtocolForResults)
            {
                ProtocolForResultsActivatedEventArgs protocolForResultsArgs = args as ProtocolForResultsActivatedEventArgs;

                Frame rootFrame = new Frame();
                rootFrame.Navigate(typeof(Windows10.App2AppCommunication.LaunchUriForResults), protocolForResultsArgs);
                Window.Current.Content = rootFrame;

                Window.Current.Activate();
            }
        }

App2AppCommunication/LaunchUriForResults.xaml

<Page
    x:Class="Windows10.App2AppCommunication.LaunchUriForResults"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows10.App2AppCommunication"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Name="grid" Background="Transparent">

        <StackPanel Margin="10 0 10 10">
            <TextBlock Name="lblMsg" Margin="5">
                <Run>本程序可以處理可返回結果的 webabcd: 協議</Run>
            </TextBlock>

            <Button Name="btnOpenProtocol" Content="打開自定義協議 webabcd: 並傳遞數據給目標程序,然后獲取目標程序的返回數據" Click="btnOpenProtocol_Click" Margin="5" />

            <Button Name="btnBack" Content="返回數據" Click="btnBack_Click" Margin="5" />

        </StackPanel>

    </Grid>
</Page>

App2AppCommunication/LaunchUriForResults.xaml.cs

/*
 * 演示如何通過協議打開指定的 app 並傳遞數據以及獲取返回數據
 * 
 * 1、在 Package.appxmanifest 中新增一個“協議”聲明,並做相關配置
 *    本例中的這部分的配置如下,協議名必須全小寫
 *    <uap:Extension Category="windows.protocol">
 *      <uap:Protocol Name="webabcd" ReturnResults="optional">
 *        <uap:Logo>Assets\StoreLogo.png</uap:Logo>
 *      </uap:Protocol>
 *    </uap:Extension>
 *    其中關於 ReturnResults 的說明如下:
 *        optional - 可以通過 LaunchUriAsync() 啟動,也可以通過 LaunchUriForResultsAsync() 啟動
 *        always - 只能通過 LaunchUriForResultsAsync() 啟動
 *        none - 只能通過 LaunchUriAsync() 啟動
 * 2、在 App.xaml.cs 中 override void OnActivated(IActivatedEventArgs args),以獲取相關的協議信息
 * 
 * 
 * ProtocolForResultsActivatedEventArgs - 通過可返回結果的協議激活應用程序時的事件參數
 *     Uri - 協議的 uri
 *     CallerPackageFamilyName - 激活當前 app 的 app 的 PackageFamilyName
 *     ProtocolForResultsOperation - 獲取 ProtocolForResultsOperation 對象
 *     Data - 返回一個 ValueSet 對象,用於獲取激活此 app 的 app 傳遞過來的數據
 *     Kind - 此 app 被激活的類型(ActivationKind 枚舉)
 *         本例為 ActivationKind.ProtocolForResults
 *     PreviousExecutionState - 此 app 被激活前的狀態(ApplicationExecutionState 枚舉)
 *         比如,如果此 app 被激活前就是運行狀態的或,則此值為 Running
 *     SplashScreen - 獲取此 app 的 SplashScreen 對象
 *     User - 獲取激活了此 app 的 User 對象
 *     
 * ProtocolForResultsOperation - 用於返回數據給激活當前 app 的 app
 *     ReportCompleted(ValueSet data) - 返回指定的數據
 *     
 * Launcher - 用於啟動與指定 Uri 相關的應用程序
 *     LaunchUriAsync(Uri uri) - 打開指定的 Uri,無返回結果
 *     LaunchUriForResultsAsync(Uri uri, LauncherOptions options, ValueSet inputData) - 打開指定的 Uri,並可以獲取到被激活的 app 返回的數據
 *         使用此種方式的話,必須要通過 LauncherOptions 的 TargetApplicationPackageFamilyName 指定目標程序的 PackageFamilyName
 *         使用此種方式的話,除了通過協議 uri 傳遞數據外,還可以通過 ValueSet 傳遞數據
 *         使用此種方式的話,會返回一個 LaunchUriStatus 類型的枚舉數據
 *             Success - 成功激活了
 *             AppUnavailable - 沒有通過 TargetApplicationPackageFamilyName 找到指定的 app
 *             ProtocolUnavailable - 指定的目標程序不支持此協議
 *             Unknown - 激活時發生了未知錯誤
 * 
 * LauncherOptions - 啟動外部應用程序時的相關選項
 *     TargetApplicationPackageFamilyName - 指定目標程序的 PackageFamilyName
 *     
 *         
 * 注:通過 ValueSet 傳遞數據,最大不能超過 100KB
 */

using System;
using Windows.ApplicationModel.Activation;
using Windows.Foundation.Collections;
using Windows.System;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace Windows10.App2AppCommunication
{
    public sealed partial class LaunchUriForResults : Page
    {
        private ProtocolForResultsActivatedEventArgs _protocolForResultsArgs;
        private ProtocolForResultsOperation _protocolForResultsOperation;

        public LaunchUriForResults()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // 獲取 ProtocolForResultsActivatedEventArgs 對象(從 App.xaml.cs 傳來的)
            _protocolForResultsArgs = e.Parameter as ProtocolForResultsActivatedEventArgs;

            // 顯示協議的詳細信息
            if (_protocolForResultsArgs != null)
            {
                _protocolForResultsOperation = _protocolForResultsArgs.ProtocolForResultsOperation;

                grid.Background = new SolidColorBrush(Colors.Blue);
                lblMsg.Foreground = new SolidColorBrush(Colors.White);

                lblMsg.Text = "激活程序的自定義協議為: " + _protocolForResultsArgs.Uri.AbsoluteUri;
                lblMsg.Text += Environment.NewLine;

                if (_protocolForResultsArgs.Data.ContainsKey("InputData"))
                {
                    string inputData = _protocolForResultsArgs.Data["InputData"] as string;

                    lblMsg.Text += $"收到了數據:{inputData}";
                    lblMsg.Text += Environment.NewLine;
                }                

                btnOpenProtocol.Visibility = Visibility.Collapsed;
            }
            else
            {
                btnBack.Visibility = Visibility.Collapsed;
            }
        }

        // 打開自定義協議 webabcd: 並傳遞數據給目標程序,然后獲取目標程序的返回數據
        private async void btnOpenProtocol_Click(object sender, RoutedEventArgs e)
        {
            Uri uri = new Uri("webabcd:data");
            var options = new LauncherOptions();
            // 用 LaunchUriForResultsAsync() 的話必須要指定目標程序的 PackageFamilyName
            options.TargetApplicationPackageFamilyName = "48c7dd54-1ef2-4db7-a75e-7e02c5eefd40_vsy44gny1fmrj"; 

            ValueSet inputData = new ValueSet();
            inputData["InputData"] = "input data";

            lblMsg.Text = "打開 webabcd: 協議,並傳遞數據";
            lblMsg.Text += Environment.NewLine;

            LaunchUriResult result = await Launcher.LaunchUriForResultsAsync(uri, options, inputData);
            if (result.Status == LaunchUriStatus.Success && result.Result != null && result.Result.ContainsKey("ReturnData"))
            {
                ValueSet theValues = result.Result;
                string returnData = theValues["ReturnData"] as string;

                lblMsg.Text += $"收到返回數據:{returnData}";
                lblMsg.Text += Environment.NewLine;
            }
        }

        // 返回數據
        private void btnBack_Click(object sender, RoutedEventArgs e)
        {
            ValueSet result = new ValueSet();
            result["ReturnData"] = "return data";

            _protocolForResultsOperation.ReportCompleted(result);
        }
    }
}


2、演示如何將本 app 沙盒內的文件共享給其他 app 使用
App2AppCommunication/SharedStorage.xaml

<Page
    x:Class="Windows10.App2AppCommunication.SharedStorage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows10.App2AppCommunication"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="10 0 10 10">

            <TextBlock Name="lblMsg" TextWrapping="Wrap" Margin="5" />

            <Button Name="btnSave" Content="將沙盒內的指定文件設置為可共享,並生成 token" Click="btnSave_Click" Margin="5" />

            <Button Name="btnLoad" Content="根據 token 獲取文件(為了演示方便,本例就在同一個 app 中演示了,實際上在其他 app 中也是可以根據此 token 獲取文件的)" Click="btnLoad_Click" Margin="5" />

            <Button Name="btnDelete" Content="根據 token 將沙盒內的可共享文件設置為不可共享" Click="btnDelete_Click" Margin="5" />

        </StackPanel>
    </Grid>
</Page>

App2AppCommunication/SharedStorage.xaml.cs

/*
 * 演示如何將本 app 沙盒內的文件共享給其他 app 使用
 * 
 * SharedStorageAccessManager.AddFile(IStorageFile file) - 指定文件設置為可共享,並返回 token
 * SharedStorageAccessManager.RedeemTokenForFileAsync(string token) - 在其他 app 中可以根據 token 獲取 StorageFile 對象,並且可讀可寫
 * SharedStorageAccessManager.RemoveFile(string token) - 根據 token 將指定的可共享文件設置為不可共享
 * 
 * 注:
 * 1、一個 token 的有效期為 14 天
 * 2、一個 app 最多可以擁有 1000 個有效的 token
 * 3、一個 token 被訪問一次后就會失效(文檔是這么寫的,但是實際測試發現並不會失效)
 */

using System;
using Windows.ApplicationModel.DataTransfer;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Windows10.App2AppCommunication
{
    public sealed partial class SharedStorage : Page
    {
        private string _sharedToken;

        public SharedStorage()
        {
            this.InitializeComponent();
        }

        // 將沙盒內的指定文件設置為可共享,並生成 token
        private async void btnSave_Click(object sender, RoutedEventArgs e)
        {
            StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(@"webabcdTest\sharedStorage.txt", CreationCollisionOption.ReplaceExisting);
            await FileIO.WriteTextAsync(file, "I am webabcd: " + DateTime.Now.ToString());

            _sharedToken = SharedStorageAccessManager.AddFile(file);

            lblMsg.Text += $"文件 {file.Path} 已經被設置為可共享,其 token 值為 {_sharedToken}";
            lblMsg.Text += Environment.NewLine;
        }

        // 根據 token 獲取文件
        // 為了演示方便,本例就在同一個 app 中演示了,實際上在其他 app 中也是可以根據此 token 獲取文件的
        private async void btnLoad_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                StorageFile file = await SharedStorageAccessManager.RedeemTokenForFileAsync(_sharedToken);
                string textContent = await FileIO.ReadTextAsync(file);

                lblMsg.Text += $"token 值為 {_sharedToken} 的文件的內容為: {textContent}";
                lblMsg.Text += Environment.NewLine;
            }
            catch (Exception ex)
            {
                lblMsg.Text += ex.ToString();
                lblMsg.Text += Environment.NewLine;
            }
        }

        // 根據 token 將沙盒內的可共享文件設置為不可共享
        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                SharedStorageAccessManager.RemoveFile(_sharedToken);

                lblMsg.Text += $"token 值為 {_sharedToken} 的文件取消共享了";
                lblMsg.Text += Environment.NewLine;
            }
            catch (Exception ex)
            {
                lblMsg.Text += ex.ToString();
                lblMsg.Text += Environment.NewLine;
            }
        }
    }
}



OK
[源碼下載]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM