0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

鴻蒙應用如何喚起 QQ 安卓客戶端進行授權(quán)

OpenHarmony技術(shù)社區(qū) ? 來源:HarmonyOS技術(shù)社區(qū) ? 作者:HarmonyOS技術(shù)社區(qū) ? 2022-01-04 15:01 ? 次閱讀

因為鴻蒙系統(tǒng)剛出不久,官方的第三方登錄 SDK 還沒出來,下面就介紹下在鴻蒙應用中實現(xiàn) QQ 登錄的方法(支持喚起 QQ 安卓客戶端進行授權(quán))。

前期準備

登錄 QQ 開放平臺→應用管理→創(chuàng)建應用 ,創(chuàng)建一個網(wǎng)站應用。

https://connect.qq.com/index.html
注意:要選擇網(wǎng)站應用,移動應用和小程序不適用該方案。

編寫代碼

①判斷是否已登錄

獲取登錄狀態(tài):在入口 AbilitySliceMainAbilitySlice 中進行判斷。

從數(shù)據(jù)庫獲取 token 的值判斷是否已經(jīng)登錄賬號(已登錄返回 token,未登錄返回 null)

//創(chuàng)建數(shù)據(jù)庫(這里使用官方提供的“輕量級數(shù)據(jù)存儲”,相關(guān)文檔:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/database-preference-guidelines-0000000000030083)
Preferencespreferences=newDatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME");
//從數(shù)據(jù)庫獲取token的值判斷是否已經(jīng)登錄賬號(已登錄返回token,未登錄返回null)
Stringtoken=preferences.getString("token",null);

進行相應跳轉(zhuǎn):已登錄跳轉(zhuǎn)至個人界面 MyAbility,未登錄跳轉(zhuǎn)至登錄界面 LoginAbility。

if(token!=null){
//已登錄,跳轉(zhuǎn)至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{
//未登錄,跳轉(zhuǎn)至LoginAbility
IntentloginIntent=newIntent();
OperationloginOperation=newIntent.OperationBuilder()
.withBundleName("cn.dsttl3.test")
.withAbilityName("cn.dsttl3.qqlogin.LoginAbility")
.build();
loginIntent.setOperation(loginOperation);
startAbility(loginIntent);
terminateAbility();
}

②登錄界面的操作

申請網(wǎng)絡(luò)訪問權(quán)限:在 config.json 添加。

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

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







登錄界面的 AbilitySlice LoginAbilitySlice.java,需要用到的幾個常量如下:

Stringstate=UUID.randomUUID().toString();//唯一標識,成功授權(quán)后回調(diào)時會原樣帶回。
Stringclient_id="101***151";//QQ開放平臺應用APPID
Stringredirect_uri="https%3A%2F%2Fapi.dsttl3.cn%2FRedis%2FQQLogin";//應用網(wǎng)站回調(diào)域需進行url編碼,授權(quán)成功后會跳轉(zhuǎn)至該鏈接
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設(shè)置為安卓,授權(quán)頁才顯示QQ客戶端一鍵登錄按鈕

自定義 WebAgent,當 WebView 即將打開一個鏈接時調(diào)用 isNeedLoadUrl 方法,當在網(wǎng)頁上點擊“一鍵登錄”時,打開 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);
}

因為目前還找不到網(wǎng)頁端喚起鴻蒙應用的方法,所以 QQ 客戶端回調(diào)的 code 放在自己服務器處理。

授權(quán)成功后,會打開之前在 QQ 開放平臺設(shè)置的回調(diào)域 redirect_uri。

示例:

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

code:QQ 授權(quán)返回的 code,用于申請 token。

state:在 webview 請求 QQ 授權(quán)頁面時傳入的唯一標識,用于判斷用戶身份,方便后續(xù)從服務器請求 token。

出于安全考慮 ,請求 token 操作放在服務器上執(zhí)行。獲取到 token 后將 token 存入數(shù)據(jù)庫,客戶端通過請求 https://api.dsttl3.cn/Redis/Get?key= + state 來獲取到 token。

