Android设备通过蓝牙HID技术模拟键盘实现

目录

一,背景介绍

二,技术方案

2.1 获取BluetoothHidDevice实例

2.2 注册/解除注册HID实例

2.3 Hid report description描述符生成工具

2.4 键盘映射表

2.5 通过HID发送键盘事件

 三,实例


一,背景介绍

        日常生活中,各种物理遥控器和鼠标等设备,需要摆放和携带,便捷性有待考验。根据蓝牙HID特性,可以用蓝牙协议模仿键盘,来实现空中键盘等功能。


二,技术方案

        自Android 9开放BluetoothHidDevice功能后,Android平台可以很简单的通过BluetoothHidDevice模拟键盘鼠标等蓝牙hid device角色。


2.1 获取BluetoothHidDevice实例

 BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
 
bluetoothAdapter.setName("KEYBOARD BT");
      bluetoothAdapter.getProfileProxy(context,mProfileServiceListener,BluetoothProfile.HID_DEVICE);

2.2 注册/解除注册HID实例

    public static BluetoothProfile.ServiceListener mProfileServiceListener = new BluetoothProfile.ServiceListener() {
        @Override
        public void onServiceDisconnected(int profile) {
            Log.e(TAG, "hid onServiceDisconnected");
            if (profile == BluetoothProfile.HID_DEVICE) {
                mHidDevice.unregisterApp();
            }
        }

        @SuppressLint("NewApi")
        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            Log.e(TAG, "hid onServiceConnected");
            bluetoothProfile = proxy;
            if (profile == BluetoothProfile.HID_DEVICE) {
                mHidDevice = (BluetoothHidDevice) proxy;
                HidConsts.HidDevice = mHidDevice;
                BluetoothHidDeviceAppSdpSettings sdp = new BluetoothHidDeviceAppSdpSettings(HidConsts.NAME, HidConsts.DESCRIPTION, HidConsts.PROVIDER, BluetoothHidDevice.SUBCLASS1_COMBO, HidConsts.Descriptor);
                mHidDevice.registerApp(sdp, null, null, Executors.newCachedThreadPool(), mCallback);
            }
        }
    };

 

        在获取到BluetoothHidDevice实例后通过registerApp注册hid device,此时hid host角色会被禁用,因此在不需要hid device功能时要及时解除hid device的注册。

        registerApp函数中最重要的一个参数BluetoothHidDeviceAppSdpSettings,主要是给对端host提供hid device角色的名称,描述信息,供应商信息,以及Hid device的Reports Descriptor。


2.3 Hid report description描述符生成工具

