Unity 多平台原生SDK接入速览(二):QQ互联

2021-04-12 12:28

阅读:698

标签:category   文件中   call   存在   eui   data   lis   -o   内容   

ZeroyiQ:Unity 多平台原生SDK接入速览(一):微信开放平台

ZeroyiQ:Unity 多平台原生SDK接入速览(三):Facebook

ZeroyiQ:Unity 多平台原生SDK接入速览(四):Twitter

ZeroyiQ:Unity 多平台原生SDK接入速览(五):微博

一、前言

QQ互联,当前(2020-6-29)支持个人开发者认证和企业认证。创建应用,等待审核后获取 AppID 和 AppKey。

二、SDK接入

1. 添加 jar 包

下载 jar 包,添加到工程 libs 路径下。(Android SDK 中就包含了演示工程 Demo)

技术图片

2. 设置权限

AndroidManifest.xml 文件中添加网络权限。

3. 配置 Activity

AndroidManifest.xml 添加 Activity 配置 ,需要填入 AppId。注意格式为 tencent+AppId,例,AppId 是 2222 ,则填入 tencent2222。


 
    

4. 初始化

创建 Tencent 实例。

    public static final String QQ_ID = "你的AppId";
    public static final String AUTHORITIES = ".fileprovider";
    
    public static Tencent QQ_API;

    private void init() {
        if (!bIsInitialized) {
            bIsInitialized = true;
            
            // Tencent类是SDK的主要实现类,开发者可通过Tencent类访问腾讯开放的OpenAPI。
            // 其中APP_ID是分配给第三方应用的appid,类型为String。
            // 其中Authorities为 Manifest文件中注册FileProvider时设置的authorities属性值 
            QQ_API = Tencent.createInstance(QQ_ID, activity.getApplicationContext(), AUTHORITIES);
        }
    }

注,初始化依赖 FileProvider,如果没有添加,可以从 Demo 中找到 Jar 包, 依照 第1步 一样添加 Jar包。

在 AndroidManifest.xml 中配置,替换包名。

上面的创建实例传入的 AUTHORITIES 值与 android:authorities 保持一致。

    
        

5. 实现回调

通过实现对应接口,创建和传入对应 Listener,实现请求的回调监听。然而,当前存在两种回调接口。

IUiListener(SDK 封装的情况)

例如:登录、快速支付登录、应用分享、应用邀请等接口,需传入该回调的实例。

private class BaseUiListener implements IUiListener {
        public static final String TAG = "QQUiListener";

        @Override
        public void onComplete(Object response) {
            if (null == response) {
                UnityCallApi.unityLogError(TAG, "QQ request error. response is null.");
                ToastUtils.show(activity, R.string.errcode_null);
                return;
            }
            JSONObject jsonResponse = (JSONObject) response;
            if (jsonResponse.length() == 0) {
                UnityCallApi.unityLogError(TAG, "QQ request error. response length is 0.");
                ToastUtils.show(activity, R.string.errcode_null);
                return;
            }
            UnityCallApi.unityLogInfo(TAG, "QQ request successfully.");
            ToastUtils.show(activity, R.string.errcode_success);
            // 有奖分享处理
//            handlePrizeShare();
            onSuccessful((JSONObject) response);
        }

        @Override
        public void onError(UiError e) {
            UnityCallApi.unityLogError(TAG, "QQ request error" + e.toString());
            ToastUtils.show(activity, activity.getString(R.string.errcode_unknown) + ", type=" + e.errorMessage);
            onFailed();
        }

        @Override
        public void onCancel() {
            UnityCallApi.unityLogInfo(TAG, "QQ request cancel.");
            ToastUtils.show(activity, R.string.errcode_cancel);
            onFailed();
        }

        protected void onFailed() {

        }

        protected void onSuccessful(JSONObject values) {

        }
    }

IRequestListener (SDK 未封装的情况)

使用requestAsync、request等通用方法调用sdk未封装的接口时,例如上传图片、查看相册等,需传入该回调的实例。(轻度使用 SDK,将不会涉及该接口 ,故对于接口内容不做展示)