客戶端請求到 token 后,將 token 存儲到數(shù)據(jù)庫:

//將token存入數(shù)據(jù)庫
Preferencespreferences=newDatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME");
preferences.putString("token",token);
preferences.flush();

token 存儲完成后跳轉(zhuǎn)至 MyAbility,自定義 WebAgent 完整代碼:

myWebView.setWebAgent(newWebAgent(){
//當WebView即將打開一個鏈接時調(diào)用該方法
@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存入數(shù)據(jù)庫
Preferencespreferences=newDatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME");
preferences.putString("token",token);
preferences.flush();
//跳轉(zhuǎn)至用戶界面
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;
}
});

加載網(wǎng)頁:

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開放平臺登錄授權(quán)文檔https://wiki.connect.qq.com/%e5%87%86%e5%a4%87%e5%b7%a5%e4%bd%9c_oauth2-0
Stringstate=UUID.randomUUID().toString();//唯一標識,成功授權(quán)后回調(diào)時會原樣帶回。
Stringclient_id="101547151";//QQ開放平臺應用APPID
Stringredirect_uri="https%3A%2F%2Fapi.dsttl3.cn%2FRedis%2FQQLogin";//應用網(wǎng)站回調(diào)域需進行url編碼,授權(quán)成功后會跳轉(zhuǎn)至該鏈接
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即將打開一個鏈接時調(diào)用該方法
@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存入數(shù)據(jù)庫
Preferencespreferences=newDatabaseHelper(getApplicationContext()).getPreferences("DATA_NAME");
preferences.putString("token",token);
preferences.flush();
//跳轉(zhuǎn)至用戶界面
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 數(shù)據(jù):

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

后續(xù)操作

獲取用戶信息請參考 QQ 開放平臺文檔:

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

附件下載

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

原文標題:在鴻蒙上實現(xiàn)QQ第三方登錄!

文章出處:【微信公眾號:HarmonyOS技術(shù)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

審核編輯:彭菁

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 數(shù)據(jù)庫
    +關(guān)注

    關(guān)注

    7

    文章

    3799

    瀏覽量

    64388
  • SDK
    SDK
    +關(guān)注

    關(guān)注

    3

    文章

    1036

    瀏覽量

    45935
  • 鴻蒙
    +關(guān)注

    關(guān)注

    57

    文章

    2351

    瀏覽量

    42849

原文標題:在鴻蒙上實現(xiàn)QQ第三方登錄!

