Реализация Shake-to-Report (отправка бага встряхиванием) в мобильном приложении

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Реализация Shake-to-Report (отправка бага встряхиванием) в мобильном приложении
Средняя
от 1 рабочего дня до 3 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Реализация Shake-to-Report (отправка бага встряхиванием) в мобильном приложении

Shake-to-Report — это паттерн, при котором пользователь или тестировщик встряхивает устройство и получает форму отправки бага с автоматически захваченным скриншотом и диагностической информацией. Внутри команды — удобнее TestFlight feedback. Для beta-тестеров — намного ниже порог входа, чем заполнять форму вручную.

Детектирование встряхивания

iOS

// UIWindow subclass для перехвата shake
class FeedbackWindow: UIWindow {
    override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        if motion == .motionShake {
            FeedbackManager.shared.presentFeedbackForm()
        }
        super.motionEnded(motion, with: event)
    }
}

// Использование в SceneDelegate
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
    options connectionOptions: UIScene.ConnectionOptions) {
    if let windowScene = scene as? UIWindowScene {
        window = FeedbackWindow(windowScene: windowScene)
        window?.rootViewController = UIHostingController(rootView: ContentView())
        window?.makeKeyAndVisible()
    }
}

Переопределение UIWindow — стандартный подход, не требует SwiftUI-specific кода и работает с любой архитектурой.

Android — акселерометр

На Android нет встроенного события «shake» — детектируем через акселерометр:

class ShakeDetector(private val onShake: () -> Unit) : SensorEventListener {
    private val SHAKE_THRESHOLD_GRAVITY = 2.7f
    private val SHAKE_SLOP_TIME_MS = 500
    private var lastShakeMs: Long = 0

    override fun onSensorChanged(event: SensorEvent) {
        val gX = event.values[0] / SensorManager.GRAVITY_EARTH
        val gY = event.values[1] / SensorManager.GRAVITY_EARTH
        val gZ = event.values[2] / SensorManager.GRAVITY_EARTH
        val gForce = sqrt(gX * gX + gY * gY + gZ * gZ.toDouble()).toFloat()

        if (gForce > SHAKE_THRESHOLD_GRAVITY) {
            val now = System.currentTimeMillis()
            if (lastShakeMs + SHAKE_SLOP_TIME_MS > now) return
            lastShakeMs = now
            onShake()
        }
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
}

// Регистрация в Activity/Fragment
val sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
val shakeDetector = ShakeDetector { showFeedbackDialog() }
sensorManager.registerListener(
    shakeDetector,
    sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
    SensorManager.SENSOR_DELAY_UI
)

SHAKE_SLOP_TIME_MS = 500 предотвращает многократный вызов от одного встряхивания. Threshold 2.7g — компромисс между чувствительностью и ложными срабатываниями при ходьбе.

Контекст, который собирается автоматически

При встряхивании до показа UI:

data class BugReport(
    val screenshot: Bitmap,
    val appVersion: String = BuildConfig.VERSION_NAME,
    val buildNumber: String = BuildConfig.VERSION_CODE.toString(),
    val osVersion: String = "Android ${Build.VERSION.RELEASE}",
    val device: String = "${Build.MANUFACTURER} ${Build.MODEL}",
    val currentScreen: String = screenTracker.currentScreenName,
    val recentLogs: List<String> = LogBuffer.getLast(50),  // последние 50 строк лога
    val memoryInfo: String = getMemoryInfo(),
    val networkType: String = getNetworkType()
)

recentLogs — если в приложении настроен in-memory log buffer (Timber tree, записывающий в кольцевой буфер), баг-репорт сразу содержит последние события. Разработчик видит всё, что происходило за 30 секунд до встряхивания.

Режимы доступности

Shake неудобен для пользователей с тремором или тех, кто держит устройство на столе. Для QA и beta-программ добавляем альтернативные триггеры:

  • Долгое нажатие на логотип или версию в «О приложении»
  • Скрытое меню через тройной тап по пустой области экрана
  • Жест двумя пальцами (3 пальца, 3 тапа)

Shake обычно отключают в production или делают опциональным через developer settings — чтобы обычный пользователь не открывал форму случайно.

Готовые инструменты

Инструмент Платформы Особенности
Instabug iOS, Android, Flutter, RN Shake + screen recording, Jira/Slack интеграции
Shake.io iOS, Android Встроенный тред-модель обсуждения
BugShaker iOS (open source) Простой, email-only
Собственная реализация Любые Полный контроль, без внешних зависимостей

Instabug — промышленный стандарт для мобильных QA-команд. Собственная реализация оправдана, если нужно контролировать, какие данные покидают устройство.

Ориентиры по срокам

Кастомная реализация shake-детектора с захватом скриншота и отправкой в Jira — 3–5 дней. Интеграция Instabug с кастомной темой и настройкой маршрутизации репортов — 1–2 дня.