参考文章《官网HID描述符工具》

 

   val Descriptor = byteArrayOf(
        0x05.toByte(),
        0x01.toByte(),
        0x09.toByte(),
        0x02.toByte(),
        0xa1.toByte(),
        0x01.toByte(),
        0x09.toByte(),
        0x01.toByte(),
        0xa1.toByte(),
        0x00.toByte(),
        0x85.toByte(),
        0x01.toByte(),
        0x05.toByte(),
        0x09.toByte(),
        0x19.toByte(),
        0x01.toByte(),
        0x29.toByte(),
        0x03.toByte(),
        0x15.toByte(),
        0x00.toByte(),
        0x25.toByte(),
        0x01.toByte(),
        0x95.toByte(),
        0x03.toByte(),
        0x75.toByte(),
        0x01.toByte(),
        0x81.toByte(),
        0x02.toByte(),
        0x95.toByte(),
        0x01.toByte(),
        0x75.toByte(),
        0x05.toByte(),
        0x81.toByte(),
        0x03.toByte(),
        0x05.toByte(),
        0x01.toByte(),
        0x09.toByte(),
        0x30.toByte(),
        0x09.toByte(),
        0x31.toByte(),
        0x09.toByte(),
        0x38.toByte(),
        0x15.toByte(),
        0x81.toByte(),
        0x25.toByte(),
        0x7f.toByte(),
        0x75.toByte(),
        0x08.toByte(),
        0x95.toByte(),
        0x03.toByte(),
        0x81.toByte(),
        0x06.toByte(),
        0xc0.toByte(),
        0xc0.toByte(),
        0x05.toByte(),
        0x01.toByte(),
        0x09.toByte(),
        0x06.toByte(),
        0xa1.toByte(),
        0x01.toByte(),
        0x85.toByte(),
        0x02.toByte(),
        0x05.toByte(),
        0x07.toByte(),
        0x19.toByte(),
        0xE0.toByte(),
        0x29.toByte(),
        0xE7.toByte(),
        0x15.toByte(),
        0x00.toByte(),
        0x25.toByte(),
        0x01.toByte(),
        0x75.toByte(),
        0x01.toByte(),
        0x95.toByte(),
        0x08.toByte(),
        0x81.toByte(),
        0x02.toByte(),
        0x95.toByte(),
        0x01.toByte(),
        0x75.toByte(),
        0x08.toByte(),
        0x15.toByte(),
        0x00.toByte(),
        0x25.toByte(),
        0x65.toByte(),
        0x19.toByte(),
        0x00.toByte(),
        0x29.toByte(),
        0x65.toByte(),
        0x81.toByte(),
        0x00.toByte(),
        0x05.toByte(),
        0x08.toByte(),
        0x95.toByte(),
        0x05.toByte(),
        0x75.toByte(),
        0x01.toByte(),
        0x19.toByte(),
        0x01.toByte(),
        0x29.toByte(),
        0x05.toByte(),
        0x91.toByte(),
        0x02.toByte(),
        0x95.toByte(),
        0x01.toByte(),
        0x75.toByte(),
        0x03.toByte(),
        0x91.toByte(),
        0x03.toByte(),
        0xc0.toByte()
    )