文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術(shù)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    2012微信電腦客戶端免費下載

    的彩信不用再在意彩信費用,因為它完全免費,即時拍照即時分享?! ⊥型惖牧奶燔浖粯?,微信也能設(shè)置自己的個人信息和頭像,更方便你的好友快速的找到你。  微信目前就是簡單的手機客戶端,沒有電腦
    發(fā)表于 09-13 18:59

    如何看待鴻蒙系統(tǒng)兼容系統(tǒng)?

    網(wǎng)絡(luò)看到很多人討論鴻蒙,有人說鴻蒙就是換皮版的,有人說
    發(fā)表于 10-10 11:06

    鴻蒙取代?這下鴻蒙開發(fā)者要坐不住了!

    授權(quán)。僅這一點,華為做的事情,就應當受到國人的支持。換句話說,華為現(xiàn)如今不開發(fā)鴻蒙OS系統(tǒng),谷歌全面斷供國產(chǎn)手機的情況一旦出現(xiàn)。手機直接變成“板磚”,屆時對于國內(nèi)的手機市場造成的
    發(fā)表于 12-08 09:33

    CSDN博客客戶端源碼

    CSDN博客客戶端源碼CSDN博客客戶端源碼CSDN博客客戶端源碼
    發(fā)表于 11-18 10:22 ?1次下載

    Android 仿QQ客戶端及服務源碼

    Android 仿QQ客戶端及服務源碼
    發(fā)表于 03-19 11:23 ?3次下載

    iOS淘寶客戶端應用名稱發(fā)生變化 Android客戶端應用名稱尚未更改

    iOS淘寶客戶端應用名稱發(fā)生變化 Android客戶端應用名稱尚未更改
    發(fā)表于 04-18 15:37 ?935次閱讀

    鴻蒙系統(tǒng)是基于

    有網(wǎng)友詢問鴻蒙系統(tǒng)是基于嗎?答案:鴻蒙系統(tǒng)并不是基于!
    的頭像 發(fā)表于 06-18 16:17 ?3.1w次閱讀

    鴻蒙系統(tǒng)和系統(tǒng)區(qū)別在哪里 鴻蒙的比較

    華為今年正式推出了全新的鴻蒙系統(tǒng),不少用戶都關(guān)心鴻蒙系統(tǒng)和之間的區(qū)別,下面就為大家介紹鴻蒙系統(tǒng)和
    的頭像 發(fā)表于 06-16 15:41 ?1.4w次閱讀

    鴻蒙os底層是

    鴻蒙os底層是系統(tǒng)嗎?答案顯然是否定的。根據(jù)小編的求證了解發(fā)現(xiàn),華為的鴻蒙操作系統(tǒng)只有一半是鴻蒙系統(tǒng)底層,而另一半?yún)s是
    的頭像 發(fā)表于 07-06 09:11 ?1.2w次閱讀

    鴻蒙好嗎 鴻蒙系統(tǒng)有哪些優(yōu)勢

    6月2號,鴻蒙系統(tǒng)正式發(fā)布,到現(xiàn)在,華為已經(jīng)有很多機型都能夠升級鴻蒙系統(tǒng)了,升級了的用戶還調(diào)侃到“從此是路人”。那么問題來了,鴻蒙
    的頭像 發(fā)表于 07-07 15:51 ?1.9w次閱讀

    鴻蒙的底層是鴻蒙是基于

    華為鴻蒙系統(tǒng)2.0自從上線后頗受國人追捧,作為全球首款主打“面向未來”、“萬物互聯(lián)”的分布式全場景操作系統(tǒng),鴻蒙系統(tǒng)可以說是開創(chuàng)了新的領(lǐng)域。然而很多人質(zhì)疑鴻蒙系統(tǒng)底層是基于
    的頭像 發(fā)表于 07-07 15:08 ?2.7w次閱讀

    鴻蒙是否脫離 鴻蒙的關(guān)系

    華為鴻蒙系統(tǒng)2.0發(fā)布至今,引發(fā)很多人對鴻蒙系統(tǒng)與系統(tǒng)之間的關(guān)聯(lián)的困惑,鴻蒙系統(tǒng)是基于
    的頭像 發(fā)表于 07-09 15:21 ?1.8w次閱讀

    鴻蒙是基于鴻蒙區(qū)別

    很多人很好奇鴻蒙系統(tǒng)和卓有什么關(guān)系?鴻蒙系統(tǒng)是基于系統(tǒng)研發(fā)而成的?鴻蒙系統(tǒng)與
    的頭像 發(fā)表于 07-10 09:36 ?4.6w次閱讀

    鴻蒙基于 鴻蒙系統(tǒng)和卓有什么區(qū)別

    華為鴻蒙系統(tǒng)2.0自發(fā)布至今備受關(guān)注,廣受好評,然而鴻蒙系統(tǒng)其底層也引發(fā)了許多人爭議,鴻蒙系統(tǒng)到底有沒有脫離系統(tǒng)?是基于
    的頭像 發(fā)表于 07-12 15:05 ?3w次閱讀

    密鑰服務器和客戶端常見問題解答

    OpticStudio網(wǎng)絡(luò)版授權(quán)被設(shè)計用于客戶端-服務器交互模式。密鑰服務器的意義為保有授權(quán),并且將單個授權(quán)席位分配給一臺客戶端電腦。
    的頭像 發(fā)表于 11-15 10:15 ?1288次閱讀