特别注意,为了能收到回调,还需要在调用 SDK 接口的 Activity 的 onActivityResult 添加如下方法。官方文档 中的方法已经被废弃,当前使用的是 Demo 演示中的方法,loginListener 就是 BaseUiListener 的用来处理登录回调的实例。可以根据 requestCode 来判断该响应那个回调。关于 onActivityResult 可以看这个介绍文章,从 otherActivity 切换回来当前 Activity 的时候运行。

 	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	    Log.d(TAG, "-->onActivityResult " + requestCode  + " resultCode=" + resultCode);
	    if (requestCode == Constants.REQUEST_LOGIN ||
	    	requestCode == Constants.REQUEST_APPBAR) {
	    	// 传递回调
	    	Tencent.onActivityResultData(requestCode,resultCode,data,loginListener);
	    }

	    super.onActivityResult(requestCode, resultCode, data);
	}

三、登录

1.发起登录请求

在初始化 Tencent 后,发起登录请求。

    public void login(Activity activity) {
        this.activity = activity;
        // 判断会话是否有效
        if (!QQ_API.isSessionValid()) {
            // all 全部作用域,loginListener 就是上文的登录回调
            QQ_API.login(activity, "all", loginListener);
            Log.d("SDKQQAgentPref", "FirstLaunch_SDK:" + SystemClock.elapsedRealtime());
        }
    }

2.实例化回调

实例化我们之前实现的 IUiListener 的 BaseUiListener 类。

    IUiListener loginListener = new BaseUiListener() {
        @Override
        protected void onSuccessful(JSONObject values) {
            UnityCallApi.unityLogInfo(TAG, "Login successful.");
            // 初始化 openId 和 Token
            initOpenidAndToken(values);
            // 获取用户信息
            updateUserInfo();
        }

        @Override
        protected void onFailed() {
            UnityCallApi.unityLogInfo(TAG, "Login failed.");
        }
    };

注意别忘记前文所说,在 Activity 的 onActivityResult 添加对应的 onActivityResultData。

3.初始化 OpenId 和 Token

使用登陆接口登陆成功以后,在登陆的回调接口保存登陆返回的token和过期时间。

    private void initOpenidAndToken(JSONObject jsonObject) {
        try {
            String token = jsonObject.getString(Constants.PARAM_ACCESS_TOKEN);
            String expires = jsonObject.getString(Constants.PARAM_EXPIRES_IN);
            String openId = jsonObject.getString(Constants.PARAM_OPEN_ID);
            if (!TextUtils.isEmpty(token) && !TextUtils.isEmpty(expires) && !TextUtils.isEmpty(openId)) {
                QQ_API.setAccessToken(token, expires);
                QQ_API.setOpenId(openId);
                QQ_API.saveSession(jsonObject);
            }
        } catch (Exception e) {
            e.printStackTrace();
            UnityCallApi.unityLogError(TAG, "Parse response to json error.");
        }
    }

四、获取用户信息

在登录后,发送获取用户信息请求。

    private void updateUserInfo() {
        if (QQ_API != null && QQ_API.isSessionValid()) {

            IUiListener listener = new BaseUiListener() {
                @Override
                protected void onSuccessful(JSONObject values) {
                    // 传递到 Unity 中进行解析
                    UnityCallApi.sendLoginInfoToUnity(true, values.toString());
                }

                @Override
                protected void onFailed() {
                    UnityCallApi.sendLoginInfoToUnity(false, "");
                }
            };
            // 只有初始化过 token 后才能 get 
            UserInfo info = new UserInfo(activity, QQ_API.getQQToken());
            info.getUserInfo(listener);
        }
    }

将返回信息传递给 Unity 进行解析。

正确返回的 json。

技术图片

五、分享

1. 图文(网页)

QQ分享不支持直接分享纯文字,必须要传入跳转 URL。

    public void shareWebLink(Bundle params) {
        Bundle paramsIn = new Bundle();
        paramsIn.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);    // 类型 default (必要)
        paramsIn.putString(QQShare.SHARE_TO_QQ_TARGET_URL,"链接");     // 链接 (必要)
        paramsIn.putString(QQShare.SHARE_TO_QQ_TITLE,"标题");    // 链接标题 (必要)
        paramsIn.putString(QQShare.SHARE_TO_QQ_SUMMARY,"摘要");    // 链接摘要 (必要)
        paramsIn.putString(QQShare.SHARE_TO_QQ_IMAGE_URL,"图片URL"); // 本地 or 网络图片 url (可选)
        paramsIn.putString(QQShare.SHARE_TO_QQ_APP_NAME, APP_NAME); // 应用名称 客户端顶部替换返回按钮文字 (可选)
        paramsIn.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_ITEM_HIDE);     // 隐藏 QZone (可选)
        // 分享Listener,会添加到 OnActivityResult 中
        shareListener = new BaseUiListener() {
            @Override
            protected void onSuccessful(JSONObject values) {
                // 成功
            }

            @Override
            protected void onFailed() {
                // 失败
            }
        };
        QQ_API.shareToQQ(activity, paramsIn, shareListener);
    }

