16

ディスプレイを消さずに近接センサーを傍受したい。

ドキュメントで、2 つの Bool 変数があることを知っています。

proximityMonitoringEnabled
proximityState

そしてこのコード

[UIDevice currentDevice].proximityMonitoringEnabled = YES;

近接センサーが何かを検出すると、電話中に電話を耳に当てているときと同じように、ディスプレイをオフにします。

近接センサーが覆われているときにディスプレイをオンにしておくにはどうすればよいですか?

4

5 に答える 5

8

このトピックに関するさまざまなフォーラムを読んだ後、近接センサーが覆われているときに iPhone の画面が黒くなるのを防ぐことは、パブリック API では現在不可能です。センサーでできる唯一のことは、通知センターを介してカバーされているかどうかを通知することですが、その自然な動作を制御することはできません (画面が暗くなったり黒くなったりする場合)。

于 2014-12-02T22:53:51.303 に答える
7

Apple のドキュメントには、「すべての iPhone OS デバイスに近接センサーがあるわけではない」と記載されています。アプリが実行しているデバイスが近接監視をサポートしているかどうかを判断するには、proximityMonitoringEnabled プロパティを YES に設定し、その値を確認します。

UIDevice *device = [UIDevice currentDevice];
[device setProximityMonitoringEnabled:YES];

if (device.proximityMonitoringEnabled == YES) {
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(proximityChanged:) 
                                                 name:@"UIDeviceProximityStateDidChangeNotification"
                                               object:device];
}

- (void) proximityChanged:(NSNotification *)notification {
    UIDevice *device = [notification object];
    NSLog(@"In proximity: %i", device.proximityState);
}

ソース: http://www.whatsoniphone.com/blog/new-in-iphone-30-tutorial-series-part-4-proximity-detection/

センサーの現在の状態を検出するのに役立ちます。

画面を暗くできるパブリック API:

[UIScreen mainScreen].wantsSoftwareDimming = YES;
[UIScreen mainScreen].brightness = $your_brightness_value;

ここにあります: iOS 6 で wantsSoftwareDimming に変更しますか?

于 2014-11-26T11:24:59.940 に答える
5

これを行うパブリック API はありませんが、 にフックして、画面IOKitIOHIDEventSystem減光通知をリッスンできます。

// Create and open an event system.
IOHIDEventSystemRef system = IOHIDEventSystemCreate(NULL);

// Set the PrimaryUsagePage and PrimaryUsage that the AppleProxShim service uses
int page = 65280;
int usage = 8;

// Create a dictionary to match the service with
CFStringRef keys[2];
CFNumberRef nums[2];
keys[0] = CFStringCreateWithCString(0, "PrimaryUsagePage", 0);
keys[1] = CFStringCreateWithCString(0, "PrimaryUsage", 0);
nums[0] = CFNumberCreate(0, kCFNumberSInt32Type, &page);
nums[1] = CFNumberCreate(0, kCFNumberSInt32Type, &usage);
CFDictionaryRef dict = CFDictionaryCreate(0, (const void**)keys, (const void**)nums, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
// Get the total of matching services with the above criteria
CFArrayRef srvs = (CFArrayRef)IOHIDEventSystemCopyMatchingServices(system, dict, 0, 0, 0, 0);

// Get the service
IOHIDServiceRef serv = (IOHIDServiceRef)CFArrayGetValueAtIndex(srvs, 0);
int interval = 1 ;

// Set an interval of 1 , to activate the sensor  
IOHIDServiceSetProperty((IOHIDServiceRef)serv, CFSTR("ReportInterval"), CFNumberCreate(0, kCFNumberSInt32Type, &interval));

// add your event handler
IOHIDEventSystemOpen(system, handle_event, NULL, NULL, NULL);
int defaultInterval = 0;
IOHIDServiceSetProperty((IOHIDServiceRef)serv, CFSTR("ReportInterval"), CFNumberCreate(0, kCFNumberSInt32Type, &defaultInterval));

// close handles and release the IOHIDEventSystemRef
IOHIDEventSystemClose(system, NULL);
CFRelease(system);

イベント ハンドラー関数ポインターは次のようになります。

void handle_event(void* target, void* refcon, IOHIDServiceRef service, IOHIDEventRef event) {
    if (IOHIDEventGetType(event) == kIOHIDEventTypeProximity) { // Proximity Event Received
        // not necessary, but if you want the value from the sensor, get it from IOHIDEventGetIntegerValue
        int proximityValue = IOHIDEventGetIntegerValue(event, (IOHIDEventField)kIOHIDEventFieldProximityDetectionMask); // Get the value of the ProximityChanged Field (0 or 64)

        // Call dimScreen with the boolean NO
        int (*SBSSpringBoardServerPort)() = (int (*)())dlsym(RTLD_DEFAULT, "SBSSpringBoardServerPort");
        int port = SBSSpringBoardServerPort(); 
        void (*_SBDimScreen)(int _port,BOOL shouldDim) = (void (*)(int _port,BOOL shouldDim))dlsym(RTLD_DEFAULT, "SBDimScreen");

        // This is where the logic to dim the screen based on the sensor value would go.  In this case, I'm hardcoding NO instead of the value of proximityValue from above
        // BOOL dim = proximityValue == 0 ? NO : YES;
        _SBDimScreen(port, NO); 
    }
}

空の関数ポインターがあると、すべての近接センサー イベントが停止する可能性があるため、呼び出す_SBDimScreen必要さえない場合があります。

iPhoneDevWiki のAppleProxShimページにあるコマンド ライン ツールの例から変更されたコード。

于 2016-04-20T17:22:30.510 に答える