2.4 键盘映射表

    <string name="KeyText1" translatable="false">Esc</string>
    <string name="KeyCode1" translatable="false">29</string> <!-- Keyboard ESCAPE -->
    <string name="KeyText2" translatable="false">F1</string>
    <string name="KeyCode2" translatable="false">3a</string> <!-- Keyboard F1 -->
    <string name="KeyText3" translatable="false">F2</string>
    <string name="KeyCode3" translatable="false">3b</string> <!-- Keyboard F2 -->
    <string name="KeyText4" translatable="false">F3</string>
    <string name="KeyCode4" translatable="false">3c</string> <!-- Keyboard F3 -->
    <string name="KeyText5" translatable="false">F4</string>
    <string name="KeyCode5" translatable="false">3d</string> <!-- Keyboard F4 -->
    <string name="KeyText6" translatable="false">F5</string>
    <string name="KeyCode6" translatable="false">3e</string> <!-- Keyboard F5 -->
    <string name="KeyText7" translatable="false">F6</string>
    <string name="KeyCode7" translatable="false">3f</string> <!-- Keyboard F6 -->
    <string name="KeyText8" translatable="false">F7</string>
    <string name="KeyCode8" translatable="false">40</string> <!-- Keyboard F7 -->
    <string name="KeyText9" translatable="false">F8</string>
    <string name="KeyCode9" translatable="false">41</string> <!-- Keyboard F8 -->
    <string name="KeyText10" translatable="false">F9</string>
    <string name="KeyCode10" translatable="false">42</string> <!-- Keyboard F9 -->
    <string name="KeyText11" translatable="false">F10</string>
    <string name="KeyCode11" translatable="false">43</string> <!-- Keyboard F10 -->
    <string name="KeyText12" translatable="false">F11</string>
    <string name="KeyCode12" translatable="false">44</string> <!-- Keyboard F11 -->
    <string name="KeyText13" translatable="false">F12</string>
    <string name="KeyCode13" translatable="false">45</string> <!-- Keyboard F12 -->
    <string name="KeyText14" translatable="false">`&#160;&#160;~</string>
    <string name="KeyCode14" translatable="false">35</string> <!-- Keyboard ` and ~ -->
    <string name="KeyText15" translatable="false">1&#160;&#160;!</string>
    <string name="KeyCode15" translatable="false">1e</string> <!-- Keyboard 1 and ! -->
    <string name="KeyText16" translatable="false">2&#160;&#160;@</string>
    <string name="KeyCode16" translatable="false">1f</string> <!-- Keyboard 2 and @ -->
    <string name="KeyText17" translatable="false">3&#160;&#160;#</string>
    <string name="KeyCode17" translatable="false">20</string> <!-- Keyboard 3 and # -->
    <string name="KeyText18" translatable="false">4&#160;&#160;$</string>
    <string name="KeyCode18" translatable="false">21</string> <!-- Keyboard 4 and $ -->
    <string name="KeyText19" translatable="false">5&#160;&#160;%</string>
    <string name="KeyCode19" translatable="false">22</string> <!-- Keyboard 5 and % -->
    <string name="KeyText20" translatable="false">6&#160;&#160;^</string>
    <string name="KeyCode20" translatable="false">23</string> <!-- Keyboard 6 and ^ -->
    <string name="KeyText21" translatable="false">7&#160;&#160;&amp;</string>
    <string name="KeyCode21" translatable="false">24</string> <!-- Keyboard 7 and & -->
    <string name="KeyText22" translatable="false">8&#160;&#160;*</string>
    <string name="KeyCode22" translatable="false">25</string> <!-- Keyboard 8 and * -->
    <string name="KeyText23" translatable="false">9&#160;&#160;(</string>
    <string name="KeyCode23" translatable="false">26</string> <!-- Keyboard 9 and ( -->
    <string name="KeyText24" translatable="false">0&#160;&#160;)</string>
    <string name="KeyCode24" translatable="false">27</string> <!-- Keyboard 0 and ) -->
    <string name="KeyText25" translatable="false">-&#160;&#160;_</string>
    <string name="KeyCode25" translatable="false">2d</string> <!-- Keyboard - and _ -->
    <string name="KeyText26" translatable="false">=&#160;&#160;+</string>
    <string name="KeyCode26" translatable="false">2e</string> <!-- Keyboard = and + -->
    <string name="KeyText27" translatable="false">Backspace</string>
    <string name="KeyCode27" translatable="false">2a</string> <!-- Keyboard DELETE (Backspace) -->
    <string name="KeyText28" translatable="false">Tab</string>
    <string name="KeyCode28" translatable="false">2b</string> <!-- Keyboard Tab -->
    <string name="KeyText29" translatable="false">Q</string>
    <string name="KeyCode29" translatable="false">14</string> <!-- Keyboard q and Q -->
    <string name="KeyText30" translatable="false">W</string>
    <string name="KeyCode30" translatable="false">1a</string> <!-- Keyboard w and W -->
    <string name="KeyText31" translatable="false">E</string>
    <string name="KeyCode31" translatable="false">08</string> <!-- Keyboard e and E -->
    <string name="KeyText32" translatable="false">R</string>
    <string name="KeyCode32" translatable="false">15</string> <!-- Keyboard r and R -->
    <string name="KeyText33" translatable="false">T</string>
    <string name="KeyCode33" translatable="false">17</string> <!-- Keyboard t and T -->
    <string name="KeyText34" translatable="false">Y</string>
    <string name="KeyCode34" translatable="false">1c</string> <!-- Keyboard y and Y -->
    <string name="KeyText35" translatable="false">U</string>
    <string name="KeyCode35" translatable="false">18</string> <!-- Keyboard u and U -->
    <string name="KeyText36" translatable="false">I</string>
    <string name="KeyCode36" translatable="false">0c</string> <!-- Keyboard i and I -->
    <string name="KeyText37" translatable="false">O</string>
    <string name="KeyCode37" translatable="false">12</string> <!-- Keyboard o and O -->
    <string name="KeyText38" translatable="false">P</string>
    <string name="KeyCode38" translatable="false">13</string> <!-- Keyboard p and P -->
    <string name="KeyText39" translatable="false">[&#160;&#160;{</string>
    <string name="KeyCode39" translatable="false">2f</string> <!-- Keyboard [ and { -->
    <string name="KeyText40" translatable="false">]&#160;&#160;}</string>
    <string name="KeyCode40" translatable="false">30</string> <!-- Keyboard ] and } -->
    <string name="KeyText41" translatable="false">\\&#160;&#160;|</string>
    <string name="KeyCode41" translatable="false">31</string> <!-- Keyboard \ and | -->
    <string name="KeyText42" translatable="false">CapsLock</string>
    <string name="KeyCode42" translatable="false">39</string> <!-- Keyboard Caps Lock -->
    <string name="KeyText43" translatable="false">A</string>
    <string name="KeyCode43" translatable="false">04</string> <!-- Keyboard a and A -->
    <string name="KeyText44" translatable="false">S</string>
    <string name="KeyCode44" translatable="false">16</string> <!-- Keyboard s and S -->
    <string name="KeyText45" translatable="false">D</string>
    <string name="KeyCode45" translatable="false">07</string> <!-- Keyboard d and D -->
    <string name="KeyText46" translatable="false">F</string>
    <string name="KeyCode46" translatable="false">09</string> <!-- Keyboard f and F -->
    <string name="KeyText47" translatable="false">G</string>
    <string name="KeyCode47" translatable="false">0a</string> <!-- Keyboard g and G -->
    <string name="KeyText48" translatable="false">H</string>
    <string name="KeyCode48" translatable="false">0b</string> <!-- Keyboard h and H -->
    <string name="KeyText49" translatable="false">J</string>
    <string name="KeyCode49" translatable="false">0d</string> <!-- Keyboard j and J -->
    <string name="KeyText50" translatable="false">K</string>
    <string name="KeyCode50" translatable="false">0e</string> <!-- Keyboard k and K -->
    <string name="KeyText51" translatable="false">L</string>
    <string name="KeyCode51" translatable="false">0f</string> <!-- Keyboard l and L -->
    <string name="KeyText52" translatable="false">;&#160;&#160;:</string>
    <string name="KeyCode52" translatable="false">33</string> <!-- Keyboard ; and : -->
    <string name="KeyText53" translatable="false">\'&#160;&#160;\"</string>
    <string name="KeyCode53" translatable="false">34</string> <!-- Keyboard ' and " -->
    <string name="KeyText54" translatable="false">Enter</string>
    <string name="KeyCode54" translatable="false">28</string> <!-- Keyboard Return (ENTER) -->
    <string name="KeyText55" translatable="false">Shift</string>
    <string name="KeyCode55" translatable="false">02</string> <!-- Keyboard Left Shift -->
    <string name="KeyText56" translatable="false">Z</string>
    <string name="KeyCode56" translatable="false">1d</string> <!-- Keyboard z and Z -->
    <string name="KeyText57" translatable="false">X</string>
    <string name="KeyCode57" translatable="false">1b</string> <!-- Keyboard x and X -->
    <string name="KeyText58" translatable="false">C</string>
    <string name="KeyCode58" translatable="false">06</string> <!-- Keyboard c and C -->
    <string name="KeyText59" translatable="false">V</string>
    <string name="KeyCode59" translatable="false">19</string> <!-- Keyboard v and V -->
    <string name="KeyText60" translatable="false">B</string>
    <string name="KeyCode60" translatable="false">05</string> <!-- Keyboard b and B -->
    <string name="KeyText61" translatable="false">N</string>
    <string name="KeyCode61" translatable="false">11</string> <!-- Keyboard n and N -->
    <string name="KeyText62" translatable="false">M</string>
    <string name="KeyCode62" translatable="false">10</string> <!-- Keyboard m and M -->
    <string name="KeyText63" translatable="false">,&#160;&#160;&lt;</string>
    <string name="KeyCode63" translatable="false">36</string> <!-- Keyboard , and < -->
    <string name="KeyText64" translatable="false">.&#160;&#160;&gt;</string>
    <string name="KeyCode64" translatable="false">37</string> <!-- Keyboard . and > -->
    <string name="KeyText65" translatable="false">/&#160;&#160;?</string>
    <string name="KeyCode65" translatable="false">38</string> <!-- Keyboard / and ? -->
    <string name="KeyText66" translatable="false">Shift</string>
    <string name="KeyCode66" translatable="false">20</string> <!-- Keyboard Right Shift -->
    <string name="KeyText67" translatable="false">Ctrl</string>
    <string name="KeyCode67" translatable="false">01</string> <!-- Keyboard Left Ctrl -->
    <string name="KeyText68" translatable="false">⊞</string>
    <string name="KeyCode68" translatable="false">08</string> <!-- Keyboard Left Win -->
    <string name="KeyText69" translatable="false">Alt</string>
    <string name="KeyCode69" translatable="false">04</string> <!-- Keyboard Left Alt -->
    <string name="KeyText70" translatable="false">SPACE</string>
    <string name="KeyCode70" translatable="false">2c</string> <!-- Keyboard Space -->
    <string name="KeyText71" translatable="false">Alt</string>
    <string name="KeyCode71" translatable="false">40</string> <!-- Keyboard Right Alt -->
    <string name="KeyText72" translatable="false">Win</string>
    <string name="KeyCode72" translatable="false">80</string> <!-- Keyboard Right Win -->
    <string name="KeyText73" translatable="false">☰</string>
    <string name="KeyCode73" translatable="false">65</string> <!-- Keyboard Application -->
    <string name="KeyText74" translatable="false">Ctrl</string>
    <string name="KeyCode74" translatable="false">10</string> <!-- Keyboard Right Ctrl -->
    <string name="KeyText75" translatable="false">Print Screen</string>
    <string name="KeyCode75" translatable="false">46</string> <!-- Keyboard Print Screen -->
    <string name="KeyText76" translatable="false">Scroll Lock</string>
    <string name="KeyCode76" translatable="false">47</string> <!-- Keyboard Scroll Lock -->
    <string name="KeyText77" translatable="false">PAUSE</string>
    <string name="KeyCode77" translatable="false">48</string> <!-- Keyboard Pause -->
    <string name="KeyText78" translatable="false">Insert</string>
    <string name="KeyCode78" translatable="false">49</string> <!-- Keyboard Insert -->
    <string name="KeyText79" translatable="false">Home</string>
    <string name="KeyCode79" translatable="false">4a</string> <!-- Keyboard Home -->
    <string name="KeyText80" translatable="false">PgUp</string>
    <string name="KeyCode80" translatable="false">4b</string> <!-- Keyboard Page Up -->
    <string name="KeyText81" translatable="false">Delete</string>
    <string name="KeyCode81" translatable="false">4c</string> <!-- Keyboard Delete Forward -->
    <string name="KeyText82" translatable="false">End</string>
    <string name="KeyCode82" translatable="false">4d</string> <!-- Keyboard End -->
    <string name="KeyText83" translatable="false">PgDn</string>
    <string name="KeyCode83" translatable="false">4e</string> <!-- Keyboard Page Down -->
    <string name="KeyText84" translatable="false">▲</string>
    <string name="KeyCode84" translatable="false">52</string> <!-- Keyboard Up Arrow -->
    <string name="KeyText85" translatable="false">◀</string>
    <string name="KeyCode85" translatable="false">50</string> <!-- Keyboard Left Arrow -->
    <string name="KeyText86" translatable="false">▼</string>
    <string name="KeyCode86" translatable="false">51</string> <!-- Keyboard Down Arrow -->
    <string name="KeyText87" translatable="false">▶</string>
    <string name="KeyCode87" translatable="false">4f</string> <!-- Keyboard Right Arrow -->

