Site icon May's Notes

React Native 打包 Android APP 發布到 Play Store 測試與上架

React Native logo

這是我在2023第十五屆 iThome 鐵人賽發表的系列文章。https://ithelp.ithome.com.tw/users/20136637/ironman/6408

本篇會分享從生成 APK/AAB、設置應用、測試應用到上架 Play Store 的過程。

  1. Android 要求所有應用都必須使用憑證進行數位簽署,才能安裝到裝置上或進行更新。
  2. 自 2021 年 8 月起,Google Play 上的新應用程式都必須以 .AAB (Android App Bundle) 檔案格式發布。

生成 Keystore

Keystore 憑證用於保存加密的金鑰。為驗證開發者身份,應用需要使用 keystore 進行數位簽署。只有擁有憑證私鑰的人才能創建、更新應用,所以必須好好保存。

注意:如果丟失上架應用的 keystore 密碼、私鑰的相關信息,那原本的應用就無法繼續更新,只能創建新的應用或者向 google 申請換成新的 key。

  1. 使用 keytool 指令產生金鑰組:keytool -genkeypair -v -storetype PKCS12 -keystore ${KEY_NAME}.keystore -alias ${KEY_ALIAS} -keyalg RSA -keysize 2048 -validity 10000 例如:keytool -genkeypair -v -storetype PKCS12 -keystore pokedex.keystore -alias pokedex -keyalg RSA -keysize 2048 -validity 10000
    • keytool: Java 中用於管理金鑰和憑證的命令工具
    • -genkeypair: 生成一個金鑰組,即公鑰和私鑰
    • -storetype PKCS12: 金鑰的類型為 PKCS12
    • -keystore {KEY_NAME.keystore}: 金鑰檔案名稱為 ${KEY_NAME}.keystore
    • -alias {KEY_ALIAS}: keystore 的別名為 ${KEY_ALIAS}
    • -keyalg RSA: 指定產生金鑰組使用 RSA 演算法為
    • -keysize 2048: 指定產生的每一個金鑰的大小為2048位元,金鑰大小至少為 112 位元,建議設為 2048 位元。
    • -validity 10000: 生成的憑證有效期為 10000 天,即憑證將在 10000 天後過期
  2. 接著會要求你輸入 keystore 的密碼,以及一些發行相關的資訊。
    • 發行相關資訊可以都不填直接按下 Enter 跳過

      完成後會生成 <KEY_NAME>.keystore 在輸入指令的路徑:

注意:記得將 .keystore 加進 .gitignore 中,不要上傳。

設置 Gradle 變數

1.把 <KEYSTORE_NAME>.keystore 放到 android/app 下。

2.在 /android 底下新增 keystore.properties 將 keystore 變數存在裡面:

STORE_FILE=KEYSTORE_NAME.keystore
KEY_ALIAS=KEYSTORE_ALIAS
STORE_PASSWORD=******
KEY_PASSWORD=******

STORE_PASSWORD 就是剛剛生成密鑰對時輸入的密碼,KEY_PASSWORD 會和 STORE_PASSWORD 一樣。

注意:記得將 keystore.properties 加進 .gitignore

把簽署配置添加到 gradle 中

在 android/app/build.gradle 添加以下內容:

