5

检测用户当前是否在他们的计算机上的最佳方法是什么,即以某种方式使用它。我们有一个应用程序,如果用户在他们的计算机上,它应该只发布通知(带有关闭按钮的横幅通知)。

例如,想象一个股票交易应用程序,它会提醒用户注意可能仅在几分钟内相关的各种时间敏感信息。如果用户远离他们的计算机,他们不希望找到 20 个未执行的警报来关闭。

4

3 回答 3

8

如果链接到 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;

于 2012-10-11T00:35:03.857 回答
7

从技术上讲,我不知道如何观察不活动,但我认为您可以使用超时通知在一段时间间隔后自行关闭和/或将显示的通知限制为很少,因此最新的通知会自动关闭最旧的通知。

苹果文档

注意:如果用户在预定的通知计划触发后超过 15 分钟醒来,则将其丢弃。如果通知以小于 15 分钟的间隔重复,则它会在 1 分钟后过期。过期的通知只会被丢弃,除非它们重复,在这种情况下,它们会留在预定列表中,稍后再触发。

于 2012-10-10T00:34:11.547 回答
2

相反,您可以检查用户的空闲时间。假设用户离开她的计算机并走开,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;
}
于 2012-10-10T10:20:26.320 回答