cocosCreator2.4 googlePlay登录升级、API 35、16KB内存页面的支持

环境:我这里是cocosCreator 2.4.12 导出的android 工程

登录升级

后台收到的google 的提醒:
在这里插入图片描述
之前是通过implementation 'com.google.android.gms:play-services-auth:20.0.0' 来获取玩家 uid 和 邮箱,然后发送到我们的服务器获取账号。

升级文档:从旧版 Google 登录服务迁移到 Credential Manager 和 AuthorizationClient

这位网友的文档写的很好:接入谷歌最新登录SDK凭据管理器Credential Manager

具体细节不考虑的话我们这边只要能从新的登录方式中继续获取玩家的 uid 和 邮箱,后续按照之前的逻辑继续下去就行了。

build.gradle 中引入新的sdk:

//google登录
implementation "androidx.credentials:credentials:1.3.0"
implementation "androidx.credentials:credentials-play-services-auth:1.3.0"
implementation "com.google.android.libraries.identity.googleid:googleid:1.1.0"

登录主要代码:

public static AppActivity app; // 在onCreate里保存的  app = this;
static final String TAG = "MainActivity";private static CredentialManager credentialManager;
private static boolean oneTapStatus = false;public static void googleSignIn(String str) {credentialManager = CredentialManager.create(app);GetSignInWithGoogleOption signInWithGoogleOption = new GetSignInWithGoogleOption.Builder(app.getString(R.string.web_client_id)).build(); //这里是web client idGetCredentialRequest request = new GetCredentialRequest.Builder().addCredentialOption(signInWithGoogleOption).build();android.os.CancellationSignal cancellationSignal = new android.os.CancellationSignal();cancellationSignal.setOnCancelListener(() -> {if (oneTapStatus) oneTapStatus = false;showToast("Preparing credentials with Google was cancelled.");});credentialManager.getCredentialAsync(app,request,cancellationSignal,Executors.newSingleThreadExecutor(),new CredentialManagerCallback<GetCredentialResponse, GetCredentialException>() {@Overridepublic void onResult(GetCredentialResponse result) {handleGoogleSignIn(result);}@Overridepublic void onError(GetCredentialException e) {Log.e(TAG, "googleSignIn Error: " + e);}});}// Handle the successfully returned credential.public static void handleGoogleSignIn(GetCredentialResponse result) {Credential credential = result.getCredential();if (credential instanceof CustomCredential) {if (GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL.equals(credential.getType())) {// Use googleIdTokenCredential and extract id to validate and// authenticate on your serverGoogleIdTokenCredential googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.getData());String email = googleIdTokenCredential.getId();String idToken = googleIdTokenCredential.getIdToken();Log.d(TAG, "handleGoogleSignIn: " + email);app.nativeCallLoginWithGoogle(email, idToken);} else {// Catch any unrecognized custom credential type here.Log.e(TAG, "Unexpected type of credential");}} else {// Catch any unrecognized credential type here.Log.e(TAG, "Unexpected type of credential");}}public void nativeCallLoginWithGoogle(String email, String token){Log.d(TAG, "signIn token:" + token);Cocos2dxHelper.runOnGLThread(new Runnable() {@Overridepublic void run() {Cocos2dxJavascriptJavaBridge.evalString("cc.sdkMgr.googleSignIn(\""+email+"\",\""+token+"\")");}});}

这里的 token 是 JWT,可以直接解出来。JWT网站。

我这里把token放在JS里解析的,加了一个解析函数:

	getDataFromJWT(token) {try {//分割 Token 的三个部分const parts = token.split('.');if (parts.length !== 3) {throw new Error("Invalid JWT format");}//获取 Payload (Base64Url 部分)const payloadBase64Url = parts[1];//Base64Url 转 Base64let base64 = payloadBase64Url.replace(/-/g, '+').replace(/_/g, '/');//补全 Base64 末尾的 '='switch (base64.length % 4) {case 2: base64 += '=='; break;case 3: base64 += '='; break;}//解码 Base64 → 字符串const buffer = Buffer.from(base64, 'base64');let decodedPayload = buffer.toString('utf-8');//解析为 JSON 对象return JSON.parse(decodedPayload);} catch (error) {console.error("JWT 解析失败:", error);return null;}},}

解出来是这样的数据(其中sub 就是uid,email就是邮箱):

{"iss": "https://accounts.google.com","azp": "xxxxxxxxx.apps.googleusercontent.com","aud": "xxxxxxxxxx.apps.googleusercontent.com","sub": "11111111111","email": "222222222222222222@gmail.com","email_verified": true,"name": "ZZZZZZZZZZZZZZZZ","picture": "https://lh3.googleusercontent.com/ZZZZZZZZZZZZZZZZ","given_name": "ZZZZZZZZZZZZZZZZ","family_name": "ZZZZZZZZZZZZZZZZ","iat": 1752744039,"exp": 1752747639
}

我们这边由于是托管给 googlePlay 签名的,就导致本地调试登录会因为签名问题无法进行,只能上内部轨道。后来同事将develop的签名信息上传的google后台,这样就可以在本地用androidStudio进行调试了(具体是在后台添加了多个签名,还是用develop签名新建了一个测试项目我就不清楚)。
参考:Google Play 签名维护

升级API 35

参考链接:请教各位,2025年,如何打包符合google商店要求的apk?

在这里插入图片描述

1.下载新一些的androidStudio,下载链接,我选的版本是:Android Studio Meerkat Feature Drop | 2024.3.2 Patch 1

2.打开 Tools >> SDK Manager
SDK Platforms 下载 Android 15.0
SDK Tools 下载 35.0.0

3.升级gradle,使用的版本是:
在这里插入图片描述
gradle sync失败的话可以手动处理一下:Android Studio 手动下载Gradle配置的方法

4.在gradle.properties中升级API35相关的配置:(cocosCreator 可以在导出项目的时候先选择 api-35,其它不一样的再手动改)
在这里插入图片描述
5.新版的AndroidStudio 需要在build.gradle 中也要配置一下ndkVerison(注意要跟 local.properties 中的一致 )
在这里插入图片描述
6.如果还 编不过去的话,可以尝试升级ndk到r26,如果需要支持16KB内存页面,直接升级到r28。

16KB内存页面的支持

参考链接:cocos2.4系列,如何打包支持16KB对齐的安卓应用???

先说如何检测是否支持,官方文档里有说 :支持 16 KB 的页面大小,我使用的是mac,直接按照下面的方法:

使用 check_elf_alignment.sh 脚本(Linux 或 macOS) 请按照以下步骤使用
check_elf_alignment.sh 脚本检查 ELF 段的对齐情况:

将 check_elf_alignment.sh 脚本保存到文件中。

对应用的 APK 文件运行脚本:

check_elf_alignment.sh APK_NAME.apk
该脚本会针对所有 arm64-v8a 共享库输出 ALIGNED 或 UNALIGNED。

如果任何 arm64-v8a 或 x86_64 共享库是
UNALIGNED,您需要更新这些库的打包,然后重新编译应用,并按照本部分中的步骤重新测试。

其中 check_elf_alignment.sh脚本中的内容是:

#!/bin/bash
progname="${0##*/}"
progname="${progname%.sh}"# usage: check_elf_alignment.sh [path to *.so files|path to *.apk]cleanup_trap() {if [ -n "${tmp}" -a -d "${tmp}" ]; thenrm -rf ${tmp}fiexit $1
}usage() {echo "Host side script to check the ELF alignment of shared libraries."echo "Shared libraries are reported ALIGNED when their ELF regions are"echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED."echoecho "Usage: ${progname} [input-path|input-APK|input-APEX]"
}if [ ${#} -ne 1 ]; thenusageexit
ficase ${1} in--help | -h | -\?)usageexit;;*)dir="${1}";;
esacif ! [ -f "${dir}" -o -d "${dir}" ]; thenecho "Invalid file: ${dir}" >&2exit 1
fiif [[ "${dir}" == *.apk ]]; thentrap 'cleanup_trap' EXITechoecho "Recursively analyzing $dir"echoif { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; thenecho "=== APK zip-alignment ==="zipalign -v -c -P 16 4 "${dir}" | egrep 'lib/arm64-v8a|lib/x86_64|Verification'echo "========================="elseecho "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher."echo "  You can install the latest build-tools by running the below command"echo "  and updating your \$PATH:"echoecho "    sdkmanager \"build-tools;35.0.0-rc3\""fidir_filename=$(basename "${dir}")tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX")unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1dir="${tmp}"
fiif [[ "${dir}" == *.apex ]]; thentrap 'cleanup_trap' EXITechoecho "Recursively analyzing $dir"echodir_filename=$(basename "${dir}")tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX")deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; }dir="${tmp}"
fiRED="\e[31m"
GREEN="\e[32m"
ENDCOLOR="\e[0m"unaligned_libs=()echo
echo "=== ELF alignment ==="matches="$(find "${dir}" -type f)"
IFS=$'\n'
for match in $matches; do# We could recursively call this script or rewrite it to though.[[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}"[[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}"[[ $(file "${match}") == *"ELF"* ]] || continueres="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)"if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; thenecho -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"elseecho -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"unaligned_libs+=("${match}")fi
doneif [ ${#unaligned_libs[@]} -gt 0 ]; thenecho -e "${RED}Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}"
elif [ -n "${dir_filename}" ]; thenecho -e "ELF Verification Successful"
fi
echo "====================="

注意执行 脚本前需要搞一下环境:export PATH=/Users/loofnn/Library/Android/sdk/build-tools/35.0.0:$PATH
输出是这个样子的:

=== APK zip-alignment ===
4570074 lib/arm64-v8a/libcocos2djs.so (OK - compressed)
Verification succesful
============================ ELF alignment ===
/var/folders/4v/qgw2n0k93k33q9kbl3b6n_7c0000gn/T/app-release3_out_XXXXX.gxZM5X8KG7/lib/armeabi-v7a/libcocos2djs.so: \e[31mUNALIGNED\e[0m (2**12)
/var/folders/4v/qgw2n0k93k33q9kbl3b6n_7c0000gn/T/app-release3_out_XXXXX.gxZM5X8KG7/lib/arm64-v8a/libcocos2djs.so: \e[32mALIGNED\e[0m (2**14)

需要关注的是 arm64 和 x86_64 的括号内输出。如果是(2**12)就是要升级。(上边的输出是我升级之后的)。

升级16KB这个非常简单,按照网友说的 升级 NDK 到 r28就可以了。

如何升级ndk: 打开 Tools >> SDK Manager,SDK Tools 下载 NDK 28.1.13356709

如果帮到你的话,点个赞赞吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/93898.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/93898.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

unity avpro实现互动影游关键问题

创建视频播放器​在Hierarchy面板中右键创建&#xff1a;Video > AVPro Video - MediaPlayer创建后会生成一个MediaPlayer对象&#xff0c;用于控制视频播放添加视频资源将视频文件放入项目的StreamingAssets文件夹下在MediaPlayer组件的设置中选择要播放的视频文件在UI上显…

【C找第一个只出现一次的字符】2022-8-18

缘由样例通过&#xff0c;请问为什么错了呢&#xff1f;(语言-c语言)-编程语言-CSDN问答 char str[100000];fgets(str, 100000, stdin);int a[26]{}, i, count 0;int len strlen(str);for (i 0; i<len; i) a[str[i] - a];for (i 0; i<len; i){if (a[str[i] - a] 1){…

MCP AI应用通信的底层机制

技术小馆专注AI与Java领域的前沿技术知识库 技术小馆官网 在AI应用快速发展的今天&#xff0c;不同AI系统之间的高效通信成为技术架构的关键挑战。MCP&#xff08;Model Context Protocol&#xff09;作为新一代AI应用通信协议&#xff0c;正在重新定义AI工具生态的构建方式。…

UI测试平台TestComplete如何实现从Git到Jenkins的持续测试

还在为手动做UI测试又慢又累发愁&#xff1f;更头痛的是&#xff0c;代码改完还得等半天才能测&#xff0c;测完了结果又散得到处都是&#xff0c;根本看不清质量全貌?TestComplete帮你搞定&#xff1a;直接连上你的Git仓库&#xff0c;代码一有动静就能感知。接着&#xff0c…

【Debian】4-‌2 Gitea搭建

【Debian】4-‌2 Gitea搭建一、准备工作二、创建 Gitea 用户&#xff08;推荐&#xff09;三、下载并安装 Gitea四、配置Gitea4-1 创建目录结构4-2 创建配置目录五、配置 Systemd 服务六、访问 Gitea Web 界面七、小插曲一、准备工作 更新系统软件为最新 sudo apt update &am…

【CDH × Docker】一次测试部署,N 次复用的环境镜像方案

&#x1f680; 一次测试环境的探索&#xff1a;我如何将 CDH 集群打包成 Docker 镜像&#xff0c;留给未来的自己 &#x1f9e9; 背景故事 最近在项目中&#xff0c;我们计划上线一个基于 CDH&#xff08;Cloudera Distribution Hadoop&#xff09; 的大数据平台。正式上生产环…

Java 日期时间格式化模式说明

Java 中日期时间格式化使用特定的模式字符串来定义输出格式。以下是常见的格式化符号及其含义&#xff0c;适用于 SimpleDateFormat 和 DateTimeFormatter一、日期部分格式化符号符号含义示例y年 (Year)yyyy → 2023M月 (Month)MM → 09, MMM → Sep, MMMM → Septemberd月中的…

代码随想录算法训练营三十三天|动态规划part06

LeetCode 322 零钱兑换 题目链接&#xff1a;322. 零钱兑换 - 力扣&#xff08;LeetCode&#xff09; 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。…

【大模型LLM】大模型训练加速 - 梯度累积(Gradient Accumulation)原理详解

梯度累积&#xff08;Gradient Accumulation&#xff09;原理详解 梯度累积是一种在深度学习训练中常用的技术&#xff0c;特别适用于显存有限但希望使用较大批量大小&#xff08;batch size&#xff09;的情况。通过梯度累积&#xff0c;可以在不增加单个批次大小的情况下模拟…

【数据分享】各省文旅融合耦合协调度及原始数据(2012-2022)

数据介绍引言 文旅融合是推动区域经济高质量发展、促进共同富裕的重要路径。党的二十大报告明确提出“推进文化和旅游深度融合发展”的战略目标&#xff0c;文旅产业通过资源整合与业态创新&#xff0c;可显著缩小城乡、区域差距&#xff0c;提升物质与精神双重福祉&#xff08…

Linux编程: 10、线程池与初识网络编程

今天我计划通过一个小型项目&#xff0c;系统讲解线程池与网络编程的核心原理及实践。项目将围绕 “利用线程池实现高并发网络通信” 这一核心需求展开&#xff0c;具体设计如下&#xff1a; 为保证线程安全&#xff0c;线程池采用单例模式设计&#xff0c;确保全局唯一实例避…

藏云阁 Logo 库(开源项目SVG/PNG高清Logo)

在日常技术方案设计、架构图绘制或PPT制作中&#xff0c;常常会遇到一些问题&#xff0c;比如&#xff1a; 找不到统一风格的开源项目组件图标&#xff0c;PPT中的logo五花八门下载的图标分辨率不足&#xff0c;放大后模糊失真不同来源的图标颜色风格冲突&#xff0c;破坏整体…

从0开始学习R语言--Day64--决策树回归

对于没有特征或者说需要寻找另类关系的数据集&#xff0c;我们通常会用聚合或KNN近邻的方法来分类&#xff0c;但这样的分类或许在结果上是好的&#xff0c;但是解释性并不好&#xff0c;有时候我们甚至能看到好的结果反直觉&#xff1b;而决策树回归做出的结果&#xff0c;由于…

B+树高效实现与优化技巧

B树的定义 一颗M阶B树T,满足以下条件 每个结点至多拥有M课子树 根结点至少拥有两颗子树 除了根结点以外,其余每个分支结点至少拥有M/2课子树 所有的叶结点都在同一层上 有k棵子树的分支结点则存在k-1个关键字,关键字按照递增顺序进行排序 关键字数量满足 ceil( M/2 ) - 1 &…

Android 基础入门学习目录(持续更新)

四大组件 Activity&#xff1a; Service&#xff1a; BroadcastReceiver&#xff1a; ContentProvider&#xff1a; UI 与交互开发 常见的UI布局和UI控件 样式与主题 Fragment Intent 数据存储 自定义View和自定义Group 自定义View 自定义ViewGroup 事件分发 Key…

Linux移动大量文件命令

背景 使用 mv 命令报“/bin/mv: 参数列表过长”&#xff0c;也是第一遇到&#xff0c;查了一下&#xff0c;最后用rsync命令解决了。还好每台服务器&#xff0c;都必装rsync了&#xff0c;记录如下。 命令 nohup rsync -av --remove-source-files --progress /public/tmp/video…

SQL中的HAVING用法

HAVING 是 SQL 中专门对 “分组之后的聚合结果” 再做筛选的子句。 它一般跟在 GROUP BY 后面&#xff0c;不能单独使用&#xff0c;作用类似于分组版的 WHERE。✅ 1. 语法位置 SELECT 列1, 聚合函数(列2) AS 别名 FROM 表 GROUP BY 列1 HAVING 聚合条件; -- 这里写对聚合…

【Halcon 】Halcon 实战:如何为 XLD 模板添加极性信息以提升匹配精度?

Halcon 实战&#xff1a;如何为 XLD 模板添加极性信息以提升匹配精度&#xff1f; 在使用 Halcon 进行模板匹配时&#xff0c;我们通常有两种方式创建模板&#xff1a; 基于图像灰度&#xff08;CreateScaledShapeModel&#xff09;基于轮廓 XLD&#xff08;CreateScaledShapeM…

grafana/lock-stack 日志 Pipeline 配置

前言 本文使用的是 grafana/loki-stack chart 抓取的 k8s 日志。其他 chart 配置都差不多。 日志问题 docker 容器运行时 pod 内原始日志 [cpu-4] Hello, 第 9788 次报时&#xff0c;时间&#xff1a;2025-08-01T06:35:420000 {"HOSTNAME":"cpu-4",&qu…

appium2.0+之PointerActions详解

以下内容在 夜神模拟器 上进行。 一、应用场景 一些针对手势的操作&#xff0c;比如滑动、长按、拖动等。可以将这些基本手势组合成一个相对复杂的手势。 二、使用步骤创建触摸输入设备&#xff08;模拟手指操作&#xff09; touch_input PointerInput(interaction.POINTER_TO…