具体实现:控制系统按键-音量键
前期在iosre找了一下有关于音量键的实现和处理,基本都是半桶水,也没有具体告知怎么去实现,的确苦恼了我几天,后来找到了相关代码和系统实现终于解决,今天我就分享出来,希望大家都贡献技术,少互黑 多闷声发大财。在群里被T了 ,这两天论坛被D,现在才上来分享一下:
**TODO:**针对 http://iphonedevwiki.net/index.php/IOHIDFamily 的文献仅仅只能参考Keyboard events的Usage对应的编号,离实际上的成功还差的远。
##问题:
- 最新版thoes对IOKit.framework的引入编译肯定是不行,一直报错。
- 导入
#include <IOKit/hid/IOHIDEventSystem.h>
也是无法编译。 - 通过SpringBoard的_handleHIDEvent函数只能触发语音控制/home/锁屏键之类,无法实现音量实体按键。
- 守护程序-launchd多面手对提供自定义事物支持。
实现:
1. 引入头文件:
2. extern “C” IOKit 函数:
struct __IOHIDEvent * holdEvent;
extern "C"{
typedef uint32_t IOHIDEventOptionBits;
typedef struct __IOHIDEvent *IOHIDEventRef;
typedef CFTypeRef IOHIDEventSystemClientRef;
typedef CFTypeRef IOHIDEventSystemConnectionRef;
IOHIDEventRef IOHIDEventCreateKeyboardEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, uint16_t usagePage, uint16_t usage, Boolean down, IOHIDEventOptionBits flags);
IOHIDEventSystemClientRef IOHIDEventSystemClientCreate(CFAllocatorRef allocator);
void IOHIDEventSetSenderID(struct __IOHIDEvent * event, uint64_t sender);
void IOHIDEventSystemClientDispatchEvent(IOHIDEventSystemClientRef client, IOHIDEventRef event);
typedef CFTypeRef IOHIDEventSystemRef;
typedef uint32_t IOHIDEventType;
typedef uint32_t IOOptionBits;
typedef uint32_t IOHIDEventField;
typedef uint32_t IOHIDDigitizerTransducerType;
CFTypeID IOHIDEventSystemGetTypeID(void);
IOHIDEventSystemRef IOHIDEventSystemCreate(CFAllocatorRef allocator);
IOHIDEventRef IOHIDEventSystemCopyEvent(IOHIDEventSystemRef system, IOHIDEventType type, IOHIDEventRef event, IOOptionBits options);
CFIndex IOHIDEventGetIntegerValue(void *, uint32_t);
void IOHIDEventSetIntegerValueWithOptions(IOHIDEventRef event, IOHIDEventField field, int value, IOOptionBits options);
void IOHIDEventAppendEvent(IOHIDEventRef event, IOHIDEventRef childEvent);
void IOHIDEventSetIntegerValue(IOHIDEventRef event, IOHIDEventField field, int value);}
3.申明传递事件函数:
static void SendHIDEvent(IOHIDEventRef event) {
static IOHIDEventSystemClientRef client_(NULL);
if (client_ == NULL)
client_ = IOHIDEventSystemClientCreate(kCFAllocatorDefault);
IOHIDEventSetSenderID(event, 0xDEFACEDBEEFFECE5);
IOHIDEventSystemClientDispatchEvent(client_, event);
CFRelease(event);
}
4. 音量键减 点击触发:
uint64_t abTime = mach_absolute_time();
{
//down
IOHIDEventRef event = IOHIDEventCreateKeyboardEvent(kCFAllocatorDefault, *(AbsoluteTime *)&abTime, 0x0c, 0xea, 1, 0);
#define kIOHIDEventFieldBuiltIn 4
#define kIOHIDEventFieldDigitizerDisplayIntegrated 720921
//IOHIDEventSetIntegerValueWithOptions(event, kIOHIDEventFieldDigitizerDisplayIntegrated, 1, -268435456); //-268435456
//IOHIDEventSetIntegerValueWithOptions(event, kIOHIDEventFieldBuiltIn, 1, -268435456); //-268435456
IOHIDEventSetIntegerValue(event,kIOHIDEventFieldBuiltIn, 1);
#define kIOHIDEventDigitizerSenderID 0x0000000100000194
IOHIDEventSetSenderID(event, kIOHIDEventDigitizerSenderID);
SendHIDEvent(event);
}
{
//up
uint64_t abTime2 = mach_absolute_time();
IOHIDEventRef event = IOHIDEventCreateKeyboardEvent(kCFAllocatorDefault, *(AbsoluteTime *)&abTime2, 0x0c, 0xea, 0, 0);
#define kIOHIDEventFieldBuiltIn 4
#define kIOHIDEventFieldDigitizerDisplayIntegrated 720921
//IOHIDEventSetIntegerValueWithOptions(event, kIOHIDEventFieldDigitizerDisplayIntegrated, 1, -268435456); //-268435456
//IOHIDEventSetIntegerValueWithOptions(event, kIOHIDEventFieldBuiltIn, 1, -268435456); //-268435456
IOHIDEventSetIntegerValue(event,kIOHIDEventFieldBuiltIn, 1);
#define kIOHIDEventDigitizerSenderID 0x0000000100000194
IOHIDEventSetSenderID(event, kIOHIDEventDigitizerSenderID);
SendHIDEvent(event);
}
操作步骤:
- 安装deb后注销手机 Killall -9 SpringBoard
- 手机环境: iOS8.2 iOS9.2 iOS10.2 iPhone5s arm64
结尾:
对于 IOHIDEventSetIntegerValue 函数的处理很关键。
别看短短的几句代码,实际上困扰了很多人,至少我在gogole没有找到比较完美的解决办法。关于问题第4点launchd多面手主要是提供底层接口接受处理事物支持,比如你在某个app的xm里调用函数 [%c(xxx) sendMessage:@"click_volume_up"]
后这时候你注册的守护程序会直接hook SpringBoard触发音量键按键。希望可以帮到大家!