Ios 覆盖接近传感器时,保持显示器打开

Ios 覆盖接近传感器时,保持显示器打开,ios,iphone,proximity,uidevice,proximitysensor,Ios,Iphone,Proximity,Uidevice,Proximitysensor,我想在不关闭显示器的情况下拦截接近传感器 通过文档,我知道我有两个布尔变量: proximityMonitoringEnabled proximityState 这个密码呢 [UIDevice currentDevice].proximityMonitoringEnabled = YES; 当接近传感器检测到某种东西时,它会关闭显示器,就像你在打电话时把手机放在耳朵上一样 当覆盖接近传感器时,如何保持显示器打开?苹果的文档说明“并非所有iPhone操作系统设备都有接近传感器”。要确定应用程序

我想在不关闭显示器的情况下拦截接近传感器

通过文档,我知道我有两个布尔变量:

proximityMonitoringEnabled
proximityState
这个密码呢

[UIDevice currentDevice].proximityMonitoringEnabled = YES;
当接近传感器检测到某种东西时,它会关闭显示器,就像你在打电话时把手机放在耳朵上一样


当覆盖接近传感器时,如何保持显示器打开?

苹果的文档说明“并非所有iPhone操作系统设备都有接近传感器”。要确定应用程序运行的设备是否支持接近监测,请将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);
}
资料来源:

将有助于检测传感器的当前状态

允许屏幕变暗的公共API:

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

在这里可以找到:

在阅读了关于该主题的不同论坛后,我们目前不可能在公共api中防止iPhone屏幕在覆盖接近传感器时变黑。使用传感器时,您唯一能做的就是通过通知中心告知其何时被覆盖或未被覆盖,但您同样无法控制其自然行为(当其使屏幕变暗/变黑时)。

使用以下API启用/禁用接近传感器

[UIDevice currentDevice].proximityMonitoringEnabled = NO; // Disables the Proximity Sensor and won't turnoff the display when sensor covered

[UIDevice currentDevice].proximityMonitoringEnabled = YES; // Enables the Proximity Sensor and will turnoff the display when sensor covered

并非所有iOS设备都有接近传感器。要确定是否有接近监控可用,请尝试启用它。如果proximityMonitoringEnabled属性的值保持为否,则邻近监视不可用。

尽管没有公共API来执行此操作,但您可以连接到
IOKit
IOHIDEventSystem
并侦听屏幕变暗通知:

// 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); 
    }
}
调用
\u SBDimScreen
甚至可能没有必要,因为具有空功能指针可能会停止所有接近传感器事件


从iPhoneDevWiki页面上的命令行工具示例中修改的代码。

fo swift/iOS 10/xcode 8.2

UIDevice.current.isProximityMonitoringEnabled = true/false..

嗨,谢谢你的回答。好的,通过您的代码,我可以知道接近传感器的状态,但如果状态为“是”,显示屏是否仍然不可见?您好,因此我现在只能回答。当传感器被覆盖时,我可以做些什么,但显示器仍然关闭@SimonePistecchia为什么不用您尝试过的内容更新您的问题,以便我们能够进一步帮助您。SimonePistecchia编辑了我的答案“如何使用公共API调暗屏幕”。该问题询问如何在仍然能够使用接近传感器检测到接近的情况下保持屏幕打开。这个答案导致屏幕仍然关闭。我已经用iPhone6和iOS 9.2.1对它进行了测试。谢谢你给出了这么好的答案!希望在某个时候不使用
IOKit
也能实现。谢谢@DanielStorm,祝你好运!如果这是公开API的时候会更新的。你如何用SWIFT应用程序实现这样的C++代码?@ JAL有没有在非ObjuleC应用程序中实现私有API使用的好教程?如果你使用这个方法,你的应用程序会被拒绝在应用程序商店吗?有趣的是,谷歌和PeekCalendar都能够使用这一功能,但他们的应用程序仍由苹果发布——参见