Skip to content
Open
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
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,35 @@ app.
For simulators, use `pnpm expo:ios:simulator` on iOS. For Android, start an
Android emulator first, then run `pnpm expo:android`.

#### Windows: Android development setup

The npm scripts above use `cross-env`, so they work in Windows PowerShell/cmd
out of the box. The first Android build needs a native toolchain:

1. Install **JDK 17 or 21** ([Eclipse Temurin](https://adoptium.net)) and set
the `JAVA_HOME` user environment variable to its folder.
2. Install **[Android Studio](https://developer.android.com/studio)** and, in
the **SDK Manager**, install: an Android platform (`Android 15/16`, API
35/36), **Android SDK Build-Tools**, **Android SDK Platform-Tools**, and an
`x86_64` system image for the emulator.
3. Create an AVD in **Device Manager** (or connect a device with USB debugging).
4. Set the `ANDROID_HOME` user environment variable to your SDK path
(default: `%LOCALAPPDATA%\Android\Sdk`).

Check that everything is in place:

```powershell
pnpm expo:doctor:android
```

Then start Metro and build the dev client (first build downloads Gradle and
native dependencies, so it takes a while):

```powershell
pnpm expo:start # terminal 1: Metro dev server
pnpm expo:android # terminal 2: build + install the dev client
```

Mobile app source lives in [`packages/app-expo`](packages/app-expo).

### AI Configuration
Expand Down
28 changes: 28 additions & 0 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,34 @@ Expo Go。Expo Go 无法加载 ReadAny 当前依赖的原生模块和应用配
模拟器调试时,iOS 使用 `pnpm expo:ios:simulator`;Android 先启动 Android
模拟器,再运行 `pnpm expo:android`。

#### Windows:Android 开发环境配置

上面的 npm 脚本都用了 `cross-env`,在 Windows 的 PowerShell/cmd 下可直接运行。
首次 Android 构建需要原生工具链:

1. 安装 **JDK 17 或 21**([Eclipse Temurin](https://adoptium.net)),并把
`JAVA_HOME` 用户环境变量指向其目录。
2. 安装 **[Android Studio](https://developer.android.com/studio)**,在
**SDK Manager** 中安装:Android 平台(`Android 15/16`,API 35/36)、
**Android SDK Build-Tools**、**Android SDK Platform-Tools**,以及一个
`x86_64` 模拟器系统镜像。
3. 在 **Device Manager** 创建 AVD(或用开启 USB 调试的真机)。
4. 把 `ANDROID_HOME` 用户环境变量设为 SDK 路径(默认
`%LOCALAPPDATA%\Android\Sdk`)。

检查环境是否就绪:

```powershell
pnpm expo:doctor:android
```

然后启动 Metro 并构建 dev client(首次构建会下载 Gradle 和原生依赖,耗时较长):

```powershell
pnpm expo:start # 终端 1:Metro dev server
pnpm expo:android # 终端 2:构建并安装 dev client
```

移动端源码位于 [`packages/app-expo`](packages/app-expo)。

### AI 配置
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"expo:ios": "pnpm --filter @readany/app-expo ios",
"expo:ios:simulator": "pnpm --filter @readany/app-expo ios:simulator",
"expo:android": "pnpm --filter @readany/app-expo android",
"expo:doctor:android": "pnpm --filter @readany/app-expo doctor:android",
"expo:prebuild": "pnpm --filter @readany/app-expo prebuild",
"eas:device:create": "pnpm --filter @readany/app-expo eas:device:create",
"eas:build:android": "pnpm --filter @readany/app-expo eas:build:android",
Expand Down
48 changes: 24 additions & 24 deletions packages/app-expo/assets/reader/reader.html

Large diffs are not rendered by default.

26 changes: 14 additions & 12 deletions packages/app-expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,34 @@
}
},
"scripts": {
"start": "APP_VARIANT=development pnpm run build:reader && APP_VARIANT=development node scripts/configure-native-variant.js && APP_VARIANT=development expo start --dev-client --scheme readany-dev",
"start:clear": "APP_VARIANT=development pnpm run build:reader && APP_VARIANT=development node scripts/configure-native-variant.js && APP_VARIANT=development expo start --dev-client --scheme readany-dev --clear",
"start": "cross-env APP_VARIANT=development pnpm run build:reader && cross-env APP_VARIANT=development node scripts/configure-native-variant.js && cross-env APP_VARIANT=development expo start --dev-client --scheme readany-dev",
"start:clear": "cross-env APP_VARIANT=development pnpm run build:reader && cross-env APP_VARIANT=development node scripts/configure-native-variant.js && cross-env APP_VARIANT=development expo start --dev-client --scheme readany-dev --clear",
"start:dev": "pnpm run start",
"start:dev:clear": "pnpm run start:clear",
"preandroid": "pnpm run build:reader",
"android": "expo run:android",
"android:dev": "APP_VARIANT=development pnpm run build:reader && APP_VARIANT=development expo run:android --device",
"android:dev": "cross-env APP_VARIANT=development pnpm run build:reader && cross-env APP_VARIANT=development expo run:android --device",
"preios": "pnpm run build:reader && node scripts/configure-native-variant.js",
"ios": "expo run:ios",
"ios:dev": "APP_VARIANT=development pnpm run build:reader && APP_VARIANT=development node scripts/configure-native-variant.js && APP_VARIANT=development expo run:ios --device",
"ios:simulator": "APP_VARIANT=development pnpm run build:reader && APP_VARIANT=development node scripts/configure-native-variant.js && APP_VARIANT=development expo run:ios",
"ios:dev": "cross-env APP_VARIANT=development pnpm run build:reader && cross-env APP_VARIANT=development node scripts/configure-native-variant.js && cross-env APP_VARIANT=development expo run:ios --device",
"ios:simulator": "cross-env APP_VARIANT=development pnpm run build:reader && cross-env APP_VARIANT=development node scripts/configure-native-variant.js && cross-env APP_VARIANT=development expo run:ios",
"preprebuild": "pnpm run build:reader",
"prebuild": "expo prebuild",
"build:reader": "node scripts/build-reader.js",
"sync:native-variant": "node scripts/configure-native-variant.js",
"doctor:android": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/check-android-env.ps1",
"lint": "biome check .",
"test": "vitest run",
"eas-build-pre-install": "bash scripts/eas-install-ios-build-tools.sh",
"eas-build-post-install": "pnpm run build:reader && node scripts/configure-native-variant.js",
"eas:device:create": "pnpm exec eas device:create",
"eas:build:android": "APP_VARIANT=production pnpm exec eas build --profile production --platform android",
"eas:build:android:dev": "APP_VARIANT=development pnpm exec eas build --profile development --platform android",
"eas:build:android:preview": "APP_VARIANT=preview pnpm exec eas build --profile preview --platform android",
"eas:build:ios": "APP_VARIANT=production pnpm exec eas build --profile production --platform ios",
"eas:build:ios:dev": "APP_VARIANT=development pnpm exec eas build --profile development --platform ios",
"eas:build:ios:simulator": "APP_VARIANT=development pnpm exec eas build --profile development-simulator --platform ios",
"eas:build:ios:preview": "APP_VARIANT=preview pnpm exec eas build --profile preview --platform ios"
"eas:build:android": "cross-env APP_VARIANT=production pnpm exec eas build --profile production --platform android",
"eas:build:android:dev": "cross-env APP_VARIANT=development pnpm exec eas build --profile development --platform android",
"eas:build:android:preview": "cross-env APP_VARIANT=preview pnpm exec eas build --profile preview --platform android",
"eas:build:ios": "cross-env APP_VARIANT=production pnpm exec eas build --profile production --platform ios",
"eas:build:ios:dev": "cross-env APP_VARIANT=development pnpm exec eas build --profile development --platform ios",
"eas:build:ios:simulator": "cross-env APP_VARIANT=development pnpm exec eas build --profile development-simulator --platform ios",
"eas:build:ios:preview": "cross-env APP_VARIANT=preview pnpm exec eas build --profile preview --platform ios"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.712.0",
Expand Down Expand Up @@ -117,6 +118,7 @@
"@types/react": "^19.1.17",
"babel-plugin-module-resolver": "^5.0.2",
"babel-plugin-transform-import-meta": "^2.3.2",
"cross-env": "^10.1.0",
"eas-cli": "^18.11.0",
"esbuild": "^0.27.3",
"react-native-svg-transformer": "^1.5.3",
Expand Down
125 changes: 125 additions & 0 deletions packages/app-expo/scripts/check-android-env.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<#
.SYNOPSIS
ReadAny - Android development environment checker (Windows).

.DESCRIPTION
Verifies the toolchain needed to build and run the Expo dev client on
Android: Node.js/pnpm, JDK 17+, the Android SDK (platform-tools, platforms,
build-tools, accepted licenses), and an emulator AVD or connected device.
Prints PASS/FAIL per check with concrete fix steps and exits non-zero when
any check fails.

.EXAMPLE
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/check-android-env.ps1
#>
[CmdletBinding()]
param()

$ErrorActionPreference = "SilentlyContinue"

$script:Pass = 0
$script:Fail = 0

function Write-Result {
param([string]$Name, [bool]$Ok, [string]$Hint)
if ($Ok) { $script:Pass++ } else { $script:Fail++ }
$mark = if ($Ok) { "[ OK ]" } else { "[FAIL]" }
$color = if ($Ok) { "Green" } else { "Red" }
Write-Host ("{0} {1}" -f $mark, $Name) -ForegroundColor $color
if (-not $Ok -and $Hint) {
Write-Host (" > {0}" -f $Hint) -ForegroundColor Yellow
}
}

Write-Host "ReadAny - Android dev environment check" -ForegroundColor Cyan
Write-Host ""

# --- Node.js / pnpm --------------------------------------------------
$node = Get-Command node -ErrorAction SilentlyContinue
Write-Result "Node.js" ($null -ne $node) "Install Node.js 18+ from https://nodejs.org"

$pnpm = Get-Command pnpm -ErrorAction SilentlyContinue
Write-Result "pnpm" ($null -ne $pnpm) "Install pnpm: npm install -g pnpm"

# --- JDK -------------------------------------------------------------
$javaHome = $env:JAVA_HOME
$jdkOk = $false
$jdkHint = "Install JDK 17 or 21 from https://adoptium.net, then set the JAVA_HOME user environment variable to its folder."
if ($javaHome) {
$javaBin = Join-Path $javaHome "bin\java.exe"
if (Test-Path $javaBin) {
# `cmd /c ... 2>&1` merges java's stderr at the OS level; under
# $ErrorActionPreference=SilentlyContinue PowerShell would otherwise swallow
# the NativeCommandError records produced by `2>&1`.
$verLine = (& cmd /c "`"$javaBin`" -version 2>&1" 2>$null | Select-Object -First 1)
if ($verLine -match 'version "(\d+)') {
$major = [int]$Matches[1]
$jdkOk = $major -ge 17
if (-not $jdkOk) {
$jdkHint = "Found JDK $major - Gradle 8.13 needs JDK 17 or 21 (JDK 25 is too new)."
}
} else {
$jdkHint = "Could not read the JDK version from $javaBin."
}
} else {
$jdkHint = "JAVA_HOME is set to `"$javaHome`" but bin\java.exe was not found there."
}
} else {
$jdkHint = "JAVA_HOME is not set. Install JDK 17/21 and set JAVA_HOME (e.g. C:\Program Files\Eclipse Adoptium\jdk-21.x)."
}
Write-Result "JDK (JAVA_HOME=$javaHome)" $jdkOk $jdkHint

# --- Android SDK -----------------------------------------------------
$sdk = $env:ANDROID_HOME
if (-not $sdk) { $sdk = $env:ANDROID_SDK_ROOT }
$sdkDefault = Join-Path $env:LOCALAPPDATA "Android\Sdk"
if (-not $sdk) { $sdk = $sdkDefault }
$sdkOk = Test-Path $sdk
Write-Result "Android SDK ($sdk)" $sdkOk (
"Install Android Studio or the command-line tools. If you used the default location, set the ANDROID_HOME user environment variable to: $sdkDefault"
)

if ($sdkOk) {
$adb = Join-Path $sdk "platform-tools\adb.exe"
$adbOk = Test-Path $adb
Write-Result "platform-tools (adb)" $adbOk "SDK Manager -> SDK Tools -> check 'Android SDK Platform-Tools'."

$platforms = @(Get-ChildItem (Join-Path $sdk "platforms") -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -match '^android-(3[5-9]|[4-9][0-9])$' })
Write-Result "Android SDK Platform (API 35+)" ($platforms.Count -gt 0) (
"SDK Manager -> SDK Platforms -> check 'Android 15/16 (API 35/36)'. Gradle auto-downloads the exact platform if licenses are accepted."
)

$buildTools = @(Get-ChildItem (Join-Path $sdk "build-tools") -Directory -ErrorAction SilentlyContinue)
Write-Result "Android SDK Build-Tools" ($buildTools.Count -gt 0) "SDK Manager -> SDK Tools -> check 'Android SDK Build-Tools'."

Write-Result "SDK licenses accepted" (Test-Path (Join-Path $sdk "licenses")) (
"Accept them via SDK Manager, or run sdkmanager --licenses."
)

$deviceCount = 0
if ($adbOk) {
$devOut = @(& $adb devices 2>&1)
$deviceCount = @($devOut | Where-Object { $_ -match "\tdevice$" }).Count
}
Write-Result "Android device/emulator connected" ($deviceCount -gt 0) (
"Start an emulator (Device Manager) or connect a device with USB debugging enabled."
)

$emu = Join-Path $sdk "emulator\emulator.exe"
$avdCount = 0
if (Test-Path $emu) {
$avdOut = @(& $emu -list-avds 2>&1)
$avdCount = @($avdOut | Where-Object { $_ -match '\S' -and $_ -notmatch '^INFO|^WARNING|^ERROR' }).Count
}
Write-Result "Emulator AVD configured" ($avdCount -gt 0) (
"Android Studio -> Device Manager -> Create device (x86_64 system image, API 35)."
)
}

# --- Summary ---------------------------------------------------------
Write-Host ""
$color = if ($script:Fail -eq 0) { "Green" } else { "Red" }
Write-Host ("{0} passed, {1} failed" -f $script:Pass, $script:Fail) -ForegroundColor $color
if ($script:Fail -gt 0) {
exit 1
}
33 changes: 28 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.