7.3 KiB
长安语言刷入工具 (Changan Language Flashing Tool)
Overview
A Windows GUI tool suite (Python 3.6+ / tkinter) for flashing multi-language APKs onto Android-based vehicle infotainment systems. Built by 宜宾科宜科技有限公司.
The suite contains 5 tool variants, each targeting a different vehicle model. All share the same ADKAPKGUI class architecture with model-specific customizations. Authorization is VIN-based via a cloud API.
| Tool file | Vehicle | Window title | Pack script |
|---|---|---|---|
app.py |
启源Q07 | 长安语言安装工具 | pack_q07.bat |
S05.py |
深蓝S05 | 深蓝S05多语言安装 | pack_s05.bat |
X5plusTool.py |
X5plus | 适用于X5plus多语言安装 | pack_x5plus.bat |
app-install.py |
长安逸动 (通用) | 长安语言刷入工具 | pack_common.bat |
app-yidong.py |
长安逸动 | 长安逸动语言刷入工具 | pack_yidong.bat |
Project structure
├── app.py # 启源Q07 tool
├── S05.py # 深蓝S05 tool
├── X5plusTool.py # X5plus tool
├── app-install.py # 逸动通用 tool
├── app-yidong.py # 逸动 tool
├── pack_q07.bat # Q07 pack script
├── pack_s05.bat # S05 pack script
├── pack_x5plus.bat # X5plus pack script
├── pack_common.bat # 逸动通用 pack script
├── pack_yidong.bat # 逸动 pack script
├── test_extract.py # Standalone test for package.bin extraction
├── app.ico # Application icon
├── package.bin # Encrypted ZIP (not in repo)
├── adb.exe # Bundled ADB
├── AdbWinApi.dll # ADB dependency
├── AdbWinUsbApi.dll # ADB dependency
└── .vscode/
└── settings.json
Architecture
Single-file design
Each tool is a single Python file under the ADKAPKGUI class. No MVC separation — the class handles GUI, business logic, ADB operations, network calls, and file extraction.
Threading model
- Main thread: tkinter event loop (
root.mainloop()) - Background threads: All user-triggered operations spawn
threading.Thread(target=..., daemon=True) - Thread-safety: UI mutations via
self.run_on_ui_thread(func, ...)→self.root.after(0, func, ...). Internal_implmethods are the actual tkinter-touching implementations.
ADB operations
run_adb_command(command)— standard ADB commands; auto-substitutesadbwith bundledadb.exepath when frozenrun_adb_shell(shell_command)— only in app-install.py / app-yidong.py; shells into device with auto-passwordadb36987
ADB path is portable: self.adb resolves to sys._MEIPASS/adb.exe when frozen (PyInstaller bundle), or 'adb' in development.
Authentication flow
- ADB detects device → reads VIN (
ca_vin_infoorVIN; 逸动 usesca.car.vin) - VIN sent to
https://api.changan.softwindy.cn/api/authorizations/auth-check?vin=... - Package password from
https://api.changan.softwindy.cn/api/authorizations/package-key?vin=... - Password used to decrypt
package.bin
Package extraction
package.binis a password-protected ZIP (AES via pyzipper, fallback to zipfile)- Extracted to
%LOCALAPPDATA%\.cache\system\.android\apps_cache_{variant}(hidden viaattrib +h) - Each tool has its own cache folder to avoid conflicts:
- app.py →
apps_cache_Q07 - S05.py →
apps_cache_S05 - X5plusTool.py →
apps_cache_X5plus - app-install.py →
apps_cache_common - app-yidong.py →
apps_cache_common(default)
- app.py →
- Extracted APKs in
app/pushed to/system/app/,priv-app/to/system/priv-app/
Device status monitoring
Background daemon thread runs adb devices every 5 seconds to detect connect/disconnect events.
GUI layout (650x640 dark theme for most; 650x550 for 逸动)
| Section | Contents |
|---|---|
| Title bar | Vehicle model + company subtitle |
| Password query | Hidden VIN→password lookup (S05, app-install only) |
| Button row 1 | 获取权限 (Q07/S05), 刷入语言包, 安装App, 语言设置 |
| Button row 2 | 时区设置, 安卓设置, 重启设备, 禁用升级 |
| Status bar | Connection dot, VIN, Auth status, Refresh button |
| Tips | Usage warnings |
| Progress | Extraction + push progress (hidden by default) |
| Log area | ScrolledText with tags (INFO/SUCCESS/ERROR/WARNING/CMD), 清空日志 button in title bar |
Key features
Install App (unified single/batch)
"安装App" button uses filedialog.askopenfilenames for multi-file selection, replacing old separate "单个安装" and "批量安装" buttons. Select 1 or more APKs and installs all in one pass (adb install -r).
Debug mode (hidden)
Press Ctrl+Shift+D → password zxch5200 to enter debug mode:
- Bypasses device connection and authorization checks (UI shows "已连接" / "已授权")
- Logs all raw ADB commands and output to the log panel
- Exiting debug mode auto-refreshes real device state
Language quick-set
Popup with 8 one-click locale switches (zh-CN, en-US, ru-RU, fr-FR, es-ES, pt-BR, it-IT, ar-SA). Also links to native Android language settings. Changes take effect after reboot.
Model-specific behaviors
| Feature | Q07 (app.py) | S05 (S05.py) | X5plus (X5plusTool.py) | 逸动 (app-install/yidong) |
|---|---|---|---|---|
| Root perm | Y | Y | N (no btn_root) | N |
| priv-app | Y | Y | Y | N (app only) |
| ADB shell | Standard | Standard | Standard | Auto-password adb36987 |
| VIN key | ca_vin_info/VIN | ca_vin_info/VIN | ca_vin_info/VIN | ca.car.vin |
| Old app cleanup | N | N | Y (5 packages) | N |
| Font push | N | N | Y (FZLTHPro) | N |
| Overlay enable | N | N | N | N (removed) |
| Password query | N | Y | N | Y |
| Factory hints | N | Y | Y (dynamic pwd) | Y |
Build process
Each pack_*.bat follows the same pipeline:
- Install deps:
pyinstaller,cython,pyzipper - Clean old build dirs
- Cython compile:
{source}.py→_core.pyd - Copy resources:
adb.exe, DLLs,app.ico - PyInstaller: single
.exewith--uac-admin, bundling_core.pyd+ ADB + DLLs - Fallback to normal PyInstaller if Cython fails
Output exe is self-contained — bundles adb.exe and DLLs via sys._MEIPASS, no external ADB needed.
Key behaviors to preserve
- Thread safety: Never call tkinter from background threads — always use
run_on_ui_thread - VIN-based auth: Authorization required before push; flow must remain intact
- Silent extraction: Auto-extract
package.binwithout user step - ADB portability:
self.adbresolves to bundled exe path; all commands go throughrun_adb_command - vecentek.model: Set to 1 before install, 0 after
- Chinese encoding:
# -*- coding: utf-8 -*-throughout - Debug mode:
self.debug_modeflag gates auth/connection bypass and verbose logging - Separate cache dirs: Each tool extracts to its own cache folder
Known issues
test_extract.pyhardcodes password — should fetch from APIon_disable_upgradeusesfindstr(Windows-specific)- Exception handling is minimal in many places (bare
except: pass) - 逸动 tools (app-install/yidong) use
subprocess.Popenwith stdin password injection — fragile