glasses: пассивный Accessibility-сервис (авто-запуск + живучесть) + TASKS.md с планом
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
package pw.binom.rayneovm.glasses
|
||||
|
||||
import android.accessibilityservice.AccessibilityService
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import android.view.accessibility.AccessibilityEvent
|
||||
|
||||
/**
|
||||
* Пассивный Accessibility-сервис GlassesApp.
|
||||
*
|
||||
* Зачем: Accessibility-сервис — единственный «легальный» способ для обычного
|
||||
* приложения (без root/Shizuku/system-app) получить:
|
||||
* - живучесть процесса: систему сама поднимает и перезапускает сервис,
|
||||
* - возможность открывать Activity из фона,
|
||||
* - [onAccessibilityEvent] (в будущем — для отслеживания фокуса ввода и клавиатуры, задача #4).
|
||||
*
|
||||
* ВАЖНО: сервис НИЧЕГО не делает с чужими окнами — не читает содержимое
|
||||
* ([android:canRetrieveWindowContent] = false) и не инжектит события. Это
|
||||
* сознательно: минимум привилегий, минимум риска сломать ввод в гостевых приложениях.
|
||||
*
|
||||
* Регистрируется в манифесте через [VM_ACCESSIBILITY_SERVICE] с конфигом
|
||||
* `res/xml/vm_accessibility_service.xml`. Активируется пользователем вручную:
|
||||
* Настройки → Специальные возможности → RayNeo VM.
|
||||
*/
|
||||
class VmAccessibilityService : AccessibilityService() {
|
||||
|
||||
override fun onServiceConnected() {
|
||||
super.onServiceConnected()
|
||||
Log.i(TAG, "Accessibility-сервис подключён")
|
||||
// Авто-старт: если основное приложение ещё не поднято — поднимаем его.
|
||||
// Это и есть «легальный авто-запуск» из задачи #5.
|
||||
runCatching { startActivity(Intent(this, MainActivity::class.java).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}) }
|
||||
.onSuccess { Log.i(TAG, "MainActivity запущена из Accessibility-сервиса") }
|
||||
.onFailure { Log.w(TAG, "Не удалось запустить MainActivity: ${it.message}") }
|
||||
}
|
||||
|
||||
override fun onAccessibilityEvent(event: AccessibilityEvent?) {
|
||||
// Намеренно пусто. Слушаем только для того, чтобы сервис считался живым.
|
||||
// Тут позже появится логика задачи #4 (фокус поля ввода → скрыть IME гостя).
|
||||
}
|
||||
|
||||
override fun onInterrupt() {
|
||||
// Ничего: сервис не выполняет длительных операций.
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "VmAccessibilitySvc"
|
||||
|
||||
/** Действие для запроса состояния сервиса/проверки активности (диагностика). */
|
||||
const val ACTION_PING = "pw.binom.rayneovm.glasses.ACCESSIBILITY_PING"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user