Java在后台获取USB二维码扫描枪扫描的内容

 项目需要在Web项目中获取扫描枪扫描的内容,项目是Java Web项目。

    拿到扫描枪后,连接在自己的Windows系统上试了下,插上后,不需要装任何驱动,只要有个文本框,就能将扫描到的内容输入到文本框里。反复测试后发现,当前窗口的焦点在哪里,扫描到的内容就显示在哪里。

先按照盒子上的厂家名称找到官网,在官网上查到了技术支持电话,说他们有串口类型的扫描枪,可支持软件编程。挂完电话看了下我们的上位机,是没有串口的,只有USB接口。但是网上搜了一下,有用Java扫描系统的串口,然后根据串口号获得串口输入进来的东西。

然后就以Java 扫描枪为关键字搜索相关资料,以前还真有人做过这个,在开源中国找到一个前辈做的项目,是一个条形码扫描枪,人家实现了。代码那过来研究了一番,大致明白了。

扫描仪其实说白了对电脑来说就是个键盘, 扫描枪将扫描得到的内容解析,然后模拟键盘,一个一个敲入到电脑中,最后按一下回车键!怪不得焦点在哪个窗口就输入到哪个窗口呢。

那就又遇到一个问题,Java代码运行在Jvm虚拟机内,扫描枪或键盘输入的东西,只有操作系统知道,Jvm虚拟机如何知道呢?那就是JNI编程,通过写C/C++代码,监听操作系统的的输入流,然后通过JNI调用。虽然我不会JNI,也不会C/C++,

但幸运的是,SUN公司已经实现了这个代码,弄出一个叫JNA的东西(Java Native Access),给Java提供了访问操作系统键盘鼠标的能力。

然后将人家的代码完整拷贝,想跑一下,结果没jar包,一直报错,根据包名百度,在maven仓库中找相关jar包,(想找官方的jar包和一些文档,无奈,因为被收购的原因,有些链接已经挂了,找不到哇)找到几个,放进去,编译不报错了,运行一直报错,换了好几个jar包,还是不行,真是可郁闷了。

最后在一个国内的仓库网站找到一个清晰的分类,下载里面的大分类下面的一组jar包,运行成功了。网址是www.mvnjar.com

当自己要实现字母键的时候,才发现,字母不是那么好实现的,因为有大小写区分,还有!@#$%^这些字符需要按住shift键输入。JNA提供的钩子函数,我们能拿到的只有键盘的键控代码,当时感觉很麻烦,想想头都大了。

注意,因为二维码扫描枪只能输入大小写字母、数字、特殊字符,所以其他的键我没管,类似于Ctrl、FN、Alt、F快捷键等。

代码如下

运行需要的jar包在仓库下,网址是:https://www.mvnjar.com/net.java.dev.jna/list.html,下载jna-5.2.0.jar和jna-platform-5.2.0.jar这两个就可以。

import java.util.ArrayList;
import java.util.List;

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HMODULE;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinUser.HHOOK;
import com.sun.jna.platform.win32.WinUser.KBDLLHOOKSTRUCT;
import com.sun.jna.platform.win32.WinUser.LowLevelKeyboardProc;
import com.sun.jna.platform.win32.WinUser.MSG;

public class WindowsKeybordListener {

    private static HHOOK hhk;
    private static LowLevelKeyboardProc keyboardHook;
    static List<Character> singleInput = new ArrayList<Character>();

    private static String caseCode() {
        StringBuffer buffer = new StringBuffer();
        for (Character i : singleInput) {
            buffer.append(i);
        }
        return buffer.toString();
    }

    public static void main(String[] args) {
        final User32 lib = User32.INSTANCE;
        HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
        keyboardHook = new LowLevelKeyboardProc() {
            boolean isShiftUp = false;

            @Override
            public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {
                if (nCode >= 0) {
                    switch (wParam.intValue()) {
                    case WinUser.WM_KEYDOWN:// 只监听键盘按下
                         //按下回车键,生成完整的字符串,并清空list
                         if(info.vkCode==13) {
                         String text = caseCode();
                         System.out.println(text);
                         singleInput.clear();
                         break;
                         }
                        
                        //按下的是shift键时,标记一下
                        if (info.vkCode == 160) {
                            isShiftUp = true;
                        }
                        if (!isShiftUp) {
                            if (info.vkCode >= 65 && info.vkCode <= 90) {//字母键
                                singleInput.add((char) (info.vkCode + 32));
                            } else if (info.vkCode >= 219 && info.vkCode <= 221) {//[\]
                                singleInput.add((char) (info.vkCode - 128));
                            } else if (info.vkCode >= 188 && info.vkCode <= 191) {//,-./
                                singleInput.add((char) (info.vkCode - 144));
                            } else if (info.vkCode >= 48 && info.vkCode <= 57) {//数字键
                                singleInput.add((char) info.vkCode);
                            }
                            if (info.vkCode == 186) {
                                singleInput.add(';');
                            }
                            if (info.vkCode == 187) {
                                singleInput.add('=');
                            }
                            if (info.vkCode == 192) {
                                singleInput.add('`');
                            }
                            if (info.vkCode == 222) {
                                singleInput.add('\'');
                            }
                        } else {
                            //大写字母
                            if (info.vkCode >= 65 && info.vkCode <= 90) {
                                singleInput.add((char) info.vkCode );
                            }
                            
                            switch (info.vkCode) {
                            case 186:
                                singleInput.add(':');
                                break;
                            case 187:
                                singleInput.add('+');
                                break;
                            case 188:
                                singleInput.add('<');
                                break;
                            case 189:
                                singleInput.add('_');
                                break;
                            case 190:
                                singleInput.add('>');
                                break;
                            case 191:
                                singleInput.add('?');
                                break;
                            case 192:
                                singleInput.add('~');
                                break;
                            case 219:
                                singleInput.add('{');
                                break;
                            case 220:
                                singleInput.add('|');
                                break;
                            case 221:
                                singleInput.add('}');
                                break;
                            case 222:
                                singleInput.add('\"');
                                break;
                            case 48:
                                singleInput.add('!');
                                break;
                            case 49:
                                singleInput.add('@');
                                break;
                            case 50:
                                singleInput.add('#');
                                break;
                            case 51:
                                singleInput.add('$');
                                break;
                            case 52:
                                singleInput.add('%');
                                break;
                            case 53:
                                singleInput.add('^');
                                break;
                            case 54:
                                singleInput.add('&');
                                break;
                            case 55:
                                singleInput.add('*');
                                break;
                            case 56:
                                singleInput.add('(');
                                break;
                            case 57:
                                singleInput.add(')');
                                break;
                            }
                        }
                        break;
                    case WinUser.WM_KEYUP:// 按键起来
                        if (info.vkCode == 160) {
                            isShiftUp = false;
                        }
                        break;
                    }
                }
                Pointer ptr = info.getPointer();
                long peer = Pointer.nativeValue(ptr);
                return lib.CallNextHookEx(hhk, nCode, wParam, new LPARAM(peer));
            }
        };hhk=lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL,keyboardHook,hMod,0);

    // This bit never returns from GetMessage
    int result;
    MSG msg = new MSG();while((result=lib.GetMessage(msg,null,0,0))!=0)
    {
        if (result == -1) {
            // System.err.println("error in get message");
            break;
        } else {
            // System.err.println("got message");
            lib.TranslateMessage(msg);
            lib.DispatchMessage(msg);
        }
    }lib.UnhookWindowsHookEx(hhk);
}

}
  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱喝西瓜汁的小路哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值