This commit is contained in:
198
docs/MOBILE_QUICK_START.md
Normal file
198
docs/MOBILE_QUICK_START.md
Normal file
@@ -0,0 +1,198 @@
|
||||
# 🚀 БЫСТРЫЙ СТАРТ: Интеграция Emergency Service в мобильное приложение
|
||||
|
||||
## 📋 КРАТКИЙ ЧЕКЛИСТ (30 минут)
|
||||
|
||||
### 1️⃣ УДАЛИТЕ ВРЕМЕННЫЕ ТОКЕНЫ (5 мин)
|
||||
```kotlin
|
||||
// ❌ УДАЛИТЬ:
|
||||
val tempToken = "temp_token_for_${email}"
|
||||
|
||||
// ✅ ЗАМЕНИТЬ:
|
||||
val jwtToken = authManager.getValidJwtToken()
|
||||
```
|
||||
|
||||
### 2️⃣ ДОБАВЬТЕ JWT АУТЕНТИФИКАЦИЮ (10 мин)
|
||||
```kotlin
|
||||
// Добавить в build.gradle
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1'
|
||||
|
||||
// Простая авторизация
|
||||
suspend fun login(email: String, password: String): String? {
|
||||
val response = apiService.login(LoginRequest(email, password))
|
||||
return if (response.isSuccessful) {
|
||||
response.body()?.access_token
|
||||
} else null
|
||||
}
|
||||
```
|
||||
|
||||
### 3️⃣ НАСТРОЙТЕ WEBSOCKET (10 мин)
|
||||
```kotlin
|
||||
val token = getJwtToken()
|
||||
val wsUrl = "ws://YOUR_SERVER:8002/api/v1/emergency/ws/current_user_id?token=$token"
|
||||
|
||||
val client = OkHttpClient()
|
||||
val request = Request.Builder().url(wsUrl).build()
|
||||
val webSocket = client.newWebSocket(request, object : WebSocketListener() {
|
||||
override fun onMessage(webSocket: WebSocket, text: String) {
|
||||
// Обработка сообщений от сервера
|
||||
handleEmergencyMessage(text)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 4️⃣ ДОБАВЬТЕ API CALLS (5 мин)
|
||||
```kotlin
|
||||
// Создание экстренного вызова
|
||||
suspend fun createAlert(latitude: Double, longitude: Double, description: String) {
|
||||
val alert = CreateAlertRequest("medical", latitude, longitude, null, description)
|
||||
val response = emergencyApi.createAlert(alert, "Bearer $jwtToken")
|
||||
// Обработка ответа
|
||||
}
|
||||
|
||||
// Получение списка вызовов
|
||||
suspend fun getMyAlerts() {
|
||||
val response = emergencyApi.getMyAlerts("Bearer $jwtToken")
|
||||
// Обработка списка
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ ОСНОВНЫЕ ENDPOINTS
|
||||
|
||||
### Аутентификация:
|
||||
```
|
||||
POST http://YOUR_SERVER:8000/api/v1/auth/login
|
||||
Body: {"email": "user@example.com", "password": "password"}
|
||||
Response: {"access_token": "JWT_TOKEN", "user": {...}}
|
||||
```
|
||||
|
||||
### Emergency API (все с Bearer JWT токеном):
|
||||
```
|
||||
POST http://YOUR_SERVER:8002/api/v1/alert - Создать вызов
|
||||
GET http://YOUR_SERVER:8002/api/v1/alerts/my - Мои вызовы
|
||||
GET http://YOUR_SERVER:8002/api/v1/alerts/active - Активные вызовы
|
||||
GET http://YOUR_SERVER:8002/api/v1/alerts/nearby?lat=55.7&lon=37.6&radius=5 - Ближайшие
|
||||
POST http://YOUR_SERVER:8002/api/v1/alert/{id}/respond - Ответить на вызов
|
||||
POST http://YOUR_SERVER:8002/api/v1/safety-check - Проверка безопасности
|
||||
```
|
||||
|
||||
### WebSocket:
|
||||
```
|
||||
ws://YOUR_SERVER:8002/api/v1/emergency/ws/current_user_id?token=JWT_TOKEN
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📱 МИНИМАЛЬНЫЙ КОД
|
||||
|
||||
### AuthManager.kt
|
||||
```kotlin
|
||||
class AuthManager {
|
||||
private var jwtToken: String? = null
|
||||
|
||||
suspend fun login(email: String, password: String): Boolean {
|
||||
val response = retrofit.create(AuthApi::class.java)
|
||||
.login(LoginRequest(email, password))
|
||||
|
||||
return if (response.isSuccessful) {
|
||||
jwtToken = response.body()?.access_token
|
||||
true
|
||||
} else false
|
||||
}
|
||||
|
||||
fun getJwtToken(): String? = jwtToken
|
||||
}
|
||||
```
|
||||
|
||||
### EmergencyManager.kt
|
||||
```kotlin
|
||||
class EmergencyManager(private val authManager: AuthManager) {
|
||||
private var webSocket: WebSocket? = null
|
||||
|
||||
fun connectWebSocket() {
|
||||
val token = authManager.getJwtToken() ?: return
|
||||
val wsUrl = "ws://YOUR_SERVER:8002/api/v1/emergency/ws/current_user_id?token=$token"
|
||||
|
||||
val request = Request.Builder().url(wsUrl).build()
|
||||
webSocket = OkHttpClient().newWebSocket(request, object : WebSocketListener() {
|
||||
override fun onMessage(webSocket: WebSocket, text: String) {
|
||||
handleMessage(text)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
suspend fun createAlert(lat: Double, lon: Double, description: String) {
|
||||
val token = authManager.getJwtToken() ?: return
|
||||
val alert = CreateAlertRequest("medical", lat, lon, null, description)
|
||||
|
||||
val response = emergencyApi.createAlert(alert, "Bearer $token")
|
||||
// Handle response
|
||||
}
|
||||
|
||||
private fun handleMessage(message: String) {
|
||||
val data = Json.decodeFromString<WebSocketMessage>(message)
|
||||
when (data.type) {
|
||||
"emergency_alert" -> showEmergencyNotification(data)
|
||||
"connection_established" -> onConnected()
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 ТЕСТИРОВАНИЕ
|
||||
|
||||
### Проверьте подключение:
|
||||
```bash
|
||||
# На сервере запустите тесты
|
||||
./venv/bin/python test_final_security.py
|
||||
```
|
||||
|
||||
### Тестовые данные:
|
||||
- **Server**: `http://192.168.219.108:8000` (замените на ваш IP)
|
||||
- **Email**: `shadow85@list.ru`
|
||||
- **Password**: `R0sebud1985`
|
||||
|
||||
### Быстрый тест в коде:
|
||||
```kotlin
|
||||
// В onCreate или init
|
||||
lifecycleScope.launch {
|
||||
val success = authManager.login("shadow85@list.ru", "R0sebud1985")
|
||||
if (success) {
|
||||
emergencyManager.connectWebSocket()
|
||||
Toast.makeText(this@MainActivity, "Connected!", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ ВАЖНЫЕ МОМЕНТЫ
|
||||
|
||||
1. **Замените IP адрес** `YOUR_SERVER` на реальный IP сервера
|
||||
2. **Удалите ВСЕ** `temp_token_` из кода
|
||||
3. **Добавьте разрешения** в AndroidManifest.xml:
|
||||
```xml
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
```
|
||||
|
||||
4. **Обработайте ошибки** сети и токенов
|
||||
5. **Сохраняйте токен** в зашифрованном виде
|
||||
|
||||
---
|
||||
|
||||
## 📞 ПРОБЛЕМЫ?
|
||||
|
||||
1. **WebSocket не подключается** → Проверьте JWT токен и URL
|
||||
2. **API возвращает 403** → Проверьте заголовок Authorization
|
||||
3. **API возвращает 500** → Проверьте формат данных в запросе
|
||||
4. **Нет уведомлений** → Проверьте WebSocket подключение
|
||||
|
||||
**Полная документация:** `MOBILE_APP_INTEGRATION_GUIDE.md`
|
||||
|
||||
**Готовые тесты сервера:** `test_final_security.py` - показывает, что все работает! ✅
|
||||
Reference in New Issue
Block a user