仅在用户在计算机时显示通知

时间:2012-10-10 00:27:19

标签: xcode macos cocoa osx-mountain-lion

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

例如,想象一下股票交易应用程序,它会向用户发出可能仅与几分钟相关的各种时间敏感信息。如果用户远离他们的计算机,他们不希望找到20个未采取行动的警报来解雇。

3 个答案:

答案 0 :(得分:8)

如果要连接ApplicationServices或更高版本,请尝试:

CFTimeInterval idleTime = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGAnyInputEventType);

自上次事件源事件以来的时间。

kCGAnyInputEventType eventType将报告任何输入事件,键盘,鼠标或平板电脑的最后时间戳。各种系统和应用程序定义的事件不会影响此事件类型的时间。

同样,在登录会话中发布的程序或应用程序应该使用kCGEventSourceStateCombinedSessionState。

解释硬件状态和生成事件的用户空间设备驱动程序应使用kCGEventSourceStateHIDSystemState。

CG_EXTERN CFTimeInterval CGEventSourceSecondsSinceLastEventType(CGEventSourceStateID source,CGEventType eventType)AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;

答案 1 :(得分:7)

技术我不知道如何监视不活动但我认为您可以使用超时通知在一段时间间隔后关闭自己和/或将显示的通知限制为少,所以最新的通知将自动关闭最旧的通知

来自apple documentation

  

注意:用户在预定后超过15分钟醒来   通知被安排开火,它被丢弃。如果   通知以小于15分钟的间隔重复,然后它   1分钟后到期。除非过期通知被丢弃   他们重复一遍,在这种情况下,他们会留在预定的名单中   之后再次开火。

答案 2 :(得分: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;
}