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 に答える