0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

鸿蒙应用如何唤起 QQ 安卓客户端进行授权

OpenHarmony技术社区 ? 来源:HarmonyOS技术社区 ? 作者:HarmonyOS技术社区 ? 2022-01-04 15:01 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

因为鸿蒙系统刚出不久,官方的第三方登录 SDK 还没出来,下面就介绍下在鸿蒙应用中实现 QQ 登录的方法(支持唤起 QQ 安卓客户端进行授权)。

前期准备

登录 QQ 开放平台→应用管理→创建应用 ,创建一个网站应用。

https://connect.qq.com/index.html
注意:要选择网站应用,移动应用和小程序不适用该方案。

编写代码

①判断是否已登录

获取登录状态:在入口 AbilitySliceMainAbilitySlice 中进行判断。

从数据库获取 token 的值判断是否已经登录账号(已登录返回 token,未登录返回 null)

//创建数据库(这里使用官方提供的“轻量级数据存储”,相关文档:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/database-preference-guidelines-0000000000030083)
Preferencespreferences=newDatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME");
//从数据库获取token的值判断是否已经登录账号(已登录返回token,未登录返回null)
Stringtoken=preferences.getString("token",null);

进行相应跳转:已登录跳转至个人界面 MyAbility,未登录跳转至登录界面 LoginAbility。

if(token!=null){
//已登录,跳转至MyAbility
IntentmyIntent=newIntent();
myIntent.setParam("token",token);
OperationmyOperation=newIntent.OperationBuilder()
.withBundleName("cn.dsttl3.test")
.withAbilityName("cn.dsttl3.qqlogin.MyAbility")
.build();
myIntent.setOperation(myOperation);
startAbility(myIntent);
terminateAbility();
}else{
//未登录,跳转至LoginAbility
IntentloginIntent=newIntent();
OperationloginOperation=newIntent.OperationBuilder()
.withBundleName("cn.dsttl3.test")
.withAbilityName("cn.dsttl3.qqlogin.LoginAbility")
.build();
loginIntent.setOperation(loginOperation);
startAbility(loginIntent);
terminateAbility();
}

②登录界面的操作

申请网络访问权限:在 config.json 添加。

"reqPermissions":[
{
"name":"ohos.permission.INTERNET"
}
]

登录界面布局文件 ability_login.xml,在布局文件中添加以后 webview 组件。







登录界面的 AbilitySlice LoginAbilitySlice.java,需要用到的几个常量如下:

Stringstate=UUID.randomUUID().toString();//唯一标识,成功授权后回调时会原样带回。
Stringclient_id="101***151";//QQ开放平台应用APPID
Stringredirect_uri="https%3A%2F%2Fapi.dsttl3.cn%2FRedis%2FQQLogin";//应用网站回调域需进行url编码,授权成功后会跳转至该链接
Stringauthorize_url="https://graph.qq.com/oauth2.0/authorize?response_type=code"+
"&client_id="+client_id+
"&redirect_uri="+redirect_uri+
"&state="+state;

WebView 的配置:

WebViewmyWebView=(WebView)findComponentById(ResourceTable.Id_WebView_qqlogin);
myWebView.getWebConfig().setJavaScriptPermit(true);//支持JavaScript
myWebView.getWebConfig().setUserAgent("android");//将UserAgent设置为安卓,授权页才显示QQ客户端一键登录按钮

自定义 WebAgent,当 WebView 即将打开一个链接时调用 isNeedLoadUrl 方法,当在网页上点击“一键登录”时,打开 QQ 客户端。

wtloginmqq 是 QQ 安卓客户端 URL Scheme:

if(request.getRequestUrl().toString().startsWith("wtloginmqq")){
//打开QQ客户端
IntentqqIntent=newIntent();
OperationqqOperation=newIntent.OperationBuilder()
.withAction("android.intent.action.VIEW")
.withUri(Uri.parse(request.getRequestUrl().toString()))
.build();
qqIntent.setOperation(qqOperation);
startAbility(qqIntent);
}

因为目前还找不到网页端唤起鸿蒙应用的方法,所以 QQ 客户端回调的 code 放在自己服务器处理。

授权成功后,会打开之前在 QQ 开放平台设置的回调域 redirect_uri。

示例:

https://api.dsttl3.cn/Redis/QQLogin?code=********&state=*****

code:QQ 授权返回的 code,用于申请 token。

state:在 webview 请求 QQ 授权页面时传入的唯一标识,用于判断用户身份,方便后续从服务器请求 token。

出于安全考虑 ,请求 token 操作放在服务器上执行。获取到 token 后将 token 存入数据库,客户端通过请求 https://api.dsttl3.cn/Redis/Get?key= + state 来获取到 token。

客户端请求到 token 后,将 token 存储到数据库:

//将token存入数据库
Preferencespreferences=newDatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME");
preferences.putString("token",token);
preferences.flush();

token 存储完成后跳转至 MyAbility,自定义 WebAgent 完整代码:

