鸿蒙next 游戏授权登录教程王者归来

前沿导读

各位同学很久没有分享技术文章给大家了,因为最近需要兼职讲课,所以我比较忙。都也没有多少个人时间,所以也是趁着现在有空我们就分享下

效果图

调用效果

日志打印

需求背景

工作中最近接到需求,需要接入鸿蒙的游戏授权登录和内购支付,今天把流程走完整,所以现在就做一个分享

开放步骤

初始化

这里如果不是在 EntryAbility 接入初始化代码需要做调整

// 在EntryAbility 里面初始化
javascript 复制代码
try {
  gamePlayer.init(this.context,()=>{
    hilog.info(0x0000, 'testTag', `Succeeded in initing.`);
  });
} catch (error) {
  let err = error as BusinessError;
  hilog.error(0x0000, 'testTag', `Failed to init. Code: ${err.code}, message: ${err.message}`);
}
// 不在EntryAbility 里面执行初始化
javascript 复制代码
try {
 gamePlayer.init(context as  common.UIAbilityContext ,()=>{
   hilog.info(0x0000, 'testTag', `Succeeded in initing.`);

 });
} catch (error) {
 let err = error as BusinessError;
 hilog.error(0x0000, 'testTag', `Failed to init. Code: ${err.code}, message: ${err.message}`);
}

获取 gamePlayerId

javascript 复制代码
let context = getContext(this) as common.UIAbilityContext;

let request: gamePlayer.UnionLoginParam = {
  showLoginDialog: false,  // 是否弹出联合登录面板。true表示强制弹出面板,false表示优先使用玩家上一次的登录选择,不弹出联合登录面板,若玩家首次登录或卸载重装,则正常弹出。
  thirdAccountInfos: [] // 若游戏无官包或无官方账号体系,请传空数组。
};
try {
  gamePlayer.unionLogin(context, request).then((result: gamePlayer.UnionLoginResult) => {
    hilog.info(0x0000, 'testTag', `Succeeded in logining: ${result?.accountName}`);
    console.log("gamePlayerId accountName --- >" +result.accountName)
    console.log("gamePlayerId thirdOpenId --- >" +result.boundPlayerInfo.thirdOpenId)
    console.log("gamePlayerId bindType --- >" +result.boundPlayerInfo.bindType)

    let  localPlayer=result.localPlayer;
    if(localPlayer.gamePlayerId){
      console.log("index gamePlayerId  localPlayer gamePlayerId  --- >" +localPlayer.gamePlayerId)

    }

    if(localPlayer.teamPlayerId){
      console.log("index gamePlayerId  localPlayer teamPlayerId  --- >" +localPlayer.teamPlayerId)

    }

  }).catch((error: BusinessError) => {
    hilog.error(0x0000, 'testTag', `Failed to login. Code: ${error.code}, message: ${error.message}`);
  });
} catch (error) {
  let err = error as BusinessError;
  hilog.error(0x0000, 'testTag', `Failed to login. Code: ${err.code}, message: ${err.message}`);
}

获取authorizationCode

javascript 复制代码
let loginRequest = new authentication.HuaweiIDProvider().createLoginWithHuaweiIDRequest();
loginRequest.state = util.generateRandomUUID();
// 执行认证请求
try {
  let controller = new authentication.AuthenticationController(getContext(this));
  controller.executeRequest(loginRequest, (err, data) => {
    if (err) {
      hilog.error(0x0000, 'testTag', `Failed to login. Code: ${err.code}, message: ${err.message}`);
      return;
    }
    let loginWithHuaweiIDResponse = data as authentication.LoginWithHuaweiIDResponse;
    let state = loginWithHuaweiIDResponse.state;
    console.log("index  authorizationCode  state   ---> "+state)
    if (state != undefined && loginRequest.state != state) {
      hilog.error(0x0000, 'testTag', `Failed to login. State is different.`);
      return;
    }
    hilog.info(0x0000, 'testTag', `Succeeded in logining.`);

    let loginWithHuaweiIDCredential = loginWithHuaweiIDResponse.data!;
    let authorizationCode = loginWithHuaweiIDCredential.authorizationCode;
    console.log("index  authorizationCode  ---> "+authorizationCode)
    // 开发者处理authorizationCode
  });
} catch (error) {
  let err = error as BusinessError;
  hilog.error(0x0000, 'testTag', `Failed to login. Code: ${err.code}, message: ${err.message}`);
}

