7

私のココアアプリはバックグラウンドタスクを実行します。これは、ユーザーがアイドル状態(キーボード/マウス入力なし)になったときに停止し、ユーザーが再びアクティブになったときに再開したいと考えています。アイドル状態の通知に登録する方法はありますか?

4

4 に答える 4

6

と呼ばれる特定の期間後にユーザーイベントが発生しなかった場合に通知を送信するCarbonAPIがありますEventLoopIdleTimer。Uli KustererがここにCocoaラッパーを作成しました(UKIdleTimerを探してください)

より低いレベルが必要な場合は、タイマーとCoreGraphics関数CGEventSourceSecondsSinceLastEventType(で使用可能<CoreGraphics/CGEventSource.h>)を組み合わせて、必要な動作を実装できる場合があります。

于 2011-01-10T04:44:49.877 に答える
6

Carbonにリンクできない場合(つまり、x86_64ビットバイナリをコンパイルする場合)、この関数(現在のアイドル時間を秒単位の解像度でdoubleとして返す--CFTimeInterval)をタイマーでラップできます。

#include <IOKit/IOKitLib.h>

CFTimeInterval CFDateGetIdleTimeInterval() {
    mach_port_t port;
    io_iterator_t iter;
    CFTypeRef value = kCFNull;
    uint64_t idle = 0;
    CFMutableDictionaryRef properties = NULL;
    io_registry_entry_t entry;

    IOMasterPort(MACH_PORT_NULL, &port);
    IOServiceGetMatchingServices(port, IOServiceMatching("IOHIDSystem"), &iter);
    if (iter) {
        if ((entry = IOIteratorNext(iter))) {
            if (IORegistryEntryCreateCFProperties(entry, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties) {
                if (CFDictionaryGetValueIfPresent(properties, CFSTR("HIDIdleTime"), &value)) {
                    if (CFGetTypeID(value) == CFDataGetTypeID()) {
                        CFDataGetBytes(value, CFRangeMake(0, sizeof(idle)), (UInt8 *) &idle);
                    } else if (CFGetTypeID(value) == CFNumberGetTypeID()) {
                        CFNumberGetValue(value, kCFNumberSInt64Type, &idle);
                    }
                }
                CFRelease(properties);
            }
            IOObjectRelease(entry);
        }
        IOObjectRelease(iter);
    }

    return idle / 1000000000.0;
}

コードをにリンクする必要がありますIOKit.framework

于 2012-01-06T09:34:04.307 に答える
1

私は別のアプローチを使用しました。UIApplicationのサブクラス化sendEventメソッドのフィルタリングタッチをオーバーライドします(実際には、あらゆる種類のイベント、アクセラレーション、タッチなどをフィルタリングできます)。共有変数とバックグラウンドタイマーを使用して、「アイドル」を管理しました。ユーザーが画面に触れるたびに、変数は現在のtimeInterval(現在の時間)で設定されます。タイマー起動メソッドは、最後のタッチからの経過時間をチェックします。しきい値(私の場合は約90秒)よりも大きい場合は、独自の通知をPOSTできます。

この単純なアプローチを使用して、アイドル時間の後に自動的に「スクリーンセーバー」アプリを呼び出すカスタムアプリのセットを作成しました。

賢いことは何もありません、それはただ仕事をします。

お役に立てば幸いです。

于 2012-02-22T21:04:01.817 に答える
1

Appleの技術的なQ&A QA1340睡眠と覚醒の通知の登録と登録解除は、あなたが探しているものかもしれません。

NSWorkspaceWillSleepNotification (リスト1)よりも詳細な制御が必要な場合は、I / Oキットを使用して登録し、電源通知を受信します(リスト3)。

于 2011-01-10T04:25:58.017 に答える