環境:我這里是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
如果幫到你的話,點個贊贊吧!