2.5 通过HID发送键盘事件

        通过HID设备,发送report,

HidDevice!!.sendReport(HidUtils.mDevice, report.ReportId.toInt(), report.ReportData)


 三,实例

 

       需要源码,请私信

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/78061.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue : 无法加载文件 F:\nodejs\vue.ps1,因为在此系统上禁止运行脚本。

报错信息如下 在使用Windows PowerShell输入指令查看版本时或者用脚手架创建vue项目时都有可能报错&#xff0c;报错信息如下&#xff1a;vue : 无法加载文件 F:\nodejs\vue.ps1&#xff0c;因为在此系统上禁止运行脚本 解决方案&#xff1a; 原因&#xff1a;因为Windows Po…

儿童学python语言能做什么,小孩学python到底好不好

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;儿童学python语言能做什么&#xff0c;小孩学python课程需要多久&#xff0c;现在让我们一起来看看吧&#xff01; 对于刚开始学习编程的孩子来说&#xff0c;图形化的Scratch是很好的启蒙语言。它用类似于拼图的模式&a…

自适应AI chatgpt智能聊天创作官网html源码

我们致力于开发先进的自适应AI智能聊天技术&#xff0c;旨在为用户提供前所未有的聊天体验。通过融合自然语言处理、机器学习和深度学习等领域的顶尖技术&#xff0c;我们的智能聊天系统能够准确理解用户的需求并给出相应的回应。 我们的自适应AI智能聊天系统具备以下核心特点…