我们拿到了 gamePlayerId 和 authorizationCode 去请求服务端去获取

服务端流程

获取 Access Token地址

调用on接口注册playerChanged事件监听

javascript 复制代码
aboutToAppear(): void {
  // 调用on接口注册playerChanged事件监听
  try {
    gamePlayer.on('playerChanged', this.onPlayerChangedEventCallback);
    hilog.info(0x0000, 'testTag', `Succeeded in registering.`);
  } catch (error) {
    let err = error as BusinessError;
    hilog.error(0x0000, 'testTag', `Failed to register. Code: ${err.code}, message: ${err.message}`);
  }

}

监听事件回调

csharp 复制代码
private onPlayerChangedEventCallback(result: gamePlayer.PlayerChangedResult) {
  if (result.event === gamePlayer.PlayerChangedEvent.SWITCH_GAME_ACCOUNT) {
    // ...
    // 游戏号已切换,完成本地缓存清理工作后,再次调用unionLogin接口等

  }
}

提交玩家角色信息

javascript 复制代码
let context = getContext(this) as common.UIAbilityContext;
let request: gamePlayer.GSKPlayerRole = {
  roleId: '123', // 玩家角色ID,如游戏没有角色系统,请传入"0",务必不要传""和null。
  roleName: 'Jason', // 玩家角色名,如游戏没有角色系统,请传入"default",务必不要传""和null。
  serverId: '456',
  serverName: 'Zhangshan',
  gamePlayerId: '789', // 请根据实际获取到的gamePlayerId传值。
  thirdOpenId: '123' // 接入华为账号登录时不传该字段。接入游戏官方账号登录时,请根据实际获取到的thirdOpenId传值。
};
try {
  gamePlayer.savePlayerRole(context, request).then(() => {
    hilog.info(0x0000, 'testTag', `Succeeded in saving.`);
  });
} catch (error) {
  let err = error as BusinessError;
  hilog.error(0x0000, 'testTag', `Failed to save. Code: ${err.code}, message: ${err.message}`);
}

参数配置

我们需要在 添加如此下配置

json 复制代码
"metadata": [
  // 配置如下信息
  {
    "name": "client_id",
    "value": "xxxxxxxxx"  
    // 华为Client ID  请替换成你自己的正式参数
  },
  {
    "name": "app_id",
    "value": "6917581951060909508"
    // 华为APP ID 请替换成你自己的正式参数
  }
],

"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET"
  },
],

配置手动签名测试

查看日志

写在最后

整个鸿蒙游戏授权登录相对比较简单,但是有一个槽点,就是获取 gamePlayerId 和 authorizationCode需要分开两个方法回调 。其实可以做成一个回调更简单,这个希望后期能完善, 服务端逻辑对比客户端来说,还是相对复杂一点点,不过对着文档也是很快能解决这次接入 华为技术支持也帮了不少忙,这个点赞, 对于鸿蒙生态的推广这块,华为确实下了决心,也非常积极的回应。希望鸿蒙越来越好,国产系统早日完善。我依然是你们最爱的徐老师。我们下一期再见。

相关推荐
被开发耽误的大厨2 小时前
鸿蒙ArkTS 核心篇-13-if分支语句
华为·harmonyos·鸿蒙
爱笑的眼睛114 小时前
HarmonyOS Router 基本使用详解:从代码示例到实战要点
华为·harmonyos
Points11 小时前
开源项目:OpenHarmony WMA音频解码器
harmonyos·音视频开发
bdawn11 小时前
深入解析HarmonyOS:UIAbility与Page的生命周期协同
华为·生命周期·harmonyos·page·uiability·oncreate·ondidbuild
安卓开发者13 小时前
鸿蒙NEXT布局全解析:从线性到瀑布流,构建自适应UI界面
ui·华为·harmonyos
小星74014 小时前
鸿蒙服务端开发资料汇总
华为·wpf·harmonyos
在下历飞雨15 小时前
为啥选了Kuikly?2025“液态玻璃时代“六大跨端框架横向对比
android·harmonyos
技术猿1887027835116 小时前
华为 HarmonyOS 代表未来
华为·harmonyos
Jackson_Li19 小时前
图片/视频操作一条龙(1):图片的获取,预览与压缩(鸿蒙开发)
harmonyos
森之鸟19 小时前
开发中使用——鸿蒙CoreSpeechKit让文字发声
华为·harmonyos