mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-06-22 10:02:20 +00:00
feat: add autostart APK build workflow and update Android services
- Add GitHub Actions workflow for building APK with autostart functionality - Update BootReceiver.kt: default boot autostart to true - Update MainService.kt: use START_STICKY and implement onTaskRemoved - Add documentation and quick start guides
This commit is contained in:
parent
7c41f993fe
commit
02dfd77907
5 changed files with 451 additions and 8 deletions
144
.github/AUTOSTART_APK_BUILD.md
vendored
Normal file
144
.github/AUTOSTART_APK_BUILD.md
vendored
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
# RustDesk Autostart APK Build Workflow
|
||||
|
||||
此工作流用于编译启用开机自启动功能的 RustDesk Android APK。
|
||||
|
||||
## 功能改动
|
||||
|
||||
该工作流编译的 APK 包含以下自启动功能:
|
||||
|
||||
1. **开机自启动**:手机开机后自动启动 RustDesk 服务
|
||||
2. **后台重启**:服务被系统或用户关闭后自动重新启动
|
||||
3. **前台服务**:使用 Android 前台服务,即使在后台也能继续运行
|
||||
|
||||
### 核心修改
|
||||
|
||||
修改的文件位置:
|
||||
- `flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/BootReceiver.kt`
|
||||
- 将开机启动默认值改为 `true`(无需手动UI操作)
|
||||
- 移除不必要的权限检查
|
||||
|
||||
- `flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt`
|
||||
- 返回 `START_STICKY` 标志
|
||||
- 实现 `onTaskRemoved()` 处理,任务被移除时自动重启
|
||||
|
||||
## 使用方式
|
||||
|
||||
### 自动触发
|
||||
|
||||
工作流会在以下情况自动触发:
|
||||
|
||||
1. **代码更新时**:当推送到 `master` 分支时,如果修改了以下文件:
|
||||
- `flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/BootReceiver.kt`
|
||||
- `flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt`
|
||||
- `.github/workflows/flutter-build-autostart-apk.yml`
|
||||
|
||||
### 手动触发
|
||||
|
||||
在 GitHub Actions 中选择 **"Build RustDesk Android APK with Autostart"** 工作流,点击 **"Run workflow"**,选择要编译的架构:
|
||||
- `aarch64` (ARM64,推荐用于现代手机)
|
||||
- `armv7` (ARM,用于较旧手机)
|
||||
- `x86_64` (x86 仿真器)
|
||||
|
||||
## 编译输出
|
||||
|
||||
编译成功后,会生成以下 APK 文件:
|
||||
|
||||
- `rustdesk-autostart-1.4.7-aarch64.apk` (ARM64 版本)
|
||||
- `rustdesk-autostart-1.4.7-armv7.apk` (ARM 版本)
|
||||
- `rustdesk-autostart-1.4.7-x86_64.apk` (x86_64 版本)
|
||||
|
||||
### 下载位置
|
||||
|
||||
1. **GitHub Actions Artifacts**:在工作流运行详情页面,点击 "Artifacts" 部分
|
||||
2. **GitHub Release**:自动创建 `autostart-1.4.7` Release,包含所有编译好的 APK
|
||||
|
||||
## 安装到 Root 手机
|
||||
|
||||
### 方法一:通过 ADB 安装
|
||||
|
||||
```bash
|
||||
# 连接设备
|
||||
adb devices
|
||||
|
||||
# 安装 APK
|
||||
adb install -r rustdesk-autostart-1.4.7-aarch64.apk
|
||||
|
||||
# 授予自启动权限(需要 root)
|
||||
adb shell pm grant com.carriez.flutter_hbb android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
|
||||
adb shell pm grant com.carriez.flutter_hbb android.permission.SYSTEM_ALERT_WINDOW
|
||||
```
|
||||
|
||||
### 方法二:手动安装 + Root 授权
|
||||
|
||||
1. 下载 APK 文件
|
||||
2. 将文件传输到手机
|
||||
3. 打开文件管理器,点击 APK 安装
|
||||
4. 安装后,使用 Root 应用(如 Magisk 或 SuperSU)授予必要权限
|
||||
|
||||
## 所需权限
|
||||
|
||||
该 APK 需要以下权限才能正常自启动:
|
||||
|
||||
- `RECEIVE_BOOT_COMPLETED` - 接收开机广播
|
||||
- `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` - 忽略电池优化
|
||||
- `SYSTEM_ALERT_WINDOW` - 系统提示窗口
|
||||
- `FOREGROUND_SERVICE` - 前台服务
|
||||
|
||||
## 测试自启动功能
|
||||
|
||||
### 测试方法
|
||||
|
||||
1. 安装并授权 APK
|
||||
2. 重启手机
|
||||
3. 检查 RustDesk 是否自动启动
|
||||
4. 查看通知栏是否有 RustDesk 前台服务通知
|
||||
|
||||
### 日志查看
|
||||
|
||||
```bash
|
||||
# 查看 BootReceiver 日志
|
||||
adb logcat | grep tagBootReceiver
|
||||
|
||||
# 查看 MainService 日志
|
||||
adb logcat | grep LOG_SERVICE
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 自启动不工作
|
||||
|
||||
1. **检查权限**:确保已授予所有必要权限
|
||||
2. **电池优化**:将 RustDesk 从电池优化白名单中移除
|
||||
3. **ROM 限制**:某些定制 ROM(如 MIUI、ColorOS)可能限制后台启动
|
||||
4. **Adb logcat**:运行 `adb logcat` 查看是否有错误消息
|
||||
|
||||
### APK 编译失败
|
||||
|
||||
1. 检查工作流日志
|
||||
2. 确保所有依赖项已正确安装
|
||||
3. 检查 Rust 版本是否为 1.75
|
||||
|
||||
## 工作流参数
|
||||
|
||||
工作流使用以下环境变量:
|
||||
|
||||
| 变量 | 值 | 说明 |
|
||||
|------|-----|------|
|
||||
| RUST_VERSION | 1.75 | Rust 编译器版本 |
|
||||
| FLUTTER_VERSION | 3.24.5 | Flutter SDK 版本 |
|
||||
| NDK_VERSION | r28c | Android NDK 版本 |
|
||||
| VERSION | 1.4.7 | RustDesk 版本 |
|
||||
|
||||
## 相关文件
|
||||
|
||||
- 工作流定义:`.github/workflows/flutter-build-autostart-apk.yml`
|
||||
- Boot receiver:`flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/BootReceiver.kt`
|
||||
- Main service:`flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt`
|
||||
- AndroidManifest:`flutter/android/app/src/main/AndroidManifest.xml`
|
||||
|
||||
## 注意事项
|
||||
|
||||
⚠️ **重要**:
|
||||
- 此 APK 需要在 Root 手机上安装以获得最佳效果
|
||||
- 某些权限可能需要 Magisk 或其他 Root 解决方案才能授予
|
||||
- 不同 ROM 的自启动策略可能有所不同
|
||||
214
.github/workflows/flutter-build-autostart-apk.yml
vendored
Normal file
214
.github/workflows/flutter-build-autostart-apk.yml
vendored
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
name: Build RustDesk Android APK with Autostart
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
arch:
|
||||
description: 'Architecture to build'
|
||||
required: true
|
||||
default: 'aarch64'
|
||||
type: choice
|
||||
options:
|
||||
- aarch64
|
||||
- armv7
|
||||
- x86_64
|
||||
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- 'flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/BootReceiver.kt'
|
||||
- 'flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt'
|
||||
- '.github/workflows/flutter-build-autostart-apk.yml'
|
||||
|
||||
env:
|
||||
RUST_VERSION: "1.75"
|
||||
FLUTTER_VERSION: "3.24.5"
|
||||
ANDROID_FLUTTER_VERSION: "3.24.5"
|
||||
CARGO_NDK_VERSION: "3.1.2"
|
||||
NDK_VERSION: "r28c"
|
||||
VERSION: "1.4.7"
|
||||
|
||||
jobs:
|
||||
generate-bridge:
|
||||
uses: ./.github/workflows/bridge.yml
|
||||
|
||||
build-autostart-apk:
|
||||
needs: [generate-bridge]
|
||||
name: Build RustDesk APK ${{ matrix.job.arch }} with Autostart
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job:
|
||||
- {
|
||||
arch: aarch64,
|
||||
target: aarch64-linux-android,
|
||||
reltype: release,
|
||||
android_target: arm64-v8a,
|
||||
android_platform: android-arm64,
|
||||
}
|
||||
- {
|
||||
arch: armv7,
|
||||
target: armv7-linux-androideabi,
|
||||
reltype: release,
|
||||
android_target: armeabi-v7a,
|
||||
android_platform: android-arm,
|
||||
}
|
||||
- {
|
||||
arch: x86_64,
|
||||
target: x86_64-linux-android,
|
||||
reltype: release,
|
||||
android_target: x86_64,
|
||||
android_platform: android-x64,
|
||||
}
|
||||
|
||||
steps:
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
|
||||
with:
|
||||
tool-cache: false
|
||||
android: false
|
||||
dotnet: true
|
||||
haskell: true
|
||||
large-packages: false
|
||||
docker-images: true
|
||||
swap-storage: false
|
||||
|
||||
- name: Export GitHub Actions cache environment variables
|
||||
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
|
||||
with:
|
||||
script: |
|
||||
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
clang \
|
||||
cmake \
|
||||
curl \
|
||||
gcc-multilib \
|
||||
git \
|
||||
g++ \
|
||||
g++-multilib \
|
||||
libayatana-appindicator3-dev \
|
||||
libasound2-dev \
|
||||
libc6-dev \
|
||||
libclang-dev \
|
||||
libunwind-dev \
|
||||
libgstreamer1.0-dev \
|
||||
libgstreamer-plugins-base1.0-dev \
|
||||
libgtk-3-dev \
|
||||
libpam0g-dev \
|
||||
libpulse-dev \
|
||||
libva-dev \
|
||||
libxcb-randr0-dev \
|
||||
libxcb-shape0-dev \
|
||||
libxcb-xfixes0-dev \
|
||||
libxdo-dev \
|
||||
libxfixes-dev \
|
||||
llvm-dev \
|
||||
nasm \
|
||||
ninja-build \
|
||||
openjdk-17-jdk-headless \
|
||||
pkg-config \
|
||||
wget
|
||||
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Restore bridge files
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
name: bridge-artifact
|
||||
path: ./
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: ${{ env.RUST_VERSION }}
|
||||
targets: ${{ matrix.job.target }}
|
||||
|
||||
- name: Cache Rust dependencies
|
||||
uses: Swatinem/rust-cache@23a6cea2dd7927e274fa67a56199cc32ae1ea204 # v2
|
||||
with:
|
||||
prefix-key: rustdesk-lib-cache-android
|
||||
|
||||
- uses: nttld/setup-ndk@ed92fe6cadad69be94a966a7ee3271275e62f779 # v1
|
||||
id: setup-ndk
|
||||
with:
|
||||
ndk-version: ${{ env.NDK_VERSION }}
|
||||
add-to-path: true
|
||||
|
||||
- name: Install Flutter
|
||||
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.ANDROID_FLUTTER_VERSION }}
|
||||
|
||||
- name: Build Rust lib for Android
|
||||
shell: bash
|
||||
env:
|
||||
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
run: |
|
||||
cargo build --release --target ${{ matrix.job.target }}
|
||||
|
||||
- name: Copy compiled libraries
|
||||
shell: bash
|
||||
env:
|
||||
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
run: |
|
||||
case ${{ matrix.job.target }} in
|
||||
aarch64-linux-android)
|
||||
mkdir -p ./flutter/android/app/src/main/jniLibs/arm64-v8a
|
||||
cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so ./flutter/android/app/src/main/jniLibs/arm64-v8a/
|
||||
cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/arm64-v8a/librustdesk.so
|
||||
;;
|
||||
armv7-linux-androideabi)
|
||||
mkdir -p ./flutter/android/app/src/main/jniLibs/armeabi-v7a
|
||||
cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so ./flutter/android/app/src/main/jniLibs/armeabi-v7a/
|
||||
cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/armeabi-v7a/librustdesk.so
|
||||
;;
|
||||
x86_64-linux-android)
|
||||
mkdir -p ./flutter/android/app/src/main/jniLibs/x86_64
|
||||
cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so ./flutter/android/app/src/main/jniLibs/x86_64/
|
||||
cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/x86_64/librustdesk.so
|
||||
;;
|
||||
esac
|
||||
|
||||
- name: Build Flutter APK with Autostart
|
||||
shell: bash
|
||||
env:
|
||||
JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
|
||||
run: |
|
||||
export PATH=/usr/lib/jvm/java-17-openjdk-amd64/bin:$PATH
|
||||
# Increase Gradle JVM memory for CI builds
|
||||
sed -i "s/org.gradle.jvmargs=-Xmx1024M/org.gradle.jvmargs=-Xmx2g/g" ./flutter/android/gradle.properties
|
||||
# Use debug sign config for APK
|
||||
sed -i "s/signingConfigs.release/signingConfigs.debug/g" ./flutter/android/app/build.gradle
|
||||
cd flutter
|
||||
flutter build apk --release --target-platform ${{ matrix.job.android_platform }} --split-per-abi
|
||||
popd
|
||||
mv flutter/build/app/outputs/flutter-apk/app-${{ matrix.job.android_target }}-release.apk rustdesk-autostart-${{ env.VERSION }}-${{ matrix.job.arch }}.apk
|
||||
|
||||
- name: Upload APK Artifact
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: rustdesk-autostart-${{ env.VERSION }}-${{ matrix.job.arch }}.apk
|
||||
path: rustdesk-autostart-${{ env.VERSION }}-${{ matrix.job.arch }}.apk
|
||||
retention-days: 30
|
||||
|
||||
- name: Create Release
|
||||
if: success()
|
||||
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
||||
with:
|
||||
files: rustdesk-autostart-${{ env.VERSION }}-${{ matrix.job.arch }}.apk
|
||||
tag_name: autostart-${{ env.VERSION }}
|
||||
prerelease: true
|
||||
generate_release_notes: true
|
||||
continue-on-error: true
|
||||
77
AUTOSTART_APK_QUICKSTART.md
Normal file
77
AUTOSTART_APK_QUICKSTART.md
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# 快速开始:自启动 APK 构建
|
||||
|
||||
## 一句话总结
|
||||
|
||||
在 GitHub Actions 中自动编译带开机自启动功能的 RustDesk Android APK。
|
||||
|
||||
## 快速步骤
|
||||
|
||||
### 1️⃣ 查看工作流状态
|
||||
进入 **Actions** → **Build RustDesk Android APK with Autostart**
|
||||
|
||||
### 2️⃣ 手动触发编译(可选)
|
||||
点击 **Run workflow** → 选择架构(推荐 `aarch64`)→ 点击绿色 **Run workflow**
|
||||
|
||||
### 3️⃣ 等待编译完成
|
||||
工作流运行约 30-45 分钟(首次编译时间较长)
|
||||
|
||||
### 4️⃣ 下载 APK
|
||||
两种方式下载:
|
||||
- **Artifacts**:工作流详情页 → 找 `rustdesk-autostart-*.apk`
|
||||
- **Release**:Code → Releases → 找 `autostart-*` 版本
|
||||
|
||||
### 5️⃣ 安装到手机
|
||||
```bash
|
||||
adb install -r rustdesk-autostart-1.4.7-aarch64.apk
|
||||
```
|
||||
|
||||
### 6️⃣ 授予权限(需 Root)
|
||||
```bash
|
||||
# 如果手机已 Root,使用以下命令
|
||||
adb shell pm grant com.carriez.flutter_hbb android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
|
||||
adb shell pm grant com.carriez.flutter_hbb android.permission.SYSTEM_ALERT_WINDOW
|
||||
```
|
||||
|
||||
### 7️⃣ 测试
|
||||
重启手机,检查 RustDesk 是否自动启动
|
||||
|
||||
## 文件说明
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `.github/workflows/flutter-build-autostart-apk.yml` | GitHub Actions 工作流定义 |
|
||||
| `flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/BootReceiver.kt` | 开机启动接收器(已修改) |
|
||||
| `flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainService.kt` | 主服务(已修改) |
|
||||
| `.github/AUTOSTART_APK_BUILD.md` | 详细文档 |
|
||||
|
||||
## 关键修改
|
||||
|
||||
✅ **已完成**:
|
||||
1. BootReceiver - 开机启动默认打开
|
||||
2. MainService - 服务被关闭后自动重启
|
||||
|
||||
## 架构选择
|
||||
|
||||
| 架构 | 适用设备 | 说明 |
|
||||
|------|---------|------|
|
||||
| **aarch64** | 大多数现代手机 | ARM64,推荐选择 |
|
||||
| **armv7** | 较旧的手机 | 32 位 ARM |
|
||||
| **x86_64** | Android 模拟器 | 用于开发测试 |
|
||||
|
||||
## 常见问题
|
||||
|
||||
**Q: 自启动不工作?**
|
||||
A:
|
||||
1. 确保手机已 Root
|
||||
2. 检查权限是否授予
|
||||
3. 某些 ROM(如小米)需要额外配置
|
||||
|
||||
**Q: 如何查看编译错误?**
|
||||
A: 点击工作流运行 → 查看各步骤的日志输出
|
||||
|
||||
**Q: 能否定制架构?**
|
||||
A: 可以,在工作流中手动运行时选择特定架构
|
||||
|
||||
## 下一步
|
||||
|
||||
详见 [完整文档](.github/AUTOSTART_APK_BUILD.md)
|
||||
|
|
@ -20,17 +20,12 @@ class BootReceiver : BroadcastReceiver() {
|
|||
Log.d(logTag, "onReceive ${intent.action}")
|
||||
|
||||
if (Intent.ACTION_BOOT_COMPLETED == intent.action || DEBUG_BOOT_COMPLETED == intent.action) {
|
||||
// check SharedPreferences config
|
||||
// check SharedPreferences config, default to true so boot auto-start works without manual UI action
|
||||
val prefs = context.getSharedPreferences(KEY_SHARED_PREFERENCES, FlutterActivity.MODE_PRIVATE)
|
||||
if (!prefs.getBoolean(KEY_START_ON_BOOT_OPT, false)) {
|
||||
if (!prefs.getBoolean(KEY_START_ON_BOOT_OPT, true)) {
|
||||
Log.d(logTag, "KEY_START_ON_BOOT_OPT is false")
|
||||
return
|
||||
}
|
||||
// check pre-permission
|
||||
if (!XXPermissions.isGranted(context, REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, SYSTEM_ALERT_WINDOW)){
|
||||
Log.d(logTag, "REQUEST_IGNORE_BATTERY_OPTIMIZATIONS or SYSTEM_ALERT_WINDOW is not granted")
|
||||
return
|
||||
}
|
||||
|
||||
val it = Intent(context, MainService::class.java).apply {
|
||||
action = ACT_INIT_MEDIA_PROJECTION_AND_SERVICE
|
||||
|
|
|
|||
|
|
@ -346,7 +346,20 @@ class MainService : Service() {
|
|||
requestMediaProjection()
|
||||
}
|
||||
}
|
||||
return START_NOT_STICKY // don't use sticky (auto restart), the new service (from auto restart) will lose control
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
override fun onTaskRemoved(rootIntent: Intent?) {
|
||||
super.onTaskRemoved(rootIntent)
|
||||
Log.d(logTag, "onTaskRemoved, restarting service")
|
||||
val restartIntent = Intent(applicationContext, MainService::class.java).apply {
|
||||
action = ACT_INIT_MEDIA_PROJECTION_AND_SERVICE
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
applicationContext.startForegroundService(restartIntent)
|
||||
} else {
|
||||
applicationContext.startService(restartIntent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue