Android基于wifi的无线HID设备实现
本文地址:http://www.tongxinmao.com/Article/Detail/id/402
偶然间突发奇想,想到能不能让我们的在我们的手机设备上滑动触摸屏进而控制pc上的鼠标移动,也就说把我们的android设备当成是pc设备的触摸板呢?要想实现这个目标,首先要想一想android设备和pc设备之间的通讯基础是什么?这个通讯技术必须是android和pc同时支持的,目前看来也就是wifi,蓝牙。首先说一下蓝牙,蓝牙是一个提供个人局域网的安全无线电通讯技术,相对于wifi而言,蓝牙的功耗相对较低,尤其是BLE技术使得蓝牙的功耗可以和zigbee媲美了,并且android也支持了基于蓝牙的socket操作。但是pc上的java部分对于蓝牙的socket支持就不是很好了,实现起来比较麻烦。但是wifi虽然功耗相对蓝牙而言比较高了点,但是实现起来非常容易,就是socket就好了!所以在第一版本中,可以先使用wifi作为传输技术。
解决了传输技术之后,还需要解决的是都有哪些数据类型,怎么传递数据,使用什么样的协议的问题。这些问题很关键,这涉及到以后的程序可扩展性问题,如果这部分欠缺考虑的话,那么后期的修改和扩展将是一个灾难。进过仔细考量之后,决定采用google的protobuf来封装所有的数据,因为protobuf灵活,小巧,高效,正好就是我要的。
进过了几天的业余时间开发,终于出来了一个可以运行展示的初级版本,这个版本可以满足基本的需求。目前我已经将这个代码开源出来了,项目地址是github:https://github.com/CreateChance/WirelessHid
UI的设计
我要做的就是使用手机实现一个touchpad和keyboard,这就决定了UI的设计必须符合我们日常见到的实体touchpad和keyboard的样式。进过设计之后,touchpad部分设计为一个fragment,它的布局如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <code class = "hljs xml" ><linearlayout android:layout_height= "match_parent" android:layout_width= "match_parent" android:orientation= "vertical" xmlns:android= "https://schemas.android.com/apk/res/android" xmlns:tools= "https://schemas.android.com/tools" > <linearlayout android:layout_height= "0dp" android:layout_weight= "1" android:layout_width= "match_parent" android:orientation= "horizontal" > <linearlayout android:id= "@+id/speed_control" android:layout_height= "match_parent" android:layout_width= "65dip" android:orientation= "vertical" > <togglebutton android:layout_height= "0dp" android:layout_weight= "1" android:layout_width= "match_parent" android:tag= "1" android:textoff= "@string/speed_slow" android:texton= "@string/speed_slow" > <togglebutton android:layout_height= "0dp" android:layout_weight= "1" android:layout_width= "match_parent" android:tag= "3" android:textoff= "@string/speed_medium" android:texton= "@string/speed_medium" > <togglebutton android:layout_height= "0dp" android:layout_weight= "1" android:layout_width= "match_parent" android:tag= "5" android:textoff= "@string/speed_fast" android:texton= "@string/speed_fast" > </togglebutton></togglebutton></togglebutton></linearlayout> <view android:id= "@+id/touchpad" android:layout_height= "match_parent" android:layout_weight= "1" android:layout_width= "0dp" > <view android:background= "#2b2b2b" android:id= "@+id/scrollzone" android:layout_height= "match_parent" android:layout_width= "65dip" > <linearlayout android:id= "@+id/scroll_speed_control" android:layout_height= "match_parent" android:layout_width= "65dip" android:orientation= "vertical" > <togglebutton android:layout_height= "0dp" android:layout_weight= "1" android:layout_width= "match_parent" android:tag= "1" android:textoff= "@string/speed_slow" android:texton= "@string/speed_slow" > <togglebutton android:layout_height= "0dp" android:layout_weight= "1" android:layout_width= "match_parent" android:tag= "3" android:textoff= "@string/speed_medium" android:texton= "@string/speed_medium" > <togglebutton android:layout_height= "0dp" android:layout_weight= "1" android:layout_width= "match_parent" android:tag= "5" android:textoff= "@string/speed_fast" android:texton= "@string/speed_fast" > </togglebutton></togglebutton></togglebutton></linearlayout> </view></view></linearlayout> <linearlayout android:id= "@+id/buttons" android:layout_height= "65dip" android:layout_width= "match_parent" android:orientation= "horizontal" ><button android:id= "@+id/left_button" android:layout_height= "match_parent" android:layout_weight= "1" android:layout_width= "0dp" android:tag= "0" android:text= "left" ></button><button android:layout_height= "match_parent" android:layout_weight= "1" android:layout_width= "0dp" android:tag= "1" ></button></linearlayout></linearlayout></code><button android:id= "@+id/right_button" android:layout_height= "match_parent" android:layout_weight= "1" android:layout_width= "0dp" android:tag= "2" android:text= "right" ><code class = "hljs xml" > </code></button> |
运行时的效果如下:
<img alt="这里写图片描述" src="https://www.2cto.com/uploadfile/Collfiles/20160614/20160614140910113.png" title="" kf="" ware="" vc="" "="" target="_blank" class="keylink" style="border-width: 0px; padding: 0px; margin: 0px auto; list-style: none; display: block; max-width: 630px; cursor: pointer; width: 630px; height: 354.375px;">vc+4tNTTwcujrNXisr+31tKyysfSu7j2ZnJhZ21lbnSjrNX7zOWyvL7WyOfPwqO6PC9wPg0KPHByZSBjbGFzcz0="brush:java;">
这个布局中首先放上3个textview在一个LinearLayout这三个textview充当真实键盘上的3个led灯:num lock, caps lock, scroll lock。然后就是一个存放实际keyboard布局的LinearLayout容器,这么做的目的是这样的:因为手机的屏幕很小,想要放下一个标准键盘上的所有的按键肯定是不行的,因此需要将键盘分区,然后分别展示,这里的这个容器就是用来存放不同分区,不同布局的键盘部分。目前我把键盘分成了2个部分:主键盘部分,导航部分加上数字部分。其中主键盘部分是我们最常使用的部分,这部分包含了26个字母,0~9数字(字母上排),12个功能键等,导航部分就是上下左右键盘,上页下页部分等,数字部分就是数字小键盘和一些控制按键,我把导航键和数字键合并在一起了,这两部分的布局如下:
主键盘部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | <code class = "hljs xml" ><keyboard> <layout> <key keycode= "27" keylabel= "Esc" > <key keycode= "112" keylabel= "F1" > <key keycode= "113" keylabel= "F2" > <key keycode= "114" keylabel= "F3" > <key keycode= "115" keylabel= "F4" > <key keycode= "116" keylabel= "F5" > <key keycode= "117" keylabel= "F6" > <key keycode= "118" keylabel= "F7" > <key keycode= "119" keylabel= "F8" > <key keycode= "120" keylabel= "F9" > <key keycode= "121" keylabel= "F10" > <key keycode= "122" keylabel= "F11" > <key keycode= "123" keylabel= "F12" > <key keycode= "127" keylabel= "Del" > </key></key></key></key></key></key></key></key></key></key></key></key></key></key></layout> <layout> <key keycode= "192" keylabel= "'" shiftlabel= "~" > <key keycode= "49" keylabel= "1" shiftlabel= "!" > <key keycode= "50" keylabel= "2" shiftlabel= "\@" > <key keycode= "51" keylabel= "3" shiftlabel= "\#" > <key keycode= "52" keylabel= "4" shiftlabel= "$" > <key keycode= "53" keylabel= "5" shiftlabel= "%" > <key keycode= "54" keylabel= "6" shiftlabel= "^" > <key keycode= "55" keylabel= "7" shiftlabel= "&" > <key keycode= "56" keylabel= "8" shiftlabel= "*" > <key keycode= "57" keylabel= "9" shiftlabel= "(" > <key keycode= "48" keylabel= "0" shiftlabel= ")" > <key keycode= "45" keylabel= "-" shiftlabel= "_" > <key keycode= "61" keylabel= "=" shiftlabel= "+" > <key keycode= "8" keylabel= "Backspace ←" weight= "1.5" > </key></key></key></key></key></key></key></key></key></key></key></key></key></key></layout> <layout> <key keycode= "9" keylabel= "Tab ↹" weight= "1.5" > <key keycode= "81" keylabel= "Q" > <key keycode= "87" keylabel= "W" > <key keycode= "69" keylabel= "E" > <key keycode= "82" keylabel= "R" > <key keycode= "84" keylabel= "T" > <key keycode= "89" keylabel= "Y" > <key keycode= "85" keylabel= "U" > <key keycode= "73" keylabel= "I" > <key keycode= "79" keylabel= "O" > <key keycode= "80" keylabel= "P" > <key keycode= "91" keylabel= "[" shiftlabel= "{" > <key keycode= "93" keylabel= "]" shiftlabel= "}" > <key keycode= "92" keylabel= "\\" shiftlabel= "|" > </key></key></key></key></key></key></key></key></key></key></key></key></key></key></layout> <layout> <key keycode= "20" keylabel= "Caps Lock" weight= "1.5" > <key keycode= "65" keylabel= "A" > <key keycode= "83" keylabel= "S" > <key keycode= "68" keylabel= "D" > <key keycode= "70" keylabel= "F" > <key keycode= "71" keylabel= "G" > <key keycode= "72" keylabel= "H" > <key keycode= "74" keylabel= "J" > <key keycode= "75" keylabel= "K" > <key keycode= "76" keylabel= "L" > <key keycode= "59" keylabel= ";" shiftlabel= ":" > <key keycode= "44" keylabel= "'" shiftlabel= """ > <key keycode= "10" keylabel= "Enter ↵" weight= "3.0" > </key></key></key></key></key></key></key></key></key></key></key></key></key></layout> <layout> <key keycode= "16" keyfunc= "Shift" keylabel= "Shift ⇧" weight= "1.5" > <key keycode= "90" keylabel= "Z" > <key keycode= "88" keylabel= "X" > <key keycode= "67" keylabel= "C" > <key keycode= "86" keylabel= "V" > <key keycode= "66" keylabel= "B" > <key keycode= "78" keylabel= "N" > <key keycode= "77" keylabel= "M" > <key keycode= "44" keylabel= "," shiftlabel= "<" > <key keycode= "46" keylabel= "." shiftlabel= ">" > <key keycode= "47" keylabel= "/" shiftlabel= "\?" > <key keycode= "16" keyfunc= "Shift" keylabel= "Shift ⇧" weight= "1.5" > </key></key></key></key></key></key></key></key></key></key></key></key></layout> <layout> <key keycode= "17" keylabel= "Ctrl" weight= "1.5" > <key keycode= "524" keylabel= "Win" > <key keycode= "18" keylabel= "Alt" > <key keycode= "32" keylabel= " " weight= "10.0" > <key keycode= "18" keylabel= "Alt" > <key keycode= "524" keylabel= "Win" > <key keycode= "93" keylabel= "Menu" > <key keycode= "17" keylabel= "Ctrl" weight= "1.5" > </key></key></key></key></key></key></key></key></layout> </keyboard></code> |
导航键部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <code class = "hljs xml" ><keyboard> <layout> <key keycode= "154" keylabel= "Print\nScreen" > <key keycode= "145" keylabel= "Scroll\nLock" > <key keycode= "19" keylabel= "Pause\nBreak" > </key></key></key></layout> <layout> <key keycode= "155" keylabel= "Insert" > <key keycode= "36" keylabel= "Home" > <key keycode= "33" keylabel= "Page Up" > </key></key></key></layout> <layout> <key keycode= "127" keylabel= "Delete" > <key keycode= "35" keylabel= "End" > <key keycode= "34" keylabel= "Page Down" > </key></key></key></layout> <layout> <key visible= "false" > <key keycode= "38" keylabel= "↑" > <key visible= "false" > </key></key></key></layout> <layout> <key keycode= "37" keylabel= "←" > <key keycode= "40" keylabel= "↓" > <key keycode= "39" keylabel= "→" > </key></key></key></layout> </keyboard></code> |
数字键部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <code class = "hljs xml" ><keyboard> |