软件需求-架构师之路(五)

软件需求 软件需求&#xff1a; 指用户 对系统在功能、行为、性能、设计约束等方面的期望。 分为 需求开发 和 需求管理 两大过程。 需求开发&#xff1a; 需求获取需求分析需求定义&#xff08;需求规格说明书&#xff09;需求验证&#xff1a;拉客户一起评审&#xff0c…

Golang 局部变量、全局变量 声明

文章目录 一、局部变量二、全局变量 一、局部变量 四种声明方式 多变量声明&#xff1a; package mainimport "fmt"//局部变量声明 func main() {//方法一: 声明一个变量和数据类型&#xff0c;不初始化值&#xff1b;默认值为0&#xff1b;var lvA intfmt.Printl…

1572. 矩阵对角线元素的和

题目描述&#xff1a; 给你一个正方形矩阵 mat&#xff0c;请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 示例&#xff1a; 解题思路&#xff1a; 同时求对角线和副对角线上元素的和再减去重合的元素 相关代码&#xf…

JVM---jvm里的内存溢出

目录 堆溢出 虚拟机栈和本地方法栈溢出&#xff08;栈溢出很少出现&#xff09; 方法区和运行时常量池溢出 本机内存直接溢出&#xff08;实际中很少出现、了解即可&#xff09; 堆溢出 堆溢出&#xff1a;最常见的是大list&#xff0c;list里面有很多元素 堆溢出该怎么解决…

