Разработка под Android в .NET MAUI. Встряхивание устройства

Встряхивание устройства отслеживается акселерометром (интерфейс — IAccelerometer). Для обнаружения тряски API .NET MAUI использует необработанные показания акселерометра для вычисления ускорения. Он использует простой механизм очереди для определения того, произошло ли 75% последних событий акселерометра за последние пол секунды. В этой части мы разберемся с тем, как отслеживать встряхивание устройства Android.

Событие встряхивания устройства

Событие ShakeDetected генерируется каждый раз, как только устройство встряхивается.

event EventHandler? ShakeDetected;

Сам алгоритм определения встряхнуто ли устройство или нет реализован в методе ProcessShakeEvent класса AccelerometerImplementation и выглядит следующим образом.

void ProcessShakeEvent(Vector3 acceleration)
{
    var now = Nanoseconds(DateTime.UtcNow);

    var x = acceleration.X * gravity;
    var y = acceleration.Y * gravity;
    var z = acceleration.Z * gravity;

    var g = x * x + y * y + z * z;
    queue.Add(now, g > accelerationThreshold);

    if (queue.IsShaking)
    {
        queue.Clear();
        var args = new EventArgs();

        if (useSyncContext)
            MainThread.BeginInvokeOnMainThread(() => ShakeDetected?.Invoke(null, args));
        else
            ShakeDetected?.Invoke(null, args);
    }

    static long Nanoseconds(DateTime time) =>
        (time.Ticks / TimeSpan.TicksPerMillisecond) * 1_000_000;
}

Пороговое значение accelerationThreshold, которое используется для проверки, выглядит следующим образом:

const double accelerationThreshold = 169;

Таким образом, дл того, чтобы наше приложение каким-либо образом отреагировало на встряхивание устройства, нам необходимо подписаться на событие ShakeDetected и отслеживать его срабатывание.

Встряхивание устройства

Определение необходимых разрешений

Так как используется обычный акселерометр, то и разрешение нам необходимо как и для всех прочих датчиков устройства — android.permission.HIGH_SAMPLING_RATE_SENSORS. Создадим новый проект .NET MAUI и добавим это разрешение, используя атрибут сборки:

using Android.App;
using Android.Runtime;

[assembly: UsesPermission(Android.Manifest.Permission.HighSamplingRateSensors)]

namespace MauiShake;

[Application]
public class MainApplication : MauiApplication
{
    public MainApplication(IntPtr handle, JniHandleOwnership ownership)
        : base(handle, ownership)
    {
    }

    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

Отслеживание встряхивания устройства

По сути, нам необходимо отследить только одно событие и отреагировать на него, поэтому, думаю, нет необходимости создавать в качестве примера отдельную модель представления — воспользуемся обычным code-behind. Откройте файл MainPage.xaml.cs и измените его следующим образом:

namespace MauiShake
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            Accelerometer.ShakeDetected += OnShake;
            Accelerometer.Default.Start(SensorSpeed.Fastest);
        }

        ~MainPage() 
        {
            Accelerometer.Default.Stop();
            Accelerometer.ShakeDetected += OnShake;
        }


        private async void OnShake(object? sender, EventArgs e)
        {
            await CounterBtn.ScaleTo(2);
            await CounterBtn.ScaleTo(1);
        }

    }

}

Здесь в обработчике события OnShake() выполняется анимация ScaleTo(), которая вначале увеличивает кнопку CounterBtn в 2 раза, а затем — возвращает размер к первоначальному значению.

В конструкторе класса мы подписываемся на событие ShakeDetected и запускаем датчик акселерометра:

public MainPage()
{
    InitializeComponent();
    Accelerometer.ShakeDetected += OnShake;
    Accelerometer.Default.Start(SensorSpeed.Fastest);
}

а в деструкторе — не забываем отписаться от события и отключить датчик:

~MainPage() 
{
    Accelerometer.Default.Stop();
    Accelerometer.ShakeDetected += OnShake;
}

На этом пример окончен — код XAML страницы MainPage можно не менять и оставить так, как он был в шаблоне проекта. Теперь можно запустить приложение и потрясти устройство — вы увидите, как кнопка меняет свой размер.

Итого

Встряхивание устройства отслеживается в .NET MAUI программно через данные акселерометра. Для того, чтобы приложение могло отреагировать на встряхивание, необходимо подписаться на событие ShakeDetected акселерометра.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии