【懒人精灵】蓝牙hid点击类,实现免root免无障碍物理点击

BKM蓝牙HID插件,是专为ESP32蓝牙模块而开发的键鼠模块。
提供java、http、websocket接口,可供懒人精灵、Autojs等安卓自动化框架调用。

类模块

-- 版本:2025-11-24

local BkmHID = {}
BkmHID.__index = BkmHID

-- 构造函数
function BkmHID:new(config)
    local obj = {}
    setmetatable(obj, BkmHID)

    -- 尝试加载插件
    local bkmLoader = LuaEngine.loadApk(config.apkPath)
    obj.bleClass = bkmLoader.loadClass('com.feiyun.hid.BlePlugins')
    if obj.bleClass == nil then
        print('HID插件加载失败')
        obj.error = 'HID插件加载失败'
        return obj  -- 返回对象而不是 nil
    end

    -- 初始化服务
    local context = LuaEngine.getContext()
    obj.bleClass.setContext(context) -- 初始化

    -- 连接ESP设备
    local jsonRes = obj.bleClass.autoConnect() -- 连接当前设备的蓝牙
    if jsonRes == nil then
        print('未找到蓝牙设备/蓝牙通信异常')
        obj.error = '未找到蓝牙设备/蓝牙通信异常'
        return obj  -- 返回对象而不是 nil
    end

    -- print("autoConnect result:", jsonRes)
    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    if not result then
        print('初始化HID服务失败', errMsg)
        toast('初始化HID服务失败')
        obj.error = '初始化HID服务失败: ' .. errMsg
        return obj  -- 返回对象而不是 nil
    end

    print('初始化HID服务成功')

    -- 获取屏幕宽度和高度
    obj.width, obj.height = getDisplaySize()

    return obj
end

-- 检查蓝牙权限
function BkmHID:requestBlePermission()
    return self.bleClass.requestBlePermission()
end

-- 自动连接蓝牙硬件
function BkmHID:autoConnect()
    local jsonRes = self.bleClass.autoConnect()
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    -- print("autoConnect result:", jsonRes)
    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    return result, errMsg
end

-- 检查连接状态
function BkmHID:isConnect()
    local jsonRes = self.bleClass.getState()
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']

    -- false Error during execution: Disconnected from MAC='XX:XX:XX:XX:XX:XX' with status 0 (GATT_SUCCESS)
    return result, errMsg
end

------------------------------------------------------------------------------------------------------------

function BkmHID:getName()
    if self.error then
        return false, self.error
    end

    local jsonRes = self.bleClass.getName()
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    if tbRes['data']['result'] then
        return tbRes['data']['content']
    end
    return nil
end

function BkmHID:getModel()
    local jsonRes = self.bleClass.getModel()
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    -- print(tbRes)
    if tbRes['data']['result'] then
        return tbRes['data']['content']
    end
    return nil
end

------------------------------------------------------------------------------------------------------------

-- 模拟按下 "home" 键
-- 参数解释:
-- delay (可选):
--     类型: number
--     默认值: 1000 毫秒 (1 秒)
--     说明: 控制执行模拟 "home" 按键操作前的延迟时间,单位为毫秒。
function BkmHID:home(delay)
    -- 为 delay 参数设置默认值
    delay = delay or 1 * 1000 -- 为 delay 设置默认值

    local jsonRes = self.bleClass.home()
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    if result then
        sleep(delay)
    end
    return result, errMsg
end

function BkmHID:back(delay)
    -- 为 delay 参数设置默认值
    delay = delay or 1 * 1000 -- 为 delay 设置默认值

    local jsonRes = self.bleClass.back()
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    if result then
        sleep(delay)
    end
    return result, errMsg
end

function BkmHID:recent(delay)
    -- 为 delay 参数设置默认值
    delay = delay or 1 * 1000 -- 为 delay 设置默认值

    local jsonRes = self.bleClass.recent()
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    if result then
        sleep(delay)
    end
    return result, errMsg
end

function BkmHID:enter(delay)
    -- 为 delay 参数设置默认值
    delay = delay or 1 * 1000 -- 为 delay 设置默认值

    local jsonRes = self.bleClass.enter()
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    if result then
        sleep(delay)
    end
    return result, errMsg
end

function BkmHID:copy(delay)
    -- 为 delay 参数设置默认值
    delay = delay or 1 * 1000 -- 为 delay 设置默认值

    local jsonRes = self.bleClass.copy()
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    if result then
        sleep(delay)
    end
    return result, errMsg
end

function BkmHID:cut(delay)
    -- 为 delay 参数设置默认值
    delay = delay or 1 * 1000 -- 为 delay 设置默认值

    local jsonRes = self.bleClass.cut()
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    if result then
        sleep(delay)
    end
    return result, errMsg
end

function BkmHID:paste(delay)
    -- 为 delay 参数设置默认值
    delay = delay or 1 * 1000 -- 为 delay 设置默认值

    local jsonRes = self.bleClass.paste()
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    if result then
        sleep(delay)
    end
    return result, errMsg
end

-- 模拟点击真实坐标
-- x (number):
--     类型: number
--     说明: 点击操作的横坐标 (X 轴),即点击的位置在屏幕上的水平位置。
--     必须提供此参数。

-- y (number):
--     类型: number
--     说明: 点击操作的纵坐标 (Y 轴),即点击的位置在屏幕上的垂直位置。
--     必须提供此参数。

-- delay (可选):
--     类型: number
--     默认值: 1000 毫秒 (1 秒)
--     说明: 控制执行模拟点击操作前的延迟时间,单位为毫秒。
function BkmHID:click(x, y, delay)
    delay = delay or 1 * 1000

    local isConnect, errMsg = self:isConnect()
    if not isConnect then
        print('尝试重连蓝牙设备', self:autoConnect())
    end

    local jsonRes = self.bleClass.click(x, y)
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    if result then
        sleep(delay)
    end
    return result, errMsg
end

-- interval 鼠标左按下和松开的间隔时间
function BkmHID:qClick(x, y, interval, delay)
    interval = interval or 10
    delay = delay or 1 * 1000

    local jsonRes = self.bleClass.qClick(x, y, interval)
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    if result then
        sleep(delay)
    end
    return result, errMsg
end

-- 模拟左键双击(可能不太稳定)
-- interval 鼠标左按下和松开的间隔时间
-- gap 鼠标左键两次点击的时间差
function BkmHID:dbClick(x, y, interval, gap, delay)
    interval = interval or 10
    gap = gap or 10
    delay = delay or 1 * 1000

    local jsonRes = self.bleClass.dbClick(x, y, interval, gap)
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    if result then
        sleep(delay)
    end
    return result, errMsg
end

-- 自动判断坐标参数进行点击
function BkmHID:autoClick(px, py, delay)
    if px == nil or py == nil then
        return false, '坐标参数不能为空'
    end

    if px > 0 and px < 1 and py > 0 and py < 1 then
        local realX = math.floor(px * self.width)
        local realY = math.floor(py * self.height)
        return self.bleClass.click(realX, realY, delay)
    else
        return self.bleClass.click(px, py, delay)
    end
end

function BkmHID:autoQClick(px, py, interval, delay)
    if px > 0 and px < 1 and py > 0 and py < 1 then
        local realX = math.floor(px * self.width)
        local realY = math.floor(py * self.height)
        return self.bleClass.qClick(realX, realY, interval, delay)
    else
        return self.bleClass.qClick(px, py, interval, delay)
    end
end

-- 长按某个坐标
function BkmHID:press(x, y, delay)
    delay = delay or 1 * 1000

    local jsonRes = self.bleClass.press(x, y)
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    if result then
        sleep(delay)
    end
    self.bleClass.release() -- 释放鼠标

    return result, errMsg
end

-- 长按
function BkmHID:autoPress(px, py, delay)
    if px > 0 and px < 1 and py > 0 and py < 1 then
        -- 将百分比坐标转换为真实坐标
        local realX = math.floor(px * self.width)
        local realY = math.floor(py * self.height)
        -- print(realX, realY)
        return self.bleClass.press(realX, realY, delay)
    else
        return self.bleClass.press(px, py, delay)
    end
end

-- 滑动操作
-- 自动判断是百分比还是真实坐标,如果输入的是百分比,则自动转换为真实坐标
function BkmHID:swipe(x1, y1, x2, y2, delay)
    delay = delay or 1 * 1000

    -- 检查连接
    if not self.bleClass.isConnect() then
        print('self.bleClass is not connected')
        local isConnect, errMsg = self.bleClass.autoConnect() -- 连接当前设备的蓝牙
        if isConnect then
            print('?重连HID服务成功')
        else
            print('??重连HID服务失败', errMsg)
        end
    end

    local jsonRes = self.bleClass.swipe(x1, y1, x2, y2)
    if jsonRes == nil then
        return false, '未找到蓝牙设备/蓝牙通信异常'
    end

    local tbRes = jsonLib.decode(jsonRes)
    local result, errMsg = tbRes['data']['result'], tbRes['data']['content']
    if result then
        sleep(delay)
    end
    return result, errMsg
end

-- 百分比坐标滑动
function BkmHID:autoSwipe(x1, y1, x2, y2, delay)
    if x1 > 0 and x1 < 1 and y1 > 0 and y1 < 1 and x2 > 0 and x2 < 1 and y2 > 0 and y2 < 1 then
        -- 将百分比坐标转换为真实坐标
        local realX1 = math.floor(x1 * self.width)
        local realY1 = math.floor(y1 * self.height)
        local realX2 = math.floor(x2 * self.width)
        local realY2 = math.floor(y2 * self.height)
        -- print(realX1, realY1, realX2, realY2)
        return self.bleClass.swipe(realX1, realY1, realX2, realY2)
    else
        return self.bleClass.swipe(x1, y1, x2, y2, delay)
    end
end

-- 定义贝塞尔曲线函数,用于生成平滑的滑动路径点
local function bezierCurve(p0, p1, p2, t)
    local oneMinusT = 1 - t
    local result = oneMinusT * oneMinusT * p0 + 2 * oneMinusT * t * p1 + t * t * p2
    return math.floor(result)
end

