如何检查用户是否在 UWP 上空闲? [英] How to check if user is idle on UWP?

查看:27
本文介绍了如何检查用户是否在 UWP 上空闲?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做一个函数,如果用户空闲一段时间,它会超时并导航到主页.经过一番研究,我发现 ThreadPoolTimer 应该适合我的需求.测试它我决定使用 10 秒的间隔.

I wanted to make a function that would timeout and navigate to the main page if the user is idle for a certain period of time. After a little research, I found that the ThreadPoolTimer should suit my needs. Testing it I decided to use a 10 sec interval.

    timer =ThreadPoolTimer.CreatePeriodicTimer(Timer_Tick,TimeSpan.FromSeconds(10));

这就是我不知所措的地方.我想不出一种方法来检查 UWP 上的用户输入,而不必单独检查 PointerPressed、PointerExited 等.所以我做了更多的挖掘,发现了一段代码,如果用户是否空闲.

And this is where I'm at a loss. I couldn't figure out a way to check user input on a UWP without having to individually check PointerPressed, PointerExited, etc. So I did some more digging and I found a block of code that's supposed to give you a boolean value if the user is idle or not.

    public static uint GetIdleTime()
    {
        LASTINPUTINFO lastInPut = new LASTINPUTINFO();
        lastInPut.cbSize = (uint)Marshal.SizeOf(lastInPut);
        GetLastInputInfo(ref lastInPut);

        return ((uint)Environment.TickCount - lastInPut.dwTime);
    }

    public static bool IsUserIdle()
    {
        uint idleTime = (uint)Environment.TickCount - GetLastInputEventTickCount();
       if (idleTime > 0)
       {
           idleTime = (idleTime / 1000);
       }
       else
       {
           idleTime = 0;
       }
       //user is idle for 10 sec
       bool b = (idleTime >= 10);
       return b;
    }

    private static uint GetLastInputEventTickCount()
    {
        LASTINPUTINFO lii = new LASTINPUTINFO();
        lii.cbSize = (uint)Marshal.SizeOf(lii);
        lii.dwTime = 0;
        uint p = GetLastInputInfo(ref lii) ? lii.dwTime : 0;
        return p;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct LASTINPUTINFO
    {
        public static readonly int SizeOf = Marshal.SizeOf<LASTINPUTINFO>();
        [MarshalAs(UnmanagedType.U4)]
        public UInt32 cbSize;
        [MarshalAs(UnmanagedType.U4)]
        public UInt32 dwTime;
    }

    [DllImport("user32.dll")]
    private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

然后我调用 tick 函数中的函数,并在 IsUserIdle() 等于 true 时使用条件语句,然后导航到主页.

I then call the function in the tick function and use the conditional statement if IsUserIdle() is equal to true then navigate to the main page.

    public static void Timer_Tick(object sender)
    {
       if (IsUserIdle() == true)
       {
           Frame.Navigate(typeof(MainPage));
       }                                        
    }

但是当我启动它时什么也没有发生,在我设置了几个断点后,我发现 IsUserIdle() 即使在 10 秒不活动后也永远不会返回真值.我完全被困住了,所以任何帮助将不胜感激.

But when I start it nothing happens, and after I set a couple breakpoints I found that IsUserIdle() never returns a true value even after 10 sec of inactivity. I am completely stuck so any help would be appreciated.

推荐答案

GetLastInputInfo 不支持 Windows 商店应用:

GetLastInputInfo isn't supported for Windows store apps:

支持的最低客户端:Windows 2000 Professional [仅限桌面应用]

Minimum supported client: Windows 2000 Professional [desktop apps only]

我不知道有任何内在的 UWP API 来检测用户是否空闲,但绝对可以开发自己的机制来这样做.

I'm not aware of any intrinsic UWP API to detect if the user is idle, but it's definitely possible to whip up your own mechanism for doing so.

我想不出一种方法来检查 UWP 上的用户输入,而不必单独检查 PointerPressed、PointerExited 等.

I couldn't figure out a way to check user input on a UWP without having to individually check PointerPressed, PointerExited, etc.

这种方法有什么不好?这是我的尝试:

What's so bad about that approach? Here's my attempt:

App.xaml.cs

public sealed partial class App : Application
{
    public static new App Current => (App)Application.Current;

    public event EventHandler IsIdleChanged;

    private DispatcherTimer idleTimer;

    private bool isIdle;
    public bool IsIdle
    {
        get
        {
            return isIdle;
        }

        private set
        {
            if (isIdle != value)
            {
                isIdle = value;
                IsIdleChanged?.Invoke(this, EventArgs.Empty);
            }
        }
    }

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        idleTimer = new DispatcherTimer();
        idleTimer.Interval = TimeSpan.FromSeconds(10);  // 10s idle delay
        idleTimer.Tick += onIdleTimerTick;
        Window.Current.CoreWindow.PointerMoved += onCoreWindowPointerMoved;
    }

    private void onIdleTimerTick(object sender, object e)
    {
        idleTimer.Stop();
        IsIdle = true;
    }

    private void onCoreWindowPointerMoved(CoreWindow sender, PointerEventArgs args)
    {
        idleTimer.Stop();
        idleTimer.Start();
        IsIdle = false;
    }
}

MainPage.xaml.cs

public sealed partial class MainPage : Page
{
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        App.Current.IsIdleChanged += onIsIdleChanged;
    }

    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        App.Current.IsIdleChanged -= onIsIdleChanged;
    }

    private void onIsIdleChanged(object sender, EventArgs e)
    {
        System.Diagnostics.Debug.WriteLine($"IsIdle: {App.Current.IsIdle}");
    }
}

当指针在应用程序窗口内 10 秒没有移动时检测到空闲.这也适用于仅触摸的应用(如移动应用),因为 PointerMoved 也会在点击窗口时触发.

Idle is detected when the pointer hasn't moved for 10s within the app window. This will work also for touch-only apps (like mobile apps) because PointerMoved will fire when the window is tapped, too.

这篇关于如何检查用户是否在 UWP 上空闲?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