zoukankan      html  css  js  c++  java
  • 【Win10 UWP】QQ SDK(二):SDK的回调处理

    上一讲,我们介绍了QQ SDK的使用方法,请看《【Win10 UWP】QQ SDK(一):SDK基本使用方法》

    一. 回调的基本形式

    从前面的介绍中我们知道,我们的应用和QQ客户端之间需要通过文件类型和协议关联进行互调。我们需要调起QQ客户端进行分享或授权,同时QQ分享完成或授权完成之后,也需要调起我们的应用进行回调通知,把结果告诉我们的应用。

    1. 文件类型关联

    <uap:Extension Category="windows.fileTypeAssociation">
        <uap:FileTypeAssociation Name="test">
            <uap:SupportedFileTypes>
                <uap:FileType ContentType="application/qqsdkconnect">.qc-xxxxxxxxxx</uap:FileType>
            </uap:SupportedFileTypes>
        </uap:FileTypeAssociation>
    </uap:Extension>    

    看一下我们在Package.appxmanifest里进行的文件类型关联声明,声明了一种.qc-xxxxxxxxxx(其中xxx为你的AppId),表示我当前的应用能够打开这种后缀格式的文件,从而也就实现把我的应用调起来;显而易见,QQ客户端在回调的时候会生成这种后缀格式的文件,并且我们注意到在分享成功之后,QQ客户端会提示是否“返回应用”,当点击了“返回应用”,相当于QQ客户端想要打开这个文件;由于AppId的唯一性,能保证这个文件只能用我的应用打开;我们的应用打开这个文件后,就能读取这个文件的内容并讲结果进行解析啦。

    通过文件类型关联打开这个文件之后,在App.cs里,protected override void OnFileActivated(FileActivatedEventArgs args)方法会被触发,读取args.Files[0]这个文件的内容进行解析即可。

    QQSDK类提供CanHandleWindowsFileTypeAssociation(IStorageFile file)方法和HandleOpenWindowsFileTypeAssociation(IStorageFile  file)方法分别用来判断文件是否可解析,并且解析文件的内容。处理结果返回一个ResponseResult类型的对象,这就是我们要的回调结果了。

    2. 协议关联

    <uap:Extension Category="windows.protocol">
        <uap:Protocol Name="qc-xxxxxxxxxx" />
    </uap:Extension>

    协议关联比较简单,声明一个qc-xxxxxxxxxx的协议,QQ客户端在“返回应用”的时候也可以通过Launcher.LaunchUriAsync(new Uri("qc-xxxxxxxxxxx"))的方法把我们的应用调起来,在App.cs里,protected override async void OnActivated(IActivatedEventArgs args)方法会被触发,回调内容附带在args.Uri中。

    由于触发Activated的场景比较多(除了Protocol外),需要判断一下args.Kind是否为ActivationKind.Protocol才可进行处理。

    QQSDK类提供CanHandleWindowsProtocolUri(string uri)方法和HandleOpenWindowsProtocolUri(string uri)方法分别用来判断协议是否可解析,并且解析协议的内容。处理结果同样返回一个ResponseResult类型的对象,这就是我们要的回调结果了。

    这两者的区别只是在于回调结果数据量较大时,QQ客户端以文件类型回调(如登录授权、调用Open API等情形),数据量较小时(如分享)只需要以协议形式回调。实际上,我认为QQ SDK只需要统一使用文件类型关联就足够了。

    二. QQ SDK扩展辅助

    QQ SDK回调的处理还是需要不少代码量的,如果每个项目都要写这些重复代码其实是比较烦的。这里我写了一个扩展辅助ConnectQQSDK.Extensions,将所有的回调处理都进行了封装,只需要简单调用即可。

    ConnectQQSDK.Extensions库nuget下载地址:https://www.nuget.org/packages/ConnectQQSDK.Extensions/1.0.0

    或者控制台输入PM> Install-Package ConnectQQSDK.Extensions

    1. 初始化方法

    在App.cs的OnLaunched方法里,调用封装过的初始化方法

    QQSDKHelper.Initialize("xxxxxxxxxx", new QQCallback());

    其中QQCallback是一个继承了ConnectWPQQSDK.Extensions.IQQSDKCallback接口的类型,对于回调结果,用自己的应用认为合适的方法进行显示或存储。比如分享的回调结果,可以自己用Toast或MessageDialog显示出来;比如登录授权的回调结果,可以自己存储在独立存储或本地数据库中。Do It Yourself!

    public class QQCallback : IQQSDKCallback
    {
        public void OnHandleResult(ResponseResult result)
        {
            switch (result.OpenType)
            {
                case SDKOpenMessageType.eMessageTypeAuth:
             // 登录授权结果,反序列化result.ResultMsg得到Token、OpenId、过期时间等信息
    break; case SDKOpenMessageType.eMessageTypeShare:
             // ToastPrompt.Show(result.ResultCode == ResponseRetCode.SUCCESS ? "分享成功": "分享失败");
    break; case SDKOpenMessageType.eMessageTypeOpenAPI:
    // OpenAPI结果,反序列化result.ResultMsg得到相应信息,具体返回值请查看Open API官方文档
    break; } } }

    反序列可以用Json.Net或系统自带的DataContractJsonSerializer,不再多说。

    2. 文件关联和协议关联处理

    在App.cs的OnActivated方法里:

    protected override async void OnActivated(IActivatedEventArgs args)
    {
        base.OnActivated(args);
        await QQSDKHelper.OnActicated(args);
    }

    在OnFileActivated方法里:

    protected override async void OnFileActivated(FileActivatedEventArgs args)
    {
        base.OnFileActivated(args);
        await QQSDKHelper.OnFileActivated(args);
    }

    以上就是在应用里需要添加的代码,比起自己去处理SDK的回调结果要简单很多。

    三. QQ SDK扩展源码

    QQSDKHelper.cs源码

        public static class QQSDKHelper
        {
            public static void Initialize(string appId, IQQSDKCallback callback = null)
            {
                AppId = appId;
                Callback = callback;
    
                QQSDK.Instance.Initialize(appId);
            }
    
            public static async Task OnActicated(IActivatedEventArgs e)
            {
                try
                {
                    if (e.Kind == ActivationKind.Protocol)
                    {
                        var frame = Window.Current.Content as Frame;
                        if (frame == null)
                        {
                            return;
                        }
    
                        var protocalArgs = (ProtocolActivatedEventArgs) e;
                        if (protocalArgs.Uri == null)
                        {
                            return;
                        }
    
                        if (protocalArgs.Uri.Scheme.Equals($"qc-{AppId}"))
                        {
                            if (QQSDK.Instance.CanHandleWindowsProtocolUri(protocalArgs.Uri.ToString()))
                            {
                                var result = await QQSDK.Instance.HandleOpenWindowsProtocolUri(protocalArgs.Uri.ToString());
                                HandleResult(result);
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    // ignored
                }
            }
    
            public static async Task OnFileActivated(FileActivatedEventArgs e)
            {
                try
                {
                    var file = e.Files?.FirstOrDefault() as IStorageFile;
                    if (file == null)
                    {
                        return;
                    }
    
                    if (QQSDK.Instance.CanHandleWindowsFileTypeAssociation(file))
                    {
                        var result = await QQSDK.Instance.HandleOpenWindowsFileTypeAssociation(file);
                        HandleResult(result);
                    }
                }
                catch (Exception)
                {
                    // ignored
                }
            }
    
            private static void HandleResult(ResponseResult result)
            {
                Callback?.OnHandleResult(result);
            }
    
            public static IQQSDKCallback Callback { get; private set; }
            public static string AppId { get; private set; }
        }

    IQQSDKCallback.cs源码

        public interface IQQSDKCallback
        {
            void OnHandleResult(ResponseResult result);
        }

    本文仅用于学习交流,转载请注明出处:http://www.cnblogs.com/zhxilin/p/4664093.html

  • 相关阅读:
    spring多个context:property-placeholder不生效问题
    JAVA中自定义properties文件介绍
    spring.jar是包含有完整发布的单个jar 包,spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下才会用到 spring-mock.jar来进行辅助测试,正式应用系统中是用不得这些类的。
    web.xml文件头声明各个版本参考
    Java 组件化(gradle)
    阿里开源框架-JarsLink-【JAVA的模块化开发框架】
    二gradle创建SSM项目——Hello word
    一gradle创建SSM项目——依赖包
    微信开发学习总结(二)——微信开发入门
    js函数声明的三种方式
  • 原文地址:https://www.cnblogs.com/zhxilin/p/4664093.html
Copyright © 2011-2022 走看看