-- 自定义滑动方法
-- @param x1: 滑动起始点的X坐标百分比(相对于屏幕宽度w)
-- @param y1: 滑动起始点的Y坐标百分比(相对于屏幕高度h)
-- @param x2: 滑动终点的X坐标百分比(相对于屏幕宽度w)
-- @param y2: 滑动终点的Y坐标百分比(相对于屏幕高度h)
-- @param duration: 滑动持续时间(毫秒),用于控制滑动速度
-- @param stepSize: 滑动百分比步长,默认为0.1
function BkmHID:swipeEx(x1, y1, x2, y2, duration, stepSize)
    stepSize = stepSize or 0.1
    duration = duration / 2 --- 暂时这样!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    -- 根据百分比计算实际的屏幕坐标,并转换为整数
    local startX = math.floor(x1 * self.width)
    local startY = math.floor(y1 * self.height)
    local endX = math.floor(x2 * self.width)
    local endY = math.floor(y2 * self.height)

    -- 根据滑动方向设置贝塞尔曲线的控制点,调整控制点位置来增大震荡幅度
    local controlPointX, controlPointY
    local direction
    if math.abs(endX - startX) >= math.abs(endY - startY) then
        direction = 'horizontal'
        controlPointX = math.floor((startX + endX) / 2)
        if y1 ~= y2 then
            -- 当水平移动且y1和y2不同时,增大Y坐标控制点的偏移量,比如乘以一个系数来增大震荡幅度,这里取1.5作为示例系数,可根据实际效果调整
            local midY = math.floor((startY + endY) / 2)
            local offsetY = (midY - startY) * 1.5
            controlPointY = bezierCurve(startY, midY + offsetY, endY, 0.5)
        else
            controlPointY = startY
        end
    else
        direction = 'vertical'
        controlPointY = math.floor((startY + endY) / 2)
        if x1 ~= x2 then
            -- 当垂直移动且x1和x2不同时,增大X坐标控制点的偏移量,同样乘以一个系数,这里取1.5作为示例系数,可根据实际效果调整
            local midX = math.floor((startX + endX) / 2)
            local offsetX = (midX - startX) * 1.5
            controlPointX = bezierCurve(startX, midX + offsetX, endX, 0.5)
        else
            controlPointX = startX
        end
    end

    local stepInterval = duration / ((1 / stepSize) - 1)
    local t = 0
    while t < 1 do
        local currentX, currentY
        if direction == 'horizontal' then
            currentX = bezierCurve(startX, controlPointX, endX, t)
            currentY = bezierCurve(startY, controlPointY, endY, t)
        elseif direction == 'vertical' then
            currentX = bezierCurve(startX, controlPointX, endX, t)
            currentY = bezierCurve(startY, controlPointY, endY, t)
        end

        -- 生成随机步长,适当增大随机步长范围来让滑动更具变化,这里调整范围为 [stepSize * 0.3, stepSize * 1.8],可根据实际情况进一步调整
        local randomStepSize = stepSize * (math.random() * 1.5)

        -- 触摸移动到当前点,并转换为整数
        self.bleClass.press(math.floor(currentX), math.floor(currentY))

        t = t + randomStepSize

        -- 根据计算出的步长间隔时间进行延时,以控制滑动速度
        sleep(math.floor(stepInterval))

        -- 在垂直移动时更新startX的值
        if direction == 'vertical' then
            startX = math.floor(currentX)
        end

        -- 在水平移动时更新startY的值
        if direction == 'horizontal' then
            startY = math.floor(currentY)
        end
    end

    -- 触摸抬起
    self.bleClass.release()

    -- -- 触摸抬起后延时1秒
    -- sleep(1000)
end

return BkmHID

调用方法

local hidModule = require('lib/BkmHID')
    BLE = hidModule:new({
        apkPath = bkmPluginPath, -- 设置插件路径
    })

    if not BLE:isConnect() then
        print('蓝牙HID连接失败')
        return
    end

    -- 获取设备信息
    local espName = BLE:getName()
    print('已就绪:' .. espName)
    toast('已就绪:' .. espName)
    print('硬件型号:' .. BLE:getModel())
    BLE:home()

插件文档

蓝牙hid点击类模块文档

插件下载

暂无

1. 官方交流QQ群,添加多个不批。建议使用安卓手机或电脑申请。
飞云脚本圈: 586333520飞云脚本圈
Auto.js学习交流③群:286635606
Auto.js学习交流②群:712194666(满员)
IOS免越狱自动化测试群:691997586
2. 盗版,破解有损他人权益和违法作为,请各位会员支持正版。
3. 本站部分资源来源于用户上传和网络搜集,如有侵权请提供版权证明并联系站长删除。
4.如未特别申明,本站的技术性文章均为原创,未经授权,禁止转载/搬运等侵权行为。
5.全站所有付费服务均为虚拟商品,购买后自动发货。售出后概不接受任何理由的退、换。注册即为接受此条款。
6.如果站内内容侵犯了您的权益,请联系站长删除。
飞云脚本 » 【懒人精灵】蓝牙hid点击类,实现免root免无障碍物理点击

企业级大数据智能营销管理系统

源码转让