Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions website/docs/quickstart/Avalonia Android cookbook.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
---
sidebar_position: 4
title: Avalonia Android 更新入门
title: Avalonia Android 实战手册
---

# GeneralUpdate.Avalonia.Android 快速入门
# GeneralUpdate.Avalonia.Android 实战手册

这篇手册面向需要在 Avalonia 应用中集成 Android APK 自动更新的开发者。目标是用最少的代码跑通"检查更新 → 下载 APK → 校验 SHA256 → 启动安装器"的完整流程。

<iframe
src="//player.bilibili.com/player.html?bvid=BV1HtJF6XET3&page=1"
width="100%"
height="480"
style={{ borderRadius: '8px', border: 'none' }}
allowFullScreen
scrolling="no"
/>

:::info 前置知识
这篇手册假设你已经有一个 Avalonia 项目并配置好了 Android 目标框架。如果你还没有 Avalonia Android 项目,请先参考 [Avalonia 官方文档](https://docs.avaloniaui.net/) 创建。
:::
Expand Down
64 changes: 57 additions & 7 deletions website/docs/quickstart/GeneralUpdate.PacketTool.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ dotnet run --project GeneralUpdate.Tools.csproj

前往 [GeneralUpdate.Tools Releases](https://github.com/GeneralLibrary/GeneralUpdate.Tools/releases) 下载对应平台的可执行文件,直接运行即可。

> Simulation 模块内部会调用 `dotnet publish` 构建测试应用,因此使用仿真功能时必须安装 .NET SDK仅运行 Patch / Extension / OSS / Config 模块则不需要
> Simulation 模块内部会调用 `dotnet publish` 构建测试应用,因此使用仿真功能时必须安装 .NET SDK。Mobile 模块的项目模式(Build & Locate)也会调用 `dotnet publish`,同样需要 .NET SDK。仅运行 Patch / Extension / OSS / Config 模块以及 Mobile 的文件模式则不需要

## 七个模块速览

Expand Down Expand Up @@ -332,6 +332,15 @@ Generate Sample 额外输出:

如果你使用 `GeneralUpdate.Avalonia.Android` 或 `GeneralUpdate.Maui.Android` 组件为 Android 应用提供自动更新能力,每次发布新版本时都需要获取 APK/AAB 文件的元数据(包名、版本号、SHA256 哈希、文件大小),并将其上传到服务端进行版本管理。Mobile 模块把"解析 → 打包 → 上传 → 生成版本记录"这四步收敛到一个界面中。

<iframe
src="//player.bilibili.com/player.html?bvid=BV1ctJF6XEJs&page=1"
width="100%"
height="480"
style={{ borderRadius: '8px', border: 'none' }}
allowFullScreen
scrolling="no"
/>

支持两种工作模式:

- **文件模式**:直接选择 APK 或 AAB 文件,自动解析 AndroidManifest.xml 提取元数据
Expand Down Expand Up @@ -373,12 +382,48 @@ Generate Sample 额外输出:
### 工具内部做了什么

1. **格式检测**:通过文件扩展名(`.apk` / `.aab`)和 ZIP 内部结构(`AndroidManifest.xml` 位置)自动识别包格式。
2. **元数据解析**:使用 `AxmlParser` 从 ZIP 中读取二进制的 `AndroidManifest.xml`,提取 `package`、`versionName`、`versionCode`。
3. **SHA256 计算**:对完整文件计算 SHA256 哈希值。
4. **文件大小**:读取文件长度并格式化为人类可读的显示(KB/MB/GB)。
5. **项目构建**(仅项目模式):调用 `dotnet publish -c Release -o {publishDir}`,自动定位输出的 APK/AAB 文件。
6. **上传**:通过 HTTP multipart/form-data 将文件和表单字段(Name、Version、Hash、Format、Size、Platform、ProductId、IsForcibly)上传到服务端。
7. **版本记录导出**:上传成功后生成 `mobile_version_{timestamp}.json`,包含完整的版本元数据。
- APK 检测:打开 ZIP 文件,检查根目录是否存在 `AndroidManifest.xml`。
- AAB 检测:打开 ZIP 文件,检查是否存在 `base/manifest/AndroidManifest.xml`。
- 格式未知时(不是 .apk 也不是 .aab)会直接返回 Unknown。

2. **元数据解析**:使用 `AxmlParser` 解析二进制的 AXML(Android Binary XML)格式,从 ZIP 中读取 `AndroidManifest.xml`。解析流程如下:
- **字符串池提取**:读取 AXML 文件的 Chunk 头,找到类型为 `0x0001` 的 StringPool Chunk,从中解析出所有 UTF-16LE 编码的字符串数组。
- **属性值提取**:遍历 XML 的 Start Element Chunk(类型 `0x0102`),解析属性块(每个属性 20 字节),通过属性名在字符串池中的索引匹配 `package` 和 `versionName`,再通过 `rawValueIndex` 从字符串池中取出属性值。
- **versionCode 提取**:versionCode 存储为整型属性(类型 `0x10` = INT_DEC 或 `0x11` = INT_HEX),直接从属性的 `typedValueData` 字段(偏移 +16,4 字节)读取有符号整数。
- AXML 结构与参考:https://justanapplication.wordpress.com/category/android/android-binary-xml/

3. **SHA256 计算**:对完整文件计算 SHA256 哈希值,输出小写十六进制字符串。

4. **文件大小**:读取文件长度并格式化为人类可读的显示(B / KB / MB / GB)。

5. **项目构建**(仅项目模式):选择 `.csproj` 后会触发:
- `MobileCsprojParser.Parse()` 解析 `.csproj` 的 XML,提取 `TargetFramework`(支持单 TFM 和多 TFM,多 TFM 时自动选取包含 `-android` 的目标框架)、`ApplicationId`(映射为 PackageName)、`ApplicationDisplayVersion`(映射为 VersionName)、`ApplicationVersion`(映射为 VersionCode)、`UseMaui`(用于识别 MAUI 项目)、`AndroidPackageFormat`、`AssemblyName`。
- 调用 `dotnet publish "{csprojPath}" -c Release -o "{publishDir}"`。
- 构建完成后在 `bin/Release/{tfm}/publish/` 目录搜索 `.apk` 或 `.aab` 文件,自动定位构建产物。
- 项目类型显示:MAUI(`<UseMaui>true</UseMaui>`)或 Avalonia(没有 UseMaui)。

6. **上传**:通过 HTTP multipart/form-data 将文件上传到服务端。上传表单字段和对应的数据源如下:

| 字段 | 值来源 | 示例 |
|------|--------|------|
| `Name` | ProductName(用户填写) | `MyApp` |
| `Version` | VersionName(自动解析) | `2.0.0` |
| `Hash` | SHA256(自动计算) | `a1b2c3d4...` |
| `Format` | 包格式(自动识别) | `.apk` / `.aab` |
| `Size` | 文件大小(自动计算) | `50000000` |
| `AppType` | 固定值 `"1"` | `1` |
| `Platform` | Platform(默认 4=Android) | `4` |
| `ProductId` | ProductId(用户填写 GUID) | `2d974e2a-...` |
| `IsForcibly` | 强制更新开关 | `true` / `false` |

上传服务支持以下配置:
- **Server URL**:服务端地址
- **Upload Endpoint**:API 路径,默认 `/Packet/Create`
- **Timeout**:超时时间(秒)
- **Retry Count**:失败重试次数(指数退避)
- **Auth**:认证配置,支持 Basic / Bearer Token / API Key 三种模式(凭据通过 DPAPI 加密存储)

7. **版本记录导出**:上传成功后自动生成 `mobile_version_{timestamp}.json`,包含完整的版本元数据。也可以在不上传的情况下单独点击 **Export Record Only** 导出记录,此时 URL 字段为 `"manual"`。

### 输出

Expand Down Expand Up @@ -466,6 +511,11 @@ Generate Sample 额外输出:
| Simulation 端口冲突 | 修改 `ServerPort` 或释放本地 5000 端口 |
| 客户端下载后 Hash 校验失败 | 对**最终上传到 CDN/OSS 的文件**重新计算 Hash,检查是否被中间代理重压缩 |
| Upgrade 进程没有启动 | 检查 `generalupdate.manifest.json` 中 `updateAppName` 和 `updatePath` 是否与发布目录结构一致 |
| Mobile 分析时提示 "Metadata extraction warning" | AXML 解析未找到预期属性,常见的两种原因:APK 使用资源 ID 引用而非直接文本存储属性值;或 APK 被加固/混淆后 AndroidManifest.xml 结构被修改。可以手动填写 PackageName、VersionName、VersionCode |
| Mobile 项目模式 Build & Locate 失败 | 确认已安装 .NET SDK 且版本支持目标框架(TFM),检查 `.csproj` 包含 `-android` 目标框架,输出目录 `bin/Release/{tfm}/publish/` 没有被写入保护 |
| Mobile 项目模式 "Build output not found" | `dotnet publish` 成功执行但未在预期目录找到 `.apk`/`.aab`。检查 `.csproj` 中 `AndroidPackageFormat` 设置是否正确(默认 `aab;apk` 优先产生 APK),以及 TFM 是否自动解析正确 |
| Mobile 上传失败 | 检查服务端地址和 Endpoint 配置是否正确,确认服务端认证方式(Basic / Bearer / API Key)与工具配置一致,查看工具日志中的 HTTP 状态码和错误消息 |
| Mobile 上传后客户端更新失败 | 确认服务端返回的版本记录 JSON 中 `Platform` 字段为 `4`(Android),`Format` 字段与客户端期望的 APK/AAB 格式一致 |

---

Expand Down
13 changes: 11 additions & 2 deletions website/docs/quickstart/Maui Android cookbook.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
---
sidebar_position: 5
title: MAUI Android 更新入门
title: MAUI Android 实战手册
---

# GeneralUpdate.Maui.Android 快速入门
# GeneralUpdate.Maui.Android 实战手册

这篇手册面向需要在 MAUI 应用中集成 Android APK 自动更新的开发者。目标是用最少的代码跑通"检查更新 → 下载 APK → 校验 SHA256 → 启动安装器"的完整流程。

<iframe
src="//player.bilibili.com/player.html?bvid=BV1ntJF6XEvG&page=1"
width="100%"
height="480"
style={{ borderRadius: '8px', border: 'none' }}
allowFullScreen
scrolling="no"
/>

:::info 前置知识
这篇手册假设你已经有一个 .NET MAUI 项目并配置好了 Android 目标框架。如果你还没有 MAUI Android 项目,请先参考 [.NET MAUI 官方文档](https://learn.microsoft.com/dotnet/maui/) 创建。
:::
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
---
sidebar_position: 4
title: Avalonia Android Update Quickstart
title: Avalonia Android Cookbook
---

# GeneralUpdate.Avalonia.Android Quickstart
# GeneralUpdate.Avalonia.Android Cookbook

This guide is for developers who need to integrate Android APK auto-update into their Avalonia applications. The goal is to complete the "check update → download APK → verify SHA256 → launch installer" workflow with minimal code.

<iframe
src="//player.bilibili.com/player.html?bvid=BV1HtJF6XET3&page=1"
width="100%"
height="480"
style={{ borderRadius: '8px', border: 'none' }}
allowFullScreen
scrolling="no"
/>

:::info Prerequisites
This guide assumes you already have an Avalonia project configured for Android target framework. If not, please refer to the [Avalonia documentation](https://docs.avaloniaui.net/) first.
:::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ dotnet run --project GeneralUpdate.Tools.csproj

Go to [GeneralUpdate.Tools Releases](https://github.com/GeneralLibrary/GeneralUpdate.Tools/releases) and download the executable for your platform.

> The Simulation module internally runs `dotnet publish` to build test apps, so you need the .NET SDK for that feature. Patch / Extension / OSS / Config / Mobile modules work without the SDK. However, Mobile's Project Mode (Build & Locate) does require the .NET SDK.
> The Simulation module internally runs `dotnet publish` to build test apps, so you need the .NET SDK for that feature. The Mobile module's Project Mode (Build & Locate) also runs `dotnet publish`, which requires the .NET SDK too. Patch / Extension / OSS / Config modules and Mobile's File Mode work without the SDK.

## Seven modules at a glance

Expand Down Expand Up @@ -312,6 +312,15 @@ In the **OSS Config** module, click **ComputeHash**, select a local ZIP file, an

If you use `GeneralUpdate.Avalonia.Android` or `GeneralUpdate.Maui.Android` to provide auto-update for your Android apps, each release requires extracting APK/AAB metadata (package name, version, SHA256 hash, file size) and uploading it to the server for version management. The Mobile module consolidates "parse → package → upload → generate version record" into a single interface.

<iframe
src="//player.bilibili.com/player.html?bvid=BV1ctJF6XEJs&page=1"
width="100%"
height="480"
style={{ borderRadius: '8px', border: 'none' }}
allowFullScreen
scrolling="no"
/>

Supports two modes:

- **File mode**: Select an APK or AAB file directly; the tool automatically parses AndroidManifest.xml to extract metadata.
Expand Down Expand Up @@ -353,12 +362,48 @@ Supports two modes:
### What the tool does internally

1. **Format detection**: Identifies package format via file extension (`.apk` / `.aab`) and ZIP internal structure (AndroidManifest.xml location).
2. **Metadata parsing**: Uses `AxmlParser` to read binary `AndroidManifest.xml` from the ZIP, extracting `package`, `versionName`, `versionCode`.
3. **SHA256 computation**: Computes SHA256 hash of the full file.
4. **File size**: Reads file length and formats it for human-readable display (KB/MB/GB).
5. **Project build** (Project mode only): Runs `dotnet publish -c Release -o {publishDir}`, then auto-locates the output APK/AAB.
6. **Upload**: Sends file and form fields (Name, Version, Hash, Format, Size, Platform, ProductId, IsForcibly) via HTTP multipart/form-data.
7. **Version record export**: Generates `mobile_version_{timestamp}.json` with full version metadata after successful upload.
- APK detection: Opens the ZIP file and checks for `AndroidManifest.xml` at the root.
- AAB detection: Opens the ZIP file and checks for `base/manifest/AndroidManifest.xml`.
- If the format is neither `.apk` nor `.aab`, the detector returns Unknown.

2. **Metadata parsing**: Uses `AxmlParser` to parse the binary AXML (Android Binary XML) format from the ZIP's `AndroidManifest.xml`. The parsing process works as follows:
- **String pool extraction**: Reads AXML chunk headers, locates the StringPool chunk (type `0x0001`), and extracts all UTF-16LE encoded strings.
- **Attribute value extraction**: Walks through Start Element chunks (type `0x0102`), parses the attribute block (20 bytes per attribute), matches attribute names by their string pool index to find `package` and `versionName`, then resolves values via `rawValueIndex` from the string pool.
- **versionCode extraction**: versionCode is stored as a typed integer attribute (type `0x10` = INT_DEC or `0x11` = INT_HEX), read directly from the `typedValueData` field (offset +16, 4 bytes) as a signed integer.
- AXML chunk structure reference: https://justanapplication.wordpress.com/category/android/android-binary-xml/

3. **SHA256 computation**: Computes SHA256 hash of the full file, output as a lowercase hex string.

4. **File size**: Reads file length and formats it for human-readable display (B / KB / MB / GB).

5. **Project build** (Project mode only): Selecting a `.csproj` triggers:
- `MobileCsprojParser.Parse()` reads the `.csproj` XML to extract `TargetFramework` (supports single and multi-TFM; auto-selects the one containing `-android`), `ApplicationId` (mapped to PackageName), `ApplicationDisplayVersion` (mapped to VersionName), `ApplicationVersion` (mapped to VersionCode), `UseMaui` (identifies MAUI projects), `AndroidPackageFormat`, and `AssemblyName`.
- Runs `dotnet publish "{csprojPath}" -c Release -o "{publishDir}"`.
- After build, searches `bin/Release/{tfm}/publish/` for `.apk` or `.aab` files, auto-locating the build artifact.
- Project type display: MAUI (`<UseMaui>true</UseMaui>`) or Avalonia (no UseMaui).

6. **Upload**: Sends the file and form fields via HTTP multipart/form-data. The form fields and their data sources are:

| Field | Source | Example |
|-------|--------|---------|
| `Name` | ProductName (user input) | `MyApp` |
| `Version` | VersionName (auto-parsed) | `2.0.0` |
| `Hash` | SHA256 (auto-computed) | `a1b2c3d4...` |
| `Format` | Package format (auto-detected) | `.apk` / `.aab` |
| `Size` | File size (auto-computed) | `50000000` |
| `AppType` | Fixed value `"1"` | `1` |
| `Platform` | Platform field (default 4=Android) | `4` |
| `ProductId` | ProductId (user-entered GUID) | `2d974e2a-...` |
| `IsForcibly` | Force update toggle | `true` / `false` |

The upload service supports the following configuration:
- **Server URL**: Server base address
- **Upload Endpoint**: API path, defaults to `/Packet/Create`
- **Timeout**: Timeout in seconds
- **Retry Count**: Retry attempts on failure (exponential backoff)
- **Auth**: Authentication configuration, supports Basic / Bearer Token / API Key modes (credentials stored encrypted via DPAPI)

7. **Version record export**: After a successful upload, generates `mobile_version_{timestamp}.json` with full version metadata. You can also use **Export Record Only** to generate the record without uploading — the URL field will be `"manual"`.

### Output

Expand Down Expand Up @@ -447,6 +492,11 @@ Use the Mobile module for Android app releases:
| Simulation port conflict | Change `ServerPort` or free up local port 5000 |
| Hash mismatch after client download | Re-compute hash on the file that was actually uploaded to CDN/OSS; check for proxy re-compression |
| Upgrade process doesn't start | Verify `updateAppName` and `updatePath` in `generalupdate.manifest.json` match the publish directory structure |
| Mobile analysis shows "Metadata extraction warning" | AXML parser could not find the expected attributes. Common causes: the APK uses resource ID references instead of direct string values; or the APK has been packed/obfuscated and the AndroidManifest.xml structure was modified. You can fill in PackageName, VersionName, and VersionCode manually |
| Mobile Project Mode Build & Locate fails | Verify that the .NET SDK is installed and supports the target framework. Ensure the `.csproj` contains an `-android` target framework. Make sure the output directory `bin/Release/{tfm}/publish/` is not write-protected |
| Mobile Project Mode "Build output not found" | `dotnet publish` succeeded but no `.apk`/`.aab` was found in the expected directory. Check the `AndroidPackageFormat` setting in `.csproj` (default `aab;apk` produces APK first), and verify that the TFM was resolved correctly |
| Mobile upload fails | Check that the server URL and endpoint path are configured correctly. Verify the server authentication method (Basic / Bearer / API Key) matches the tool configuration. Review the tool logs for the HTTP status code and error message |
| Mobile client update fails after upload | Confirm that the version record JSON returned by the server has `Platform` set to `4` (Android), and the `Format` field matches the APK/AAB format the client expects |

---

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
---
sidebar_position: 5
title: MAUI Android Update Quickstart
title: MAUI Android Cookbook
---

# GeneralUpdate.Maui.Android Quickstart
# GeneralUpdate.Maui.Android Cookbook

This guide is for developers who need to integrate Android APK auto-update into their .NET MAUI applications. The goal is to complete the "check update → download APK → verify SHA256 → launch installer" workflow with minimal code.

<iframe
src="//player.bilibili.com/player.html?bvid=BV1ntJF6XEvG&page=1"
width="100%"
height="480"
style={{ borderRadius: '8px', border: 'none' }}
allowFullScreen
scrolling="no"
/>

:::info Prerequisites
This guide assumes you already have a .NET MAUI project configured for Android target framework. If not, please refer to the [.NET MAUI documentation](https://learn.microsoft.com/dotnet/maui/) first.
:::
Expand Down
Loading
Loading