QQ互联SDK登录接口整合要领(Android版)

之前整合的版本很古老,可能是2018年的,最近想升级到当前最新版V3.5.14.4,遇到一些问题在此备忘。

注1:我的app只用到登录并得到open id和nickname,以下备忘仅针对此功能(如果希望得到更多用户信息参考官方demo,里边有处理头像等其它信息的代码)。

注2:最初的准备工作即申请QQ互联id等等,网上有很多介绍。

1、从app转入QQ登录界面的设置

<manifest> 内须添加

<queries>
    <package android:name="com.tencent.mobileqq" />
</queries>

这是因为Android11开始权限紧缩,若不加<queries>则无法转入QQ登录界面

2、变更引入的SDK

将gradle中对旧版SDK的引用

api files('libs/open_sdk_r6008_lite.jar')

变更为对最新版引用

api files('libs/open_sdk_3.5.14.4_r377deaa_lite.jar')

改变后注意点击Sync按钮(或File - Sync Project ...)

这个jar在官方demo下工程文件夹并列的libs/下,在官方demo工程下的libs下也有个open_sdk_lite.jar,两者大小都不一样,我选用的是这个文件名带版本号的。

3、代码部分(注意看注释

3-1、变量和类

final Activity activity = this;// Toast用,请自行修改变量名

public static Tencent mTencent;// 腾讯互联变量

// 用户在QQ登录界面登录或返回后,此侦听器进一步处理
IUiListener loginListener = new BaseUiListener() {
	@Override
	protected void doComplete(JSONObject values) {
		initOpenidAndToken(values);
		updateUserInfo();
	}
};

// BaseUiListener类
private class BaseUiListener extends DefaultUiListener {

	@Override
	public void onComplete(Object response) {
		if (null == response) {
			Toast.makeText(activity, "null == response", Toast.LENGTH_SHORT).show();
			return;
		}
		JSONObject jsonResponse = (JSONObject) response;
		if (jsonResponse.length() == 0) {
			Toast.makeText(activity, "jsonResponse.length() == 0", Toast.LENGTH_SHORT).show();
			return;
		}

        // 此时已得到用户的 open id
		Toast.makeText(activity, response.toString(), Toast.LENGTH_SHORT).show();
		doComplete((JSONObject)response);
	}

	protected void doComplete(JSONObject values) {
		// ...
	}

	@Override
	public void onError(UiError e) {
		// e.errorCode, e.errorMessage, e.errorDetail
		Toast.makeText(activity, "onError", Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onCancel() {
		Toast.makeText(activity, "onCancel", Toast.LENGTH_SHORT).show();
	}
}

// 获取用户信息后的处理句柄
Handler mHandler = new Handler() {

	@Override
	public void handleMessage(Message msg) {
		if (msg.what == 0) {
			JSONObject response = (JSONObject) msg.obj;
			if (response.has("nickname")) {
				try {
                    // 此时已得到用户的 nickname
					Toast.makeText(activity, response.getString("nickname"), Toast.LENGTH_SHORT).show();
				} catch (JSONException e) {
					Toast.makeText(activity, "JSONException", Toast.LENGTH_SHORT).show();
				}
			}
		}
	}

};

3-2、方法

private void loginQQ() {
	if(null == mTencent) {
		Toast.makeText(activity, "null == mTencent", Toast.LENGTH_SHORT).show();
	} else {
		if (!mTencent.isSessionValid()) {
			mTencent.login(this, "all", loginListener);
            // 调用后转入QQ登录界面,选择账号(若apk未签名则只能选择申请的测试QQ)
            // 选择并登录后,会返回app界面,自动调用onActivityResult()
            // 然后才能触发loginListener的onComplete或on其它方法
		} else {
			Toast.makeText(activity, "Already logged in", Toast.LENGTH_SHORT).show();
		}
	}
}

public static 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)) {
			mTencent.setAccessToken(token, expires);
			mTencent.setOpenId(openId);
		}
	} catch(Exception e) {
	}
}

private void updateUserInfo() {
	if (mTencent != null && mTencent.isSessionValid()) {
		IUiListener listener = new DefaultUiListener() {

			@Override
			public void onError(UiError e) {
				Toast.makeText(activity, "onError", Toast.LENGTH_SHORT).show();
			}

			@Override
			public void onComplete(final Object response) {
				Message msg = new Message();
				msg.obj = response;
				msg.what = 0;
				mHandler.sendMessage(msg);
			}

			@Override
			public void onCancel() {
				Toast.makeText(activity, "onCancel", Toast.LENGTH_SHORT).show();
			}
		};
        
        // 获取详细信息例如nickname
		UserInfo info = new UserInfo(this, mTencent.getQQToken());
		info.getUserInfo(listener);
	} else {
		// ...
	}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	super.onActivityResult(requestCode, resultCode, data);

	// 自V3.3.0 必须,否则无法呼出 loginListener的onComplete
	Tencent.onActivityResultData(requestCode,resultCode,data,listener);
}

3-3 调用

例如在点击界面里的登录按钮时

// 授权;实测有时不需要调用,原因未知,为保险起见调用一下
Tencent.setIsPermissionGranted(true);
// 创建 mTencent; Demo是3个参数,第3个参数对于登录来说没必要(可能对分享功能必要)
mTencent = Tencent.createInstance("your app id", this);// 替换 your app id
// 登录QQ
loginQQ();

loginQQ后的流程简介:

mTencent.login() -> QQ登录界面 -> onActivityResult()内调用Tencent.onActivityResultData() -> loginListener(BaseUiListener类)的onComlete() 得到了用户open id -> loginListener(override)的doComplete(),其内调用initOpenidAndToken(), updateUserInfo(), 后者创建内部listener并getUserInfo -> 该listener的onComplete()发送消息给mHandler -> mHandler得到用户nickname

4、混淆keep class

-keep class com.tencent.connect.** {*;}
-keep class com.tencent.open.** {*;}
-keep class com.tencent.tauth.** {*;}

否则debug时没问题,release版崩溃。

最主要的坑:

1、未处理onActivityResult()导致后续流程受阻;

2、未进行混淆处理。

参考

A、Logcat异常

若不在gradle增加

implementation 'com.squareup.okhttp3:okhttp:3.11.0'

则会在Logcat中发现异常;但不影响登录功能。

Caused by: java.lang.ClassNotFoundException: Didn't find class "okhttp3.internal.Version" on path

B、未用到的jar

在官方demo的工程文件夹下的libs/下有3个jar

mid-sdk-2.10.jar

mta-sdk-2.0.0.jar

open_sdk_lite.jar

实测不引入前2个jar,对登录功能无影响

至于第3个jar,见前边第2条

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值