检测用户当前是否在他们的计算机上的最佳方法是什么,即以某种方式使用它。我们有一个应用程序,如果用户在他们的计算机上,它应该只发布通知(带有关闭按钮的横幅通知)。
例如,想象一个股票交易应用程序,它会提醒用户注意可能仅在几分钟内相关的各种时间敏感信息。如果用户远离他们的计算机,他们不希望找到 20 个未执行的警报来关闭。
检测用户当前是否在他们的计算机上的最佳方法是什么,即以某种方式使用它。我们有一个应用程序,如果用户在他们的计算机上,它应该只发布通知(带有关闭按钮的横幅通知)。
例如,想象一个股票交易应用程序,它会提醒用户注意可能仅在几分钟内相关的各种时间敏感信息。如果用户远离他们的计算机,他们不希望找到 20 个未执行的警报来关闭。
如果链接到 ApplicationServices 或更高版本,请尝试:
CFTimeInterval idleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGAnyInputEventType);
自事件源的最后一个事件以来的时间。
kCGanyInputEventType eventType 将报告任何输入事件、键盘、鼠标或平板电脑的最后时间戳。各种系统和应用程序定义的事件不影响此事件类型的时间。
同样,从登录会话中发布的程序或应用程序应该使用 kCGEventSourceStateCombinedSessionState。
解释硬件状态和生成事件的用户空间设备驱动程序应使用 kCGEventSourceStateHIDSystemState。
CG_EXTERN CFTimeInterval CGEventSourceSecondsSinceLastEventType( CGEventSourceStateID 源, CGEventType eventType ) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
从技术上讲,我不知道如何观察不活动,但我认为您可以使用超时通知在一段时间间隔后自行关闭和/或将显示的通知限制为很少,因此最新的通知会自动关闭最旧的通知。
从苹果文档:
注意:如果用户在预定的通知计划触发后超过 15 分钟醒来,则将其丢弃。如果通知以小于 15 分钟的间隔重复,则它会在 1 分钟后过期。过期的通知只会被丢弃,除非它们重复,在这种情况下,它们会留在预定列表中,稍后再触发。
相反,您可以检查用户的空闲时间。假设用户离开她的计算机并走开,IOKit 将在 HID(人机接口设备)上报告空闲时间。代码看起来像:
int64_t getIdleTime(void) {
io_iterator_t iter;
int64_t idle = 0;
// Step 1: Prepare a matching dictionary for "IOHIDSystem", which is the I/O Kit
// class which we will query
if (IOServiceGetMatchingServices
(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"), &iter) == KERN_SUCCESS)
{
io_registry_entry_t entry = IOIteratorNext(iter);
// Step 2: If we get the classes, get the property:
if (entry) {
CFMutableDictionaryRef dict;
// Query the HIDIdleTime property, if present.
if (IORegistryEntryCreateCFProperties(entry, &dict, kCFAllocatorDefault, 0) == KERN_SUCCESS)
{
CFNumberRef prop = (CFNumberRef) CFDictionaryGetValue(dict, CFSTR("HIDIdleTime"));
if (prop) {
int64_t nsIdle;
// Value is in Nanoseconds, you might want to convert
if (CFNumberGetValue(prop, kCFNumberSInt64Type, &nsIdle)) {
idle = (nsIdle / 1000000000);
}
}
CFRelease(dict); // Be nice. Clean up
}
IOObjectRelease(entry); // as well as here..
}
IOObjectRelease(iter); // and here..
}
return idle;
}