<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
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

    文章

    3592

    瀏覽量

    63399
  • SDK
    SDK
    +關注

    關注

    3

    文章

    966

    瀏覽量

    44776
  • 鴻蒙
    +關注

    關注

    55

    文章

    1651

    瀏覽量

    42132

原文標題:在鴻蒙上實現QQ第三方登錄!

文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

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

    的彩信不用再在意彩信費用,因為它完全免費,即時拍照即時分享?! ⊥型惖牧奶燔浖粯?,微信也能設置自己的個人信息和頭像,更方便你的好友快速的找到你?! ∥⑿拍壳熬褪呛唵蔚氖謾C客戶端,沒有電腦
    發表于 09-13 18:59

    一個服務器,多個客戶端,怎么向指定的客戶端發數據

    我用labview做服務器,單片機做客戶端,客戶端幾百個,怎么區分客戶端,給指定的客戶發發數據
    發表于 06-01 09:26

    請問smartconfig開發手機客戶端的應用程序提供源代碼了嗎?在哪里下載?

    本帖最后由 一只耳朵怪 于 2018-6-7 14:46 編輯 你好,請問基于smartconfig開發手機客戶端的應用程序,你們提供源代碼了嗎?在哪里下載?ios和的都要,謝謝
    發表于 06-07 05:03

    的藍牙全面開發教程

    就基本完成了,在兩塊都開啟了藍牙的設備上分別建議服務器跟客戶端,并進行連接,連接成功后雙方就可以通過藍牙進行通信了。
    發表于 12-05 10:51

    基于的視頻遙控小車——電腦開發

    虛擬機中運行的,和平臺無關,只要平臺上有相應的Java虛擬機。本設計中手機是客戶端,電腦是服務器。采用ServerSocket類與多線程技術相互配合共同完成服務器
    發表于 07-06 16:10

    如履薄冰?華為將以鴻蒙替代

    `華為消費者CEO余承東表示HMS生態僅次于和iOS,生態中集成的AppGallery(應用市場)是谷歌Play、蘋果iOS之后全球第三大應用商店,這意味著鴻蒙系統所依賴的系統生態基本打造完成
    發表于 09-04 09:44

    如何看待鴻蒙系統兼容系統?

    網絡看到很多人討論鴻蒙,有人說鴻蒙就是換皮版的,有人說
    發表于 10-10 11:06

    鴻蒙 vs 六大維度對比

    生態系統至今已經發展了十幾年了,軟件生態可以說是相當完善。鴻蒙初出茅廬。所以現階段生態上完勝鴻蒙
    發表于 12-07 14:13

    鴻蒙 vs 六大維度對比

    生態系統至今已經發展了十幾年了,軟件生態可以說是相當完善。鴻蒙初出茅廬。所以現階段生態上完勝鴻蒙
    發表于 12-07 16:43

    如何使用Socket實現UDP客戶端?

    本教程介紹了如何利用socket 編程來實現一個 UDP 客戶端,與服務器進行通信。與開發 TCP 客戶端一樣,我們先將 socket 編程的流程列出來,然后給出具體的實例。
    發表于 03-30 07:39

    Labview客戶端狀態獲取

    求助,目前只有5積分,哪位大佬給點幫助:采用TCP傳輸數據,一個服務器多個客戶端,通過一個按鈕控制,點動按鈕將服務器中的一個文件發給4個客戶端,目前已實現發送文件和讀取連接客戶端數量,不過客戶
    發表于 11-15 15:02

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

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

    當WiFi信號變低時,服務器和客戶端之間的TCP通信丟失,如何使客戶端重新連接?

    大家好, 當 WiFi 信號變低時,服務器和客戶端之間的 TCP 通信丟失,比如超過 -80dBm。一旦客戶端斷開連接,它就無法重新連接并正常進行通信。如何讓客戶端在這里重新連接。
    發表于 05-15 07:31

    AT32基于FreeRTOS的AWS MQTT客戶端

    AT32基于FreeRTOS的AWS MQTT客戶端建立一個MQTT客戶端與 AWS IoT Core進行通訊,用戶可以基于這個范例去開發屬于自己的應用。
    發表于 10-26 06:03

    Android 仿QQ客戶端及服務端源碼

    Android 仿QQ客戶端及服務端源碼
    發表于 03-19 11:23 ?3次下載
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>