UWP 上的 Accelerometer.Shaken 事件不起作用,有啥解决方案吗?

Posted

技术标签:

【中文标题】UWP 上的 Accelerometer.Shaken 事件不起作用,有啥解决方案吗?【英文标题】:Accelerometer.Shaken event on UWP not working, any solutions?UWP 上的 Accelerometer.Shaken 事件不起作用,有什么解决方案吗? 【发布时间】:2016-05-06 15:18:12 【问题描述】:

我试图为 Accelerometer.Shaken 事件实现某种处理程序,然后我发现 Windows 10 尚不支持此事件,这可以从 answer here 中看出。

现在,即使抖动事件不起作用,Accelerometer.ReadingChanged 事件也可以正常工作。 所以我在想,是否可以从该数据中手动检测摇晃手势?我的意思是,这可能是可能的,但我真的不知道从哪里开始,有人有想法吗?

您每 x 毫秒获取一次 X、Y 和 Z 坐标,必须有某种方法可以根据该数据计算摇动手势。

感谢您的帮助!

【问题讨论】:

你可以看到它在移动。什么样的运动与“摇晃”相关,由您决定和实施。平板电脑比小型手机更难摇动。好吧,除非你放下它,它会弹跳:) @HansPassant 是的,我想我可以添加一些设置,让用户决定在引发自定义 Shaken 事件之前达到的阈值级别,感谢您的建议! 【参考方案1】:

没关系,我最终编写了自己的课程来解决这个问题,我会把它留在这里以防它对其他人有用:

/// <summary>
/// A static class that manages the Shaken event for the Accelerometer class
/// </summary>
public static class CustomAccelerometer

    // The minimum acceleration value to trigger the Shaken event
    private const double AccelerationThreshold = 2;

    // The minimum interval in milliseconds between two consecutive calls for the Shaken event
    private const int ShakenInterval = 500;

    private static bool _AccelerometerLoaded;

    private static Accelerometer _DefaultAccelerometer;

    /// <summary>
    /// Gets the current Accelerometer in use
    /// </summary>
    private static Accelerometer DefaultAccelerometer
    
        get
        
            if (!_AccelerometerLoaded)
            
                _AccelerometerLoaded = true;
                _DefaultAccelerometer = Accelerometer.GetDefault();
            
            return _DefaultAccelerometer;
        
    

    private static DateTime _ShakenTimespan = DateTime.Now;

    private static bool _Enabled;

    /// <summary>
    /// Gets or sets whether or not the Accelerometer is currently enabled and can raise the Shaken event
    /// </summary>
    public static bool Enabled
    
        get  return _Enabled; 
        set
        
            if (_Enabled != value && DefaultAccelerometer != null)
            
                if (value) DefaultAccelerometer.ReadingChanged += _DefaultAccelerometer_ReadingChanged;
                else DefaultAccelerometer.ReadingChanged -= _DefaultAccelerometer_ReadingChanged;
            
            _Enabled = value;
        
    

    // Handles the ReadingChanged event and raises the Shaken event when necessary
    private static void _DefaultAccelerometer_ReadingChanged(Accelerometer sender, AccelerometerReadingChangedEventArgs args)
    
        double g = Math.Round(args.Reading.AccelerationX.Square() + args.Reading.AccelerationY.Square() + args.Reading.AccelerationZ.Square());
        if (g > AccelerationThreshold && DateTime.Now.Subtract(_ShakenTimespan).Milliseconds > ShakenInterval)
        
            _ShakenTimespan = DateTime.Now;
            Shaken?.Invoke(null, EventArgs.Empty);
        
    

    /// <summary>
    /// Raised whenever the Accelerometer detects a shaking gesture
    /// </summary>
    public static event EventHandler Shaken;

要使用它,只需启用它并订阅它的事件:

CustomAccelerometer.Enabled = true;
CustomAccelerometer.Shaken += (s, e) =>

    Debug.WriteLine("The device was shaken!");
;

编辑:忘记添加Square方法代码,这里是:

/// <summary>
/// Returns the square of the given double value
/// </summary>
/// <param name="value">The input value</param>
public static double Square(this double value) => value * value;

【讨论】:

答案看起来很有趣。我只是不确定如何使用它。我创建了 Microsoft 拥有的示例加速度计示例 here。根据我到目前为止所做的(在那个例子中),我只是不确定如何使用你的解决方案。 @ThePeter 我在我的回答中添加了一个小代码示例,使用这个帮助类非常简单。只需启用它并订阅它的静态事件,就可以了。 @Cabuxa.Mapache 哦,这只是我忘记包含在 sn-p 中的一个扩展方法,它只需要一个双精度值并返回它的平方值 (n => n * n)。我也会用扩展代码编辑答案:)

以上是关于UWP 上的 Accelerometer.Shaken 事件不起作用,有啥解决方案吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 Xbox 上的 UWP 应用中模拟游戏手柄输入

在 uwp 中模拟 fontIcon 上的鼠标悬停效果

自定义选择器 C# UWP 上的多项选择

如何在 UWP 中更改图像鼠标悬停上的图像

UWP - 我无法从 UI 线程编辑 Application 类上的字段

UWP 应用程序从系统上的随机位置访问文件