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));
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);
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));
}
}
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 isn't supported for Windows store apps:
Minimum supported client: Windows 2000 Professional [desktop apps only]
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.
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}");
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With