Files
Password-Manager/android-client/repack-apk.ps1
T
r-zakarya 719522df92 fix(android): aapt refusait le paquet a cause de cinq doublons
Le deploiement de Delphi depose a la racine de res\ une copie a plat de
cinq de ses ressources - ic_launcher_*, splash_* - alors que les vraies
sont dans res\drawable\. Or aapt n'accepte que des DOSSIERS a cette
racine : il refusait le paquet entier, "invalid resource directory name",
une fois par fichier.

On les retire avant l'appel, et rien n'est perdu : ce sont des doublons,
verifies presents dans drawable.

Ne se voyait pas en debogage, ou l'arbre traine depuis longtemps. C'est
la premiere release qui l'a montre, comme le dossier de mise en scene
absent juste avant.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 00:41:05 +01:00

101 lines
5.3 KiB
PowerShell

# Refait les trois dernieres etapes de l'empaquetage Android, sur le dossier
# deja prepare - sans le vider au prealable.
#
# POURQUOI : la cible Deploy de MSBuild reconstruit library\lib avant d'appeler
# aapt, ce qui efface toute bibliotheque native ajoutee a la main. Or ce projet
# n'a pas d'entrees de deploiement fonctionnelles (voir README), donc nos icones
# ne peuvent y arriver autrement. On laisse Deploy faire son travail, puis on
# remet ce qu'il a efface et on refait aapt / zipalign / signature.
#
# A lancer depuis la racine du depot, apres un Deploy reussi.
#
# -Config Release empaquette la sortie Release au lieu de Debug
# -Keystore <chemin> -Alias signe avec CETTE cle au lieu de celle de debogage
#
# LE MOT DE PASSE NE PASSE PAS PAR LA LIGNE DE COMMANDE. paclient --apksign
# l'y met en clair, ou n'importe quel processus de la machine peut le lire.
# apksigner sait lire une variable d'environnement ; on l'appelle donc en
# direct pour une vraie cle, et on ne garde paclient que pour la cle de
# debogage, dont le mot de passe est public et vaut "android".
param(
[ValidateSet('Debug', 'Release')] [string]$Config = 'Debug',
[string]$Keystore,
[string]$Alias
)
$ErrorActionPreference = 'Stop'
$sdk = 'C:\Users\Public\Documents\Embarcadero\Studio\23.0\CatalogRepository\AndroidSDK-2525-23.0.51511.6924'
$bds = 'C:\Program Files (x86)\Embarcadero\Studio\23.0'
$jdk = 'C:\Program Files\Eclipse Adoptium\jdk-11.0.15.10-hotspot'
$pac = "$bds\bin\paclient.exe"
$p = ".\Android64\$Config\pmserverApk"
# 1. Nos icones par-dessus celles de Delphi :
# les proprietes Android_LauncherIcon* et Android_AdaptiveIcon* du .dproj
# devraient suffire, mais rien ne les deploie ici.
Copy-Item "$PSScriptRoot\android-res\*" "$p\res\" -Recurse -Force
# 1 ter. L'ecran de demarrage existe en plusieurs variantes de densite et de
# theme, toutes identiques chez nous. Une seule source, recopiee : quatre
# fichiers identiques dans le depot finiraient par diverger.
$splash = "$p\res\drawable\splash_vector.xml"
foreach ($v in 'drawable-anydpi-v31', 'drawable-night-anydpi-v21', 'drawable-night-anydpi-v31') {
if (Test-Path "$p\res\$v") { Copy-Item $splash "$p\res\$v\splash_vector.xml" -Force }
}
if (Test-Path "$p\res\drawable-anydpi-v21") {
Copy-Item "$p\res\drawable\splash_image_def.xml" "$p\res\drawable-anydpi-v21\splash_image_def.xml" -Force
}
# Le fond sombre vaut aussi en theme clair : l'application n'a qu'un theme.
if (Test-Path "$p\res\values-night-v21") {
Copy-Item "$PSScriptRoot\android-res\values\colors.xml" "$p\res\values-night-v21\colors.xml" -Force
}
# 1 quater. AAPT N'ACCEPTE QUE DES DOSSIERS A LA RACINE DE res\.
#
# Le deploiement de Delphi y depose aussi une copie a plat de cinq de ses
# ressources - ic_launcher_*, splash_* - alors que les vraies sont dans
# res\drawable\. aapt refuse alors le paquet entier : "invalid resource
# directory name", une fois par fichier. On les retire, et rien n'est perdu :
# ce sont des doublons, verifies presents dans drawable.
#
# Ne se voyait pas en debogage, ou l'arbre traine depuis longtemps et ou ces
# fichiers n'y avaient jamais ete deposes. C'est la premiere release qui l'a
# montre, comme le dossier de mise en scene absent juste avant.
Get-ChildItem "$p\res" -File -ErrorAction SilentlyContinue | Remove-Item -Force
# 2. aapt : reconstruit l'archive non alignee depuis library, classes, res.
& $pac -u8 --aaptpackage="$sdk\build-tools\33.0.2\Aapt.exe,$p\library,$p\classes,$p\res,$p\assets,$p\AndroidManifest.xml,$sdk\platforms\android-33\android.jar,$p\bin\pmserverApk-unaligned.apk"
if ($LASTEXITCODE -ne 0) { throw "aapt a echoue" }
# 3. zipalign refuse d'ecraser sa sortie : l'APK precedent doit disparaitre.
Remove-Item "$p\bin\pmserverApk.apk" -Force -ErrorAction SilentlyContinue
& $pac -u8 --zipalign="$sdk\build-tools\33.0.2\ZipAlign.exe,$p\bin\pmserverApk-unaligned.apk,$p\bin\pmserverApk.apk,4"
if ($LASTEXITCODE -ne 0) { throw "zipalign a echoue" }
if ($Keystore) {
# LA CLE DE L'UTILISATEUR. Le mot de passe arrive par PM_KS_PASS, pose par
# l'appelant juste avant et retire juste apres : il ne figure ni dans le
# depot, ni dans le .dproj, ni dans une ligne de commande.
if (-not $env:PM_KS_PASS) { throw 'PM_KS_PASS absent - mot de passe du magasin' }
& "$jdk\bin\java.exe" -jar "$sdk\build-tools\33.0.2\lib\apksigner.jar" sign `
--ks "$Keystore" --ks-key-alias "$Alias" `
--ks-pass env:PM_KS_PASS --key-pass env:PM_KS_PASS `
"$p\bin\pmserverApk.apk"
if ($LASTEXITCODE -ne 0) { throw "signature echouee" }
# DIRE AVEC QUOI ON A SIGNE. Une release signee par megarde avec la cle de
# debogage s'installe et fonctionne : rien ne la distingue a l'usage, et on
# ne s'en apercoit qu'au refus de la premiere mise a jour.
& "$jdk\bin\java.exe" -jar "$sdk\build-tools\33.0.2\lib\apksigner.jar" `
verify --print-certs "$p\bin\pmserverApk.apk" |
Select-String -Pattern 'Signer #1 certificate DN|SHA-256 digest' |
ForEach-Object { $_.Line.Trim() }
} else {
& $pac -u8 --apksign="$jdk\bin\java.exe,$sdk\build-tools\33.0.2\lib\apksigner.jar,$p\bin\pmserverApk.apk,androiddebugkey,$env:APPDATA\Embarcadero\BDS\23.0\debug.keystore,android,android"
if ($LASTEXITCODE -ne 0) { throw "signature echouee" }
}
$apk = Get-Item "$p\bin\pmserverApk.apk"
"APK {0:N1} Mo" -f ($apk.Length / 1MB)