途乐证券-新股行情持续火爆,哪些因素影响首日表现?

全面注册制以来&#xff0c;参加打新的投资者数量全体呈现下降。打新收益下降&#xff0c;破发频出的布景下&#xff0c;投资者打新策略从逢新必打逐步向优选个股改变。 经过很多历史数据&#xff0c;从商场定价、参加者热度以及机构重视度维度揭秘了上市后股价体现优秀的个股具…

力扣 279. 完全平方数

题目来源&#xff1a;https://leetcode.cn/problems/perfect-squares/description/ C题解&#xff08;来源代码随想录&#xff09;&#xff1a; 动规五部曲分析如下&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义。dp[j]&#xff1a;和为j的完全平方…

如何仿写简易tomcat 实现思路+代码详细讲解

仿写之前&#xff0c;我们要搞清楚都要用到哪些技术 自定义注解&#xff0c;比如Tomcat使用的是Servlet&#xff0c;我们可以定义一个自己的MyServlet构造请求体和返回体&#xff0c;比如tomcat使用HttpRequest&#xff0c;我们可以自己定义myHttpRequestjava去遍历一个指定目…

Matlab工具NIFTI包的基本功能函数

Matlab工具NIFTI包的基本功能函数 Nifti 格式最初是为神经影像学发明的。神经影像信息学技术计划&#xff08;NIFTI&#xff09;将 NIfTI 格式预设为 ANALYZE7.5 格式的替代品。它最初的应用领域是神经影像&#xff0c;但是也被用在其他领域。这种格式的主要特点就是它包含两个…