myWebView.setWebAgent(newWebAgent(){
//当WebView即将打开一个链接时调用该方法
@Override
publicbooleanisNeedLoadUrl(WebViewwebView,ResourceRequestrequest){
//request.getRequestUrl().toString()WebView即将打开的链接地址
if(request.getRequestUrl().toString().startsWith("wtloginmqq")){
//打开QQ客户端
IntentqqIntent=newIntent();
OperationqqOperation=newIntent.OperationBuilder()
.withAction("android.intent.action.VIEW")
.withUri(Uri.parse(request.getRequestUrl().toString()))
.build();
qqIntent.setOperation(qqOperation);
startAbility(qqIntent);
//向自己的服务器请求token
newThread(newRunnable(){
@Override
publicvoidrun(){
while(true){
StringgetTokenURL="https://api.dsttl3.cn/Redis/Get?key="+state;
try{
OkHttpClientclient=newOkHttpClient();
Requestrequest=newRequest.Builder().url(getTokenURL).build();
Stringtoken=client.newCall(request).execute().body().string();
if(token.length()==32){
getUITaskDispatcher().asyncDispatch(newRunnable(){
@Override
publicvoidrun(){
//将token存入数据库
Preferencespreferences=newDatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME");
preferences.putString("token",token);
preferences.flush();
//跳转至用户界面
IntentmyIntent=newIntent();
OperationmyOperation=newIntent.OperationBuilder()
.withBundleName("cn.dsttl3.test")
.withAbilityName("cn.dsttl3.qqlogin.MyAbility")
.build();
myIntent.setOperation(myOperation);
startAbility(myIntent);
terminateAbility();
}
});
break;
}
Time.sleep(1500);
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}).start();
returnfalse;
}
returntrue;
}
});

加载网页:

myWebView.load(authorize_url);

LoginAbilitySlice.java 完整代码:

importcn.dsttl3.qqlogin.ResourceTable;
importohos.aafwk.ability.AbilitySlice;
importohos.aafwk.content.Intent;
importohos.aafwk.content.Operation;
importohos.agp.components.webengine.ResourceRequest;
importohos.agp.components.webengine.WebAgent;
importohos.agp.components.webengine.WebView;
importohos.data.DatabaseHelper;
importohos.data.preferences.Preferences;
importohos.miscservices.timeutility.Time;
importohos.utils.net.Uri;
importokhttp3.OkHttpClient;
importokhttp3.Request;
importjava.io.IOException;
importjava.util.UUID;

publicclassLoginAbilitySliceextendsAbilitySlice{

//QQ开放平台登录授权文档https://wiki.connect.qq.com/%e5%87%86%e5%a4%87%e5%b7%a5%e4%bd%9c_oauth2-0
Stringstate=UUID.randomUUID().toString();//唯一标识,成功授权后回调时会原样带回。
Stringclient_id="101547151";//QQ开放平台应用APPID
Stringredirect_uri="https%3A%2F%2Fapi.dsttl3.cn%2FRedis%2FQQLogin";//应用网站回调域需进行url编码,授权成功后会跳转至该链接
Stringauthorize_url="https://graph.qq.com/oauth2.0/authorize?response_type=code"+
"&client_id="+client_id+
"&redirect_uri="+redirect_uri+
"&state="+state;
@Override
publicvoidonStart(Intentintent){
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_login);
WebViewmyWebView=(WebView)findComponentById(ResourceTable.Id_WebView_qqlogin);
myWebView.getWebConfig().setJavaScriptPermit(true);
myWebView.getWebConfig().setUserAgent("android");
myWebView.setWebAgent(newWebAgent(){
//当WebView即将打开一个链接时调用该方法
@Override
publicbooleanisNeedLoadUrl(WebViewwebView,ResourceRequestrequest){
//request.getRequestUrl().toString()WebView即将打开的链接地址
if(request.getRequestUrl().toString().startsWith("wtloginmqq")){
//打开QQ客户端
IntentqqIntent=newIntent();
OperationqqOperation=newIntent.OperationBuilder()
.withAction("android.intent.action.VIEW")
.withUri(Uri.parse(request.getRequestUrl().toString()))
.build();
qqIntent.setOperation(qqOperation);
startAbility(qqIntent);
//向自己的服务器请求token
newThread(newRunnable(){
@Override
publicvoidrun(){
while(true){
StringgetTokenURL="https://api.dsttl3.cn/Redis/Get?key="+state;
try{
OkHttpClientclient=newOkHttpClient();
Requestrequest=newRequest.Builder().url(getTokenURL).build();
Stringtoken=client.newCall(request).execute().body().string();
if(token.length()==32){
getUITaskDispatcher().asyncDispatch(newRunnable(){
@Override
publicvoidrun(){
//将token存入数据库
Preferencespreferences=newDatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME");
preferences.putString("token",token);
preferences.flush();
//跳转至用户界面
IntentmyIntent=newIntent();
OperationmyOperation=newIntent.OperationBuilder()
.withBundleName("cn.dsttl3.test")
.withAbilityName("cn.dsttl3.qqlogin.MyAbility")
.build();
myIntent.setOperation(myOperation);
startAbility(myIntent);
terminateAbility();
}
});
break;
}
Time.sleep(1500);
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}).start();
returnfalse;
}
returntrue;
}
});
myWebView.load(authorize_url);
}
}

个人界面,获取 token 信息:

Preferencespreferences=newDatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME");
Stringtoken=preferences.getString("token",null);

更新 Text 数据:

Texttext=findComponentById(ResourceTable.Id_text_helloworld);
text.setText(token);

后续操作

获取用户信息请参考 QQ 开放平台文档:

https://wiki.connect.qq.com/get_user_info

附件下载:

https://harmonyos.51cto.com/posts/9448

原文标题:在鸿蒙上实现QQ第三方登录!

文章出处:【微信公众号:HarmonyOS技术社区】欢迎添加关注!文章转载请注明出处。

审核编辑:彭菁

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据库
    +关注

    关注

    7

    文章

    3939

    浏览量

    66537
  • SDK
    SDK
    +关注

    关注

    3

    文章

    1079

    浏览量

    49410
  • 鸿蒙
    +关注

    关注

    60

    文章

    2643

    浏览量

    44234

原文标题:在鸿蒙上实现QQ第三方登录!

文章出处:【微信号:gh_834c4b3d87fe,微信公众号:OpenHarmony技术社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    2012微信电脑客户端免费下载

    的彩信不用再在意彩信费用,因为它完全免费,即时拍照即时分享。  同所有同类的聊天软件一样,微信也能设置自己的个人信息和头像,更方便你的好友快速的找到你。  微信目前就是简单的手机客户端,没有电脑
    发表于 09-13 18:59

    如何看待鸿蒙系统兼容系统?

    网络看到很多人讨论鸿蒙,有人说鸿蒙就是换皮版的,有人说
    发表于 10-10 11:06

    鸿蒙取代?这下鸿蒙开发者要坐不住了!

    授权。仅这一点,华为做的事情,就应当受到国人的支持。换句话说,华为现如今不开发鸿蒙OS系统,谷歌全面断供国产手机的情况一旦出现。手机直接变成“板砖”,届时对于国内的手机市场造成的
    发表于 12-08 09:33

    CSDN博客客户端源码

    CSDN博客客户端源码CSDN博客客户端源码CSDN博客客户端源码
    发表于 11-18 10:22 ?1次下载

    Android 仿QQ客户端及服务源码

    Android 仿QQ客户端及服务源码
    发表于 03-19 11:23 ?3次下载

    iOS淘宝客户端应用名称发生变化 Android客户端应用名称尚未更改

    iOS淘宝客户端应用名称发生变化 Android客户端应用名称尚未更改
    发表于 04-18 15:37 ?1070次阅读

    鸿蒙系统是基于

    有网友询问鸿蒙系统是基于吗?答案:鸿蒙系统并不是基于
    的头像 发表于 06-18 16:17 ?3.2w次阅读

    鸿蒙系统和系统区别在哪里 鸿蒙的比较

    华为今年正式推出了全新的鸿蒙系统,不少用户都关心鸿蒙系统和之间的区别,下面就为大家介绍鸿蒙系统和
    的头像 发表于 06-16 15:41 ?1.5w次阅读

    鸿蒙os底层是

    鸿蒙os底层是系统吗?答案显然是否定的。根据小编的求证了解发现,华为的鸿蒙操作系统只有一半是鸿蒙系统底层,而另一半却是
    的头像 发表于 07-06 09:11 ?1.3w次阅读

    鸿蒙好吗 鸿蒙系统有哪些优势

    6月2号,鸿蒙系统正式发布,到现在,华为已经有很多机型都能够升级鸿蒙系统了,升级了的用户还调侃到“从此是路人”。那么问题来了,鸿蒙
    的头像 发表于 07-07 15:51 ?2w次阅读

    鸿蒙的底层是鸿蒙是基于

    华为鸿蒙系统2.0自从上线后颇受国人追捧,作为全球首款主打“面向未来”、“万物互联”的分布式全场景操作系统,鸿蒙系统可以说是开创了新的领域。然而很多人质疑鸿蒙系统底层是基于
    的头像 发表于 07-07 15:08 ?2.7w次阅读

    鸿蒙是否脱离 鸿蒙的关系

    华为鸿蒙系统2.0发布至今,引发很多人对鸿蒙系统与系统之间的关联的困惑,鸿蒙系统是基于
    的头像 发表于 07-09 15:21 ?1.8w次阅读

    鸿蒙是基于鸿蒙区别

    很多人很好奇鸿蒙系统和卓有什么关系?鸿蒙系统是基于系统研发而成的?鸿蒙系统与
    的头像 发表于 07-10 09:36 ?4.7w次阅读

    鸿蒙基于 鸿蒙系统和卓有什么区别

    华为鸿蒙系统2.0自发布至今备受关注,广受好评,然而鸿蒙系统其底层也引发了许多人争议,鸿蒙系统到底有没有脱离系统?是基于
    的头像 发表于 07-12 15:05 ?3.1w次阅读

    密钥服务器和客户端常见问题解答

    OpticStudio网络版授权被设计用于客户端-服务器交互模式。密钥服务器的意义为保有授权,并且将单个授权席位分配给一台客户端电脑。
    的头像 发表于 11-15 10:15 ?1777次阅读