2011-01-10 30 views

Trả lời

6

Trong trường hợp bạn không thể liên kết đến Carbon (. Tức là bạn muốn biên dịch x86_64 bit nhị phân), bạn có thể quấn chức năng này (mà trả về thời gian nhàn rỗi hiện nay ở độ phân giải giây như đôi - CFTimeInterval) trong một giờ:

#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; 
} 

Bạn sẽ cần liên kết mã của mình với IOKit.framework

+0

Chỉnh sửa nhỏ, mục nhập = IOIteratorNext (tầng) phải là mục nhập = IOIteratorNext (lặp). – Shaun

+0

Xin lưu ý rằng HIDIdleTime không phải là rất đáng tin cậy và nó luôn luôn trả về số không trên một số máy Mac không rõ lý do (có lẽ một số thiết bị kết nối thiết lập lại số thời gian nhàn rỗi). –

0

Apple Technical Q&A QA1340 Registering and unregistering for sleep and wake notifications có thể là những gì bạn đang tìm kiếm.

Nếu bạn cần kiểm soát nhiều hơn NSWorkspaceWillSleepNotification (Liệt kê 1), sử dụng I/O Kit và đăng ký để nhận thông báo nguồn (Liệt kê 3).

+0

Sự cố với tùy thuộc vào thông báo ngủ/thức là nếu người dùng đặt cài đặt ngủ của họ thành "không bao giờ", chúng sẽ không bao giờ được gửi. Tôi muốn đếm thời gian rảnh rỗi khi không có hoạt động bàn phím/chuột. – David

+0

Xin lỗi, mặc dù bạn có nghĩa là khi ứng dụng vào giấc ngủ lý tưởng. Giải pháp của kperryua với CGEventSourceSecondsSinceLastEventType là chính xác cho thời gian giám sát kể từ lần nhập người dùng cuối cùng. –

5

Có API Carbon sẽ gửi thông báo khi không có sự kiện của người dùng sau một khoảng thời gian nhất định được gọi là EventLoopIdleTimer. Uli Kusterer đã viết một trình bao bọc Cocoa cho here (look for UKIdleTimer).

Nếu bạn muốn mức độ thấp hơn, bạn có thể thực hiện hành vi bạn muốn bằng kết hợp bộ hẹn giờ và chức năng CoreGraphics CGEventSourceSecondsSinceLastEventType (có sẵn trong <CoreGraphics/CGEventSource.h>).

+0

Có thể thực hiện tương tự trên iOS không? – SlowTree

+0

Cả hai API này đều không có sẵn trên iOS. Tôi không biết nếu có bất kỳ tương đương hoặc. – kperryua

+0

Không sử dụng CGEventSourceSecondsSinceLastEventType trong trình khởi chạy daemon. –

0

Tôi đã sử dụng một cách tiếp cận khác. Phân lớp UIApplication Tôi ghi đè lên phương pháp sendEvent lọc chạm (thực sự bạn có thể lọc bất kỳ loại sự kiện, tăng tốc, chạm, vv). Sử dụng biến được chia sẻ và bộ hẹn giờ nền tôi đã quản lý "không hoạt động". Mỗi khi người dùng chạm vào màn hình, biến được đặt với timeInterval hiện tại (thời gian hiện tại). Phương pháp lửa hẹn giờ kiểm tra thời gian trôi qua kể từ lần chạm cuối cùng, nếu lớn hơn ngưỡng (trong trường hợp của tôi là khoảng 90 giây), bạn có thể BẬT thông báo của riêng mình.

Tôi đã sử dụng phương pháp đơn giản này để tạo tập hợp ứng dụng tùy chỉnh sau một thời gian rảnh rỗi tự động gọi là ứng dụng "trình bảo vệ màn hình".

Không có gì thông minh, nó chỉ thực hiện công việc.

Hy vọng điều đó sẽ hữu ích.

Các vấn đề liên quan