QQShare.SHARE_TO_QQ_EXT_INT 参数值的分享到 QZone 就是如下界面。

技术图片

因为跳转到了QQ界面,别忘了为了响应回调,需要在 OnActivityResult 中添加如下代码。

    @Override  //这段代码非常重要,不加的话无法获取回调
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // 判断是QQ分享结果
        if (requestCode == Constants.REQUEST_QQ_SHARE) {
            Tencent.onActivityResultData(requestCode, resultCode, data, shareListener);
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

技术图片

2. 纯图片

注意纯图片分享是只支持本地图片的,并不支持在线图片。图片大小不能超过 5M。

       public void shareImage(Bundle params) {
        Bundle paramsIn = new Bundle();
        paramsIn.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE);    //  类型 Image (必要)
        paramsIn.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, "本地图片路径Path"); // 本地图片路径 (必要)
        paramsIn.putString(QQShare.SHARE_TO_QQ_APP_NAME, APP_NAME); // 应用名称 客户端顶部替换返回按钮文字 (可选)
        paramsIn.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_ITEM_HIDE);   // 隐藏 QZone (可选)
       shareListener = new BaseUiListener() {
            @Override
            protected void onSuccessful(JSONObject values) {
               // 成功
            }

            @Override
            protected void onFailed() {
                // 失败
            }
        };
        String localPath = paramsIn.getString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL);
        if (!TextUtils.isEmpty(localPath)) {
            File file = new File(localPath);
            if (file.length() >= 5 * 1024 * 1024) { // 大小不能超过 5M
                shareListener.onError(new UiError(Constants.ERROR_IMAGE_TOO_LARGE, Constants.MSG_SHARE_IMAGE_TOO_LARGE_ERROR, null));
                return;
            }
        }
        QQ_API.shareToQQ(activity, paramsIn, shareListener);
    }

技术图片

3. 应用

分享其实和图文很类似,重点还是在 SHARE_TO_QQ_TARGET_URL 设置的网页。

    public void shareApp(Bundle params) {
        Bundle paramsIn = new Bundle();
        paramsIn.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_APP);    // 类型 App (必要)
        paramsIn.putString(QQShare.SHARE_TO_QQ_TITLE, "标题");    // 链接标题 (必要)
        paramsIn.putString(QQShare.SHARE_TO_QQ_SUMMARY, "摘要");    // 链接摘要(必要)
        paramsIn.putString(QQShare.SHARE_TO_QQ_TARGET_URL, "应用链接");     // 应用链接 (必要)
        paramsIn.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, "应用icon链接");     // 应用icon链接 (必要)
        paramsIn.putString(QQShare.SHARE_TO_QQ_APP_NAME, APP_NAME); // 应用名称 客户端顶部替换返回按钮文字 (可选)
        paramsIn.putInt(QQShare.SHARE_TO_QQ_EXT_INT, QQShare.SHARE_TO_QQ_FLAG_QZONE_ITEM_HIDE);     // 隐藏 QZone(可选)
        shareListener = new BaseUiListener() {
            @Override
            protected void onSuccessful(JSONObject values) {
                // 成功
            }

            @Override
            protected void onFailed() {
                // 失败
            }
        };
        QQ_API.shareToQQ(activity, paramsIn, shareListener);
    }

技术图片

六、总结

QQ互联的接入和使用还是简单的。不需要微信那种通过登陆请求获取 code,再通过 code 获取 access token 的操作。并且QQ互联的分享,并不需要登陆也是可以的。官方提供的 SDK 的压缩包中,不光是 SDK,也包含了 Demo 的 APK 和工程项目,这个真的要给好评。

七、引用

  1. Android_SDK环境搭建 - QQ互联WIKI
  2. Android FileProvider的使用
  3. onActivityResult的用法_许佳佳的博客-CSDN博客_protected void onactivityresult

Unity 多平台原生SDK接入速览(二):QQ互联

标签:category   文件中   call   存在   eui   data   lis   -o   内容   

原文地址:https://www.cnblogs.com/ZeroyiQ/p/13353820.html


评论


亲,登录后才可以留言!