因為鴻蒙系統剛出不久,官方的第三方登錄 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文章
4020瀏覽量
68342 -
SDK
+關注
關注
3文章
1101瀏覽量
51717 -
鴻蒙
+關注
關注
60文章
2963瀏覽量
45891
原文標題:在鴻蒙上實現QQ第三方登錄!
文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
鴻蒙應用如何喚起 QQ 安卓客戶端進行授權
評論