Compare commits
5 Commits
v1.0.0
...
2026-03-02
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c39e3cfc5f | ||
|
|
430fa2f83a | ||
|
|
730fb6e080 | ||
|
|
d640280048 | ||
|
|
f762f4f84d |
19
README.md
19
README.md
@@ -1,15 +1,14 @@
|
|||||||
# APRS Locator (Android)
|
# APRS Locator (Android)
|
||||||
|
|
||||||
Simple Android app (Jetpack Compose) that shows:
|
|
||||||
- Decimal coordinates (latitude and longitude)
|
|
||||||
- APRS-format coordinates
|
|
||||||
- Maidenhead (ham radio) grid square
|
|
||||||
|
|
||||||
Dark theme. The app requests `ACCESS_FINE_LOCATION` at runtime. Build and run with Android Studio or Gradle.
|
-Конвертор координат GPS → APRS, Maidenhead
|
||||||
|
|
||||||
Quick build (from project root):
|
-Возможности:
|
||||||
|
|
||||||
```bash
|
-Десятичные координаты
|
||||||
# Open in Android Studio or run with Gradle wrapper in Android Studio environment
|
|
||||||
./gradlew :app:installDebug
|
-Градусы, минуты, секунды (DMS)
|
||||||
```
|
|
||||||
|
-APRS формат
|
||||||
|
|
||||||
|
-Maidenhead (QTH локатор)
|
||||||
|
|||||||
@@ -1,232 +0,0 @@
|
|||||||
# Конвертор координат GPS → APRS, Maidenhead
|
|
||||||
|
|
||||||
## Описание проекта
|
|
||||||
|
|
||||||
Приложение Android для конвертации GPS координат в различные форматы:
|
|
||||||
- Десятичные координаты (широта/долгота)
|
|
||||||
- Градусы, минуты, секунды (DMS)
|
|
||||||
- APRS формат
|
|
||||||
- Maidenhead (QTH локатор)
|
|
||||||
|
|
||||||
**Технологии:**
|
|
||||||
- Kotlin
|
|
||||||
- Jetpack Compose (Material 3)
|
|
||||||
- Android SDK 34
|
|
||||||
- Min SDK: 21
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Структура проекта
|
|
||||||
|
|
||||||
```
|
|
||||||
vs2/
|
|
||||||
├── app/
|
|
||||||
│ ├── src/main/
|
|
||||||
│ │ ├── java/com/example/aprs/
|
|
||||||
│ │ │ ├── MainActivity.kt # Основной экран
|
|
||||||
│ │ │ └── LocationUtils.kt # Утилиты конвертации
|
|
||||||
│ │ ├── res/
|
|
||||||
│ │ │ ├── values/
|
|
||||||
│ │ │ │ ├── strings.xml
|
|
||||||
│ │ │ │ ├── themes.xml
|
|
||||||
│ │ │ │ └── ic_launcher_background.xml
|
|
||||||
│ │ │ └── mipmap-*/ # Иконки приложения
|
|
||||||
│ │ ├── AndroidManifest.xml
|
|
||||||
│ │ └── build.gradle.kts
|
|
||||||
│ └── build/outputs/apk/debug/ # Скомпилированный APK
|
|
||||||
├── build.gradle.kts
|
|
||||||
├── gradle.properties
|
|
||||||
├── settings.gradle.kts
|
|
||||||
└── gradlew # Gradle wrapper
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Требования к серверу
|
|
||||||
|
|
||||||
### Необходимое ПО:
|
|
||||||
- **Java JDK 17** (`/usr/lib/jvm/java-17-openjdk-amd64`)
|
|
||||||
- **Git** (опционально)
|
|
||||||
- **SSH доступ** с паролем или ключом
|
|
||||||
|
|
||||||
### Проверка окружения на сервере:
|
|
||||||
```bash
|
|
||||||
java -version
|
|
||||||
# Должно показать: openjdk version "17.x.x"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Инструкция по компиляции на сервере
|
|
||||||
|
|
||||||
### 1. Подключение к серверу
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Подключение по SSH
|
|
||||||
ssh ua1zbe@192.168.1.46
|
|
||||||
# Введите пароль: ktdbycrbq1980
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Загрузка проекта на сервер
|
|
||||||
|
|
||||||
#### Вариант A: Через rsync (рекомендуется)
|
|
||||||
```bash
|
|
||||||
# С локальной машины
|
|
||||||
rsync -avz -e ssh /home/ua1zbe/my_aprs_project/vs2/ ua1zbe@192.168.1.46:~/my_aprs_project/vs2/
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Вариант B: Через git
|
|
||||||
```bash
|
|
||||||
# На сервере
|
|
||||||
cd ~
|
|
||||||
git clone <repository-url> my_aprs_project/vs2
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Сборка APK
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Подключение к серверу
|
|
||||||
ssh ua1zbe@192.168.1.46
|
|
||||||
|
|
||||||
# Переход в директорию проекта
|
|
||||||
cd ~/my_aprs_project/vs2
|
|
||||||
|
|
||||||
# Установка JAVA_HOME
|
|
||||||
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
|
|
||||||
|
|
||||||
# Очистка и сборка
|
|
||||||
./gradlew clean assembleDebug
|
|
||||||
|
|
||||||
# Или только сборка (быстрее)
|
|
||||||
./gradlew assembleDebug
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Результат сборки
|
|
||||||
|
|
||||||
APK файл будет создан в:
|
|
||||||
```
|
|
||||||
/home/ua1zbe/my_aprs_project/vs2/app/build/outputs/apk/debug/app-debug.apk
|
|
||||||
```
|
|
||||||
|
|
||||||
Размер: ~12-14 MB
|
|
||||||
|
|
||||||
### 5. Проверка сборки
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Проверка существования APK
|
|
||||||
ls -lh ~/my_aprs_project/vs2/app/build/outputs/apk/debug/app-debug.apk
|
|
||||||
|
|
||||||
# Информация о сборке
|
|
||||||
./gradlew buildEnvironment
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Установка на устройство
|
|
||||||
|
|
||||||
### Вариант A: Через ADB (USB)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Скачать APK с сервера
|
|
||||||
scp ua1zbe@192.168.1.46:~/my_aprs_project/vs2/app/build/outputs/apk/debug/app-debug.apk /home/ua1zbe/my_aprs_project/vs2/
|
|
||||||
|
|
||||||
# Установить на устройство
|
|
||||||
adb install -r /home/ua1zbe/my_aprs_project/vs2/app-debug.apk
|
|
||||||
```
|
|
||||||
|
|
||||||
### Вариант B: Прямая установка с сервера
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# На сервере (если есть ADB и подключено устройство)
|
|
||||||
adb install ~/my_aprs_project/vs2/app/build/outputs/apk/debug/app-debug.apk
|
|
||||||
```
|
|
||||||
|
|
||||||
### Вариант C: Через файловый менеджер
|
|
||||||
|
|
||||||
1. Скачать APK с сервера через SFTP/SCP
|
|
||||||
2. Передать на телефон
|
|
||||||
3. Установить через файловый менеджер
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Полезные команды Gradle
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Очистка сборки
|
|
||||||
./gradlew clean
|
|
||||||
|
|
||||||
# Сборка debug версии
|
|
||||||
./gradlew assembleDebug
|
|
||||||
|
|
||||||
# Сборка release версии
|
|
||||||
./gradlew assembleRelease
|
|
||||||
|
|
||||||
# Запуск тестов
|
|
||||||
./gradlew test
|
|
||||||
|
|
||||||
# Проверка зависимостей
|
|
||||||
./gradlew dependencies
|
|
||||||
|
|
||||||
# Остановка Gradle daemon
|
|
||||||
./gradlew --stop
|
|
||||||
|
|
||||||
# Сборка с логом
|
|
||||||
./gradlew assembleDebug --info
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Решение проблем
|
|
||||||
|
|
||||||
### Ошибка: "Could not connect to Kotlin compile daemon"
|
|
||||||
```bash
|
|
||||||
# Остановить Gradle и попробовать снова
|
|
||||||
./gradlew --stop
|
|
||||||
./gradlew clean assembleDebug
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ошибка: "minSdkVersion cannot be smaller than version 21"
|
|
||||||
```bash
|
|
||||||
# Jetpack Compose требует API 21+
|
|
||||||
# Проверить app/build.gradle.kts:
|
|
||||||
# minSdk = 21
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ошибка: "resource not found" для иконок
|
|
||||||
```bash
|
|
||||||
# Проверить наличие директорий mipmap
|
|
||||||
ls app/src/main/res/mipmap-*/
|
|
||||||
|
|
||||||
# Пересоздать иконки при необходимости
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ошибка: "BUILD FAILED - Manifest merger failed"
|
|
||||||
```bash
|
|
||||||
# Очистить сборку
|
|
||||||
./gradlew clean
|
|
||||||
# Проверить AndroidManifest.xml на ошибки
|
|
||||||
```
|
|
||||||
|
|
||||||
### Долгая компиляция
|
|
||||||
```bash
|
|
||||||
# Использовать daemon (по умолчанию включён)
|
|
||||||
./gradlew assembleDebug --daemon
|
|
||||||
|
|
||||||
# Или увеличить память
|
|
||||||
export GRADLE_OPTS="-Xmx2g"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Быстрая сборка (one-liner)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ssh ua1zbe@192.168.1.46 "cd ~/my_aprs_project/vs2 && export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 && ./gradlew assembleDebug" && scp ua1zbe@192.168.1.46:~/my_aprs_project/vs2/app/build/outputs/apk/debug/app-debug.apk /home/ua1zbe/my_aprs_project/vs2/ && adb install -r /home/ua1zbe/my_aprs_project/vs2/app-debug.apk
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Контакты
|
|
||||||
|
|
||||||
Автор: UA1ZBE
|
|
||||||
Дата: Март 2026
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
if [ -z "$DISPLAY" ]; then
|
|
||||||
echo "No X DISPLAY set. Cannot start GUI emulator here."
|
|
||||||
echo "If you are on a remote session, run this on a desktop with X or use SSH -X."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
SDK="$HOME/Android/Sdk"
|
|
||||||
ADB="$SDK/platform-tools/adb"
|
|
||||||
EMULATOR_BIN="$SDK/emulator/emulator"
|
|
||||||
AVD_NAME=aprs_avd
|
|
||||||
LOG=/tmp/emulator_aprs_gui.log
|
|
||||||
|
|
||||||
echo "Killing existing emulator instances..."
|
|
||||||
pkill -f 'emulator' || true
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
if [ ! -x "$ADB" ]; then
|
|
||||||
echo "adb not found at $ADB"; exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Restarting adb..."
|
|
||||||
$ADB kill-server || true
|
|
||||||
sleep 1
|
|
||||||
$ADB start-server || true
|
|
||||||
|
|
||||||
if [ ! -x "$EMULATOR_BIN" ]; then
|
|
||||||
echo "Emulator binary not found: $EMULATOR_BIN"; exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Starting emulator '$AVD_NAME' (GUI). Log -> $LOG"
|
|
||||||
"$EMULATOR_BIN" -avd "$AVD_NAME" -partition-size 5120 -gpu host -wipe-data -no-boot-anim &>"$LOG" &
|
|
||||||
EMUPID=$!
|
|
||||||
echo "Emulator PID: $EMUPID"
|
|
||||||
|
|
||||||
echo "Waiting for adb to see emulator..."
|
|
||||||
for i in $(seq 1 60); do
|
|
||||||
LIST=$($ADB devices | sed -n '2,200p' | tr -d '\r' || true)
|
|
||||||
if echo "$LIST" | grep -q 'emulator'; then
|
|
||||||
echo "Emulator connected to adb"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
echo "Waiting for adb... ($i)"
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Waiting for emulator to finish boot (up to 240s)..."
|
|
||||||
for i in $(seq 1 120); do
|
|
||||||
BOOT=$($ADB shell getprop sys.boot_completed 2>/dev/null | tr -d '\r' || true)
|
|
||||||
if [ "$BOOT" = "1" ]; then
|
|
||||||
echo "Emulator booted after $((i*2))s"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
echo "Boot waiting... ($i)"
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "--- emulator log tail ---"
|
|
||||||
tail -n 200 "$LOG" || true
|
|
||||||
|
|
||||||
echo "Building app..."
|
|
||||||
cd "$HOME/my_aprs_project/vs2"
|
|
||||||
chmod +x ./gradlew || true
|
|
||||||
./gradlew assembleDebug --no-daemon
|
|
||||||
|
|
||||||
APK="app/build/outputs/apk/debug/app-debug.apk"
|
|
||||||
if [ -f "$APK" ]; then
|
|
||||||
echo "Installing APK"
|
|
||||||
$ADB install -r "$APK" || true
|
|
||||||
$ADB shell am start -n com.example.aprs/.MainActivity || true
|
|
||||||
echo "App launched on emulator (check window)."
|
|
||||||
else
|
|
||||||
echo "APK not found: $APK"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Done. ADB devices:"; $ADB devices -l
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "This script installs Android command-line tools, creates an AVD, starts an emulator, builds and installs the app. You will be asked for sudo password for package installation."
|
|
||||||
|
|
||||||
# 1) system packages (requires sudo)
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y openjdk-11-jdk unzip curl qemu-kvm libvirt-daemon-system libvirt-clients
|
|
||||||
|
|
||||||
export ANDROID_SDK_ROOT="$HOME/Android/Sdk"
|
|
||||||
mkdir -p "$ANDROID_SDK_ROOT/cmdline-tools"
|
|
||||||
cd /tmp
|
|
||||||
|
|
||||||
CLI_ZIP=commandlinetools-linux.zip
|
|
||||||
if [ ! -f "$CLI_ZIP" ]; then
|
|
||||||
echo "Downloading Android command-line tools..."
|
|
||||||
curl -L -o "$CLI_ZIP" https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip
|
|
||||||
fi
|
|
||||||
|
|
||||||
unzip -o "$CLI_ZIP" -d "$ANDROID_SDK_ROOT/cmdline-tools/temp"
|
|
||||||
rm -rf "$ANDROID_SDK_ROOT/cmdline-tools/latest"
|
|
||||||
mv "$ANDROID_SDK_ROOT/cmdline-tools/temp" "$ANDROID_SDK_ROOT/cmdline-tools/latest"
|
|
||||||
|
|
||||||
export PATH="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/emulator:$PATH"
|
|
||||||
|
|
||||||
echo "Installing SDK packages (this will download several hundred MB)..."
|
|
||||||
yes | "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" --sdk_root="$ANDROID_SDK_ROOT" "platform-tools" "platforms;android-33" "build-tools;33.0.0" "emulator" "system-images;android-33;google_apis;x86_64"
|
|
||||||
|
|
||||||
yes | "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" --licenses --sdk_root="$ANDROID_SDK_ROOT"
|
|
||||||
|
|
||||||
AVD_NAME=aprs_avd
|
|
||||||
echo no | "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/avdmanager" create avd -n "$AVD_NAME" -k "system-images;android-33;google_apis;x86_64" --force
|
|
||||||
|
|
||||||
echo "Starting emulator in background (log -> /tmp/emulator_aprs.log). This may take 1-3 minutes."
|
|
||||||
nohup "$ANDROID_SDK_ROOT/emulator/emulator" -avd "$AVD_NAME" -no-window -no-audio -gpu swiftshader_indirect &>/tmp/emulator_aprs.log &
|
|
||||||
|
|
||||||
echo "Waiting for emulator to boot..."
|
|
||||||
adb wait-for-device
|
|
||||||
for i in {1..60}; do
|
|
||||||
BOOT_DONE=$(adb shell getprop sys.boot_completed 2>/dev/null | tr -d '\r') || BOOT_DONE=""
|
|
||||||
if [ "$BOOT_DONE" = "1" ]; then
|
|
||||||
echo "Emulator booted"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Building app with Gradle wrapper (may take several minutes)..."
|
|
||||||
cd "$HOME/my_aprs_project/vs2"
|
|
||||||
chmod +x ./gradlew || true
|
|
||||||
./gradlew assembleDebug --no-daemon
|
|
||||||
|
|
||||||
APK_PATH="app/build/outputs/apk/debug/app-debug.apk"
|
|
||||||
if [ -f "$APK_PATH" ]; then
|
|
||||||
echo "Installing APK to emulator..."
|
|
||||||
adb install -r "$APK_PATH"
|
|
||||||
adb shell am start -n com.example.aprs/.MainActivity || true
|
|
||||||
echo "Done: app installed and launched on emulator"
|
|
||||||
echo "If emulator has no window, you can run Android Studio emulator GUI or remove -no-window flag in this script to display it."
|
|
||||||
else
|
|
||||||
echo "APK not found: $APK_PATH"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
Reference in New Issue
Block a user