// android/app/build.gradle
...
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('keystore.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

android {
    ...
    defaultConfig { ... }
    signingConfigs {
        ...
        release {
            if (keystoreProperties['STORE_FILE']) {
                storeFile file(keystoreProperties['STORE_FILE'])
                storePassword keystoreProperties['STORE_PASSWORD']
                keyAlias keystoreProperties['KEY_ALIAS']
                keyPassword keystoreProperties['KEY_PASSWORD']
            }
        }
    }
    buildTypes {
        release {
            ...
            signingConfig signingConfigs.release
        }
    }
}
...

Expo

https://docs.expo.dev/app-signing/app-credentials

只需要將 .jks 或者 .p12 上傳到 Expo project 的 credentials 中,Expo 會自動執行 Android 和 iOS 應用程式的簽署過程。

Project – Credentials – Get Started (或 +Application Identifier)

你需要提供:

設置應用版本

記得修改應用的版本號 versionName, versionCode,上傳到 Play Store 不能有重複的 versionCode,每一次上傳新版本記得都要將 versionCode + 1

android/app/build.gradle

android {
	...
	defaultConfig {
		...
		versionCode 1
		versionName "1.0.0"
	}
}

應用上架前的準備工作: https://ithelp.ithome.com.tw/articles/10329076

生成 APK 或 AAB

使用以下指令開始打包:

APK

cd android && ./gradlew assembleRelease && cd ..

AAB

cd android && ./gradlew bundleRelease && cd ..

Trouble Shooting

有時候打包發生未知的錯誤可以 ./gradlew clean 清除 build 資料夾後再重新打包

Gradle version

如果打包時出現下面這個錯誤就代表 java 版本和 gradle 的不適配

* What went wrong:<br>Could not open settings generic class cache for settings file '/android/settings.gradle' (Users/.gradle/caches/8.0.1/scripts/xxxxxxxxx).<br>> BUG! exception in phase 'semantic analysis' in source unit '_BuildScript_' Unsupported class file major version 64

官方有提供 gradle 和 java 版本對應表

https://docs.gradle.org/current/userguide/compatibility.html#java

像我是 java 20 就應該對應 gradle 8.1,所以我使用 8.0.1 會因為版本過低而失敗。

因此將 android/gradle/wrapper/gradle-wrapper.properties 的 distributionUrl 改成 8.1 的連結即可

distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-all.zip

查看 gradle 版本: https://services.gradle.org/distributions/

compileReleaseJavaWithJavac

Execution failed for task ':app:compileReleaseJavaWithJavac'.

我自己遇到這個 error 是因為 AndroidManifest.xml 的 package 與 build.gradle 中的 applicationId 不一致,改成一致之後就解決了。

測試應用

在把 release 版本的 AAB 提交到 Play Store 之前,你可以先測試一下應用是否能正常使用:

npx react-native run-android --variant=release

注意:

  1. --variant=release 只能在你完成了上面的簽署配置之後才可以使用。
  2. 在 debug 和 release 版本間來回切換安裝時可能會導致簽署不匹配,需要先卸載前一個版本再安裝一次。

註冊 Play Console 帳戶

如要建立 play console 帳戶需要 $25 USD 的註冊費 (僅須支付一次)。

在 Play Console 建立 developer 帳戶,選擇帳戶類型:

後面步驟按照提示走即可,註冊完需要上傳證件照片驗證身份後才能發布應用(包括內部測試

可以接受駕照、護照、身分證、居留證

驗證的過程大概需要 1~2 個工作日,我自己是等了 1 天。

設置應用相關資料

在上架之前可以先進行內部測試,內部測試不需要通過 Google 審核,並且可以將應用分享給 100 位內部測試人員,藉此找出問題並在初期取得意見回饋。

首先建立一個新的應用程式

資訊主頁

就算只是要在內部測試還是得把一系列設定全部設定完,這邊我就不一張一張截圖要不然實在是太多了…各位按照步驟一步一步來吧

如果需要隱私權政策 URL,可以直接使用工具生成:https://app.privacypolicies.com/

設置應用商店資料:

這些圖像是必傳的:

建立新版本

左側菜單找到「內部測試」點擊「選取測試人員」:

將要測試的 email 添加進測試名單,多個 Email 之間用逗號, 隔開,然後記得按 Enter 新增:

選取好測試的人員之後按下「儲存

接著「建立新版本

點擊「選擇簽署金鑰

這邊我建議是使用 Google 產生的金鑰

上傳 AAB 以及填寫版本資料:

在這邊你能看到與版本相關的錯誤、警告,如果有錯誤的話必須先解決。

內部測試應用

一切設置完成之後在 設定 – 內部應用程式分享 將管理測試人員選為「限制存取電子郵件名單」,然後選擇下載者的清單:

如果你的應用需要登入後才能使用部分功能,需要在「測試 – 正式發布前測試報告 – 設定」中設置「提供測試帳戶憑證

還有設置 deep link, 多語系

接著回到 內部測試 – 測試人數 下面有一個「複製連結」的按鈕,這個連結就是下載內部應用程式的連結,會導向 Play Store 下載內部測試應用:

刪除 APP bundle 版本

如果想刪除錯誤或不用的 app bundle 版本可以在「應用程式套件探索工具」找到要刪除的版本右側點進去

右側有一個「刪除 app bundle」,刪除即可

上架應用至 Play Store

所有測試和設置都完成後,上架 Play Store 只缺需要提交正式版本以及提交送審即可。

測試 – 正式發布前測試報告 – 詳細資訊 這邊可以看到應用測試的結果,分穩定性、成效、無障礙、螢幕截圖、安全性,Google 會為你的應用在不同設備上進行測試並提供相關建議,你可以調整後再上架應用。

發布總覽 – 將 N 項變更送審 即可提交應用審核,審核通過後應用就會上架 Play Store,第一次送審的時間最長約 7 天,後續送審就不需要這麼久了。

參考資料

Exit mobile version