Docker容器:docker基础概述、docker安装、docker网络

文章目录 一.docker容器概述1.什么是容器2. docker与虚拟机的区别2.1 docker虚拟化产品有哪些及其对比2.2 Docker与虚拟机的区别 3.Docker容器的使用场景4.Docker容器的优点5.Docker 的底层运行原理6.namespace的六项隔离7.Docker核心概念 二.Docker安装 及管理1.安装 Docker1.…

【Unity造轮子】制作一个简单的2d抓勾效果(类似蜘蛛侠的技能)

文章目录 前言开始1. 实现简单的抓勾效果2. 高阶钩爪效果 源码参考完结 前言 欢迎阅读本文&#xff0c;本文将向您介绍如何使用Unity游戏引擎来实现一个简单而有趣的2D抓勾效果&#xff0c;类似于蜘蛛侠的独特能力。抓勾效果是许多动作游戏和平台游戏中的常见元素&#xff0c;…

zookeeper案例

目录 案例一&#xff1a;服务器动态上下线 服务端&#xff1a; &#xff08;1&#xff09;先获取zookeeper连接 &#xff08;2&#xff09;注册服务器到zookeeper集群&#xff1a; &#xff08;3&#xff09;业务逻辑&#xff08;睡眠&#xff09;&#xff1a; 服务端代码…

区间预测 | MATLAB实现QRBiLSTM双向长短期记忆神经网络分位数回归时间序列区间预测

区间预测 | MATLAB实现QRBiLSTM双向长短期记忆神经网络分位数回归时间序列区间预测 目录 区间预测 | MATLAB实现QRBiLSTM双向长短期记忆神经网络分位数回归时间序列区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 区间预测 | MATLAB实现QRBiLSTM双向长短…

SpringBoot案例 调用第三方接口传输数据

一、前言 最近再写调用三方接口传输数据的项目&#xff0c;这篇博客记录项目完成的过程&#xff0c;方便后续再碰到类似的项目可以快速上手 项目结构&#xff1a; 二、编码 这里主要介绍HttpClient发送POST请求工具类和定时器的使用&#xff0c;mvc三层架构编码不做探究 pom.x…

dom靶场

靶场下载地址&#xff1a; https://www.vulnhub.com/entry/domdom-1,328/ 一、信息收集 获取主机ip nmap -sP 192.168.16.0/24netdiscover -r 192.168.16.0/24端口版本获取 nmap -sV -sC -A -p 1-65535 192.168.16.209开放端口只有80 目录扫描 这里扫描php后缀的文件 g…

设计模式之责任链模式【Java实现】

责任链&#xff08;Chain of Resposibility&#xff09; 模式 概念 责任链&#xff08;chain of Resposibility&#xff09; 模式&#xff1a;为了避免请求发送者与多个请求处理者耦合在一起&#xff0c;于是将所有请求的处理者 通过前一对象记住其下一个对象的引用而连成一条…

Oracle 使用 CONNECT_BY_ROOT 解锁层次结构洞察:在 SQL 中导航数据关系

CONNECT_BY_ROOT 是一个在 Oracle 数据库中使用的特殊函数&#xff0c;它通常用于在层次查询中获取根节点的值。在使用 CONNECT BY 子句进行层次查询时&#xff0c;通过 CONNECT_BY_ROOT 函数&#xff0c;你可以在每一行中获取根节点的值&#xff0c;而不仅仅是当前行的值。 假…

打印出二进制的奇数位和偶数位

void print(int a) {int i0;printf("奇数位&#xff1a;");for(i30;i>0;i-2){printf("%d ",(a>>i)&1);}printf("\n");printf("偶数位&#xff1a;");for(i31;i>1;i-2){printf("%d ",(a>>i)&1);} …