精华内容
下载资源
问答
  • JAVA读取USB扫描

    2015-07-15 17:23:19
    JAVA读取USB扫描枪 代码整洁,注释清晰, 好用
  • jsr80 java 访问 usb

    2015-02-14 08:52:01
    尽管 usb.core.Host 对象的实现对于不同的操作系统是不同的,但是 Java 程序员只需要理解 usb.core 包就可以用 jUSB API 开始应用程序的开发。表 1 列出了 usb.core 的接口和类,Java 程序员应该熟悉它们: 表 1. ...
  • 项目需要在Web项目中获取扫描扫描的内容,项目是Java Web项目,最后部署在Linux系统中的。 拿到扫描枪后,连接在自己的Windows系统上试了下,插上后,不需要装任何驱动,只要有个文本框,就能将扫描到的内容输入...

         项目需要在Web项目中获取扫描枪扫描的内容,项目是Java Web项目,最后部署在Linux系统中的。

        拿到扫描枪后,连接在自己的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。

    运行的时候,人家的是条形码扫描枪,只有0到9是个数字,我们的是二维码扫描枪,输入的文字中有字母数字符合,不够用啊,只能自己再开发了。

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

    分析键控代码值发现,监控代码值跟ASCII代码值中的字母键完全匹配,数字键差一些,字符只有极个别有点规律,于是自己按照键控代码和ASCII码对照了一遍,完整实现了所有字母和数字和字符的输入。

     

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

    下面贴上代码,感觉只是为了实现功能,代码写得很Low。

    运行需要的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);
    }
    
    }

    完整实现后,想在Linux下运行,需要改代码,缺发现jar包中的Unix下面没有像Windows一样有很多类,想找官方文档也找不到,苦逼啊,按理来说有Unix和Mac相关的类,应该是全平台支持的,就是不知道咋调用。

    又在网上各种搜,最后整理了一下,有如下结论:

    有个jintellitype项目,这个项目比较简单,只能注册热键,比如设定一个Ctrl+S可以完成的功能,项目运行在后台,前台按这个组合键也可以执行自己设定的功能,这个项目只能在Windows上运行。

    然后,有外国人,从上面那个项目中过得灵感,开发了Linux下的一个项目jxgrabkey,能注册一些热键在X11窗口中,也是使用C++的钩子函数,通过JNI调用。

    不过上面两个项目都是只为注册快捷键使用的,不适合用于我们这种需要输入大量文字的模块中。

    现在还在找Linux下合适的监听器,等实现了再开一篇帖子写一下。

     

    转载于:https://www.cnblogs.com/plumsq/p/10678762.html

    展开全文
  • 上一篇文章中用JNA实现的键盘监听,在Windows上完美运行,能在后台拿到扫描扫描输入的内容,可在Linux下还是没办法,于是在网上各种找,又找到两种办法,还是一样,在Windows上运行都没问题,最后都失败在Linux,...

    上一篇文章中用JNA实现的键盘监听,在Windows上完美运行,能在后台拿到扫描枪扫描输入的内容,可在Linux下还是没办法,于是在网上各种找,又找到两种办法,还是一样,在Windows上运行都没问题,最后都失败在Linux,最后,我看失败的错误描述,貌似问题都出在了图形界面X11上面还有什么键盘布局上,我的Ubuntu系统,不是标准的那种布局,就运行失败了。想了想,虽然失败了,还是记录一下吧,万一有使用redhat等系统的运行没问题呢?

    一、使用jnativehook监听键盘输入

        jnativehook也是个开源项目,项目地址:kwhat/jnativehook,这个项目也是全平台支持的,Windows,Linux、Mac全都支持,但是Linux下貌似是需要装X11,然后键盘布局也得是相关,不然报错了。我运行的报错如下:

    报错里面的symbols/pc105我也不懂什么东西,网上一查,感觉就是个键盘类型,就像除了我们用的qwer标准键盘外,还有IBM的有F13的键盘,日文输入键盘等,总之就是我装的Ubuntu系统中没有这个文件,导致报错。但是其他系统说不定就没问题。

    这个项目使用也挺简单的,从他的仓库下载JAR包,下载下来,用命令运行java -jar jnativehook.jar,就能出现一个用Swing绘制的图形小程序demo,简单演示监听到的鼠标键盘等输入,具体怎么调用的,将jar包放入eclispe,查看包内的src/java/org/jnativehook/example/NativeHookDemo.java文件就可以看到了。项目要引用,也只需要这一个jar包导入就可以,实现方法也很简单,跟Swing程序中鼠标键盘监听一模一样。下面贴上我简单实现的鼠标监听的代码,其他鼠标监听之类的可以自己研究下官方Demo源码,很明了。

    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    import org.jnativehook.GlobalScreen;
    import org.jnativehook.NativeHookException;
    import org.jnativehook.dispatcher.DefaultDispatchService;
    import org.jnativehook.keyboard.NativeKeyEvent;
    import org.jnativehook.keyboard.NativeKeyListener;
    
    public class Test implements NativeKeyListener{
        private static final Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
        
        public static void main(String[] args) {
            //关闭日志
            logger.setLevel(Level.OFF);
            new Test();
        }
        
        public Test() {
            //添加监听调度员,如果是Swing程序,就用SwingDispatchService,不是就用默认的
            GlobalScreen.setEventDispatcher(new DefaultDispatchService());
            try {
                //注册监听
                GlobalScreen.registerNativeHook();
                //加入键盘监听,
                GlobalScreen.addNativeKeyListener(this);
            } catch (NativeHookException e) {
                e.printStackTrace();
            }
        }
    
        //实现键盘监听的三个方法,根据自己情况实现
        @Override
        public void nativeKeyTyped(NativeKeyEvent nativeEvent) {
            System.out.println("typed"+nativeEvent.paramString());
        }
    
        @Override
        public void nativeKeyPressed(NativeKeyEvent nativeEvent) {
            System.out.println("pressed"+nativeEvent.paramString());
        }
    
        @Override
        public void nativeKeyReleased(NativeKeyEvent nativeEvent) {
            System.out.println("released"+nativeEvent.paramString());
        }
    }

    二、使用JXGrabKey来监听

           JXGrabKey原本是用来注册热键的,上一篇文章中介绍过,用来实现监听键盘有点怪,但如果没有更好的解决办法时,这也是一种办法,

    github项目地址为:https://github.com/friedmag/jxgrabkey  不过这个里面没有相关的jar包和so文件,需要去http://sourceforge.net/projects/jxgrabkey/ 这里面下载,需要引入jar包,还需要加载so文件,还用刀了SWT的相关东西,所以你还得加入SWT的jar包,从eclipse目录下找到\plugins\org.eclipse.swt.win32.win32.x86_64_3.106.0.v20170608-0516.jar,这个包,添加到项目中才可以。

        具体我的思路是将每一个按键当作一个热键,都去实现自己要实现的操作。虽然很麻烦,但确实管用!而且在我的Ubuntu下运行成功!都没报任何错。可以试试,下面贴上我的代码,只简单实现了将0-9的数字捕获,按下回车即输出。

    import java.awt.event.KeyEvent;
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.swing.JOptionPane;
    
    import jxgrabkey.HotkeyConflictException;
    import jxgrabkey.HotkeyListener;
    import jxgrabkey.JXGrabKey;
    
    public class JXGrabKeyTest {
    
        private static final int MY_HOTKEY_INDEX_0 = 0;
        private static final int MY_HOTKEY_INDEX_1 = 1;
        private static final int MY_HOTKEY_INDEX_2 = 2;
        private static final int MY_HOTKEY_INDEX_3 = 3;
        private static final int MY_HOTKEY_INDEX_4 = 4;
        private static final int MY_HOTKEY_INDEX_5 = 5;
        private static final int MY_HOTKEY_INDEX_6 = 6;
        private static final int MY_HOTKEY_INDEX_7 = 7;
        private static final int MY_HOTKEY_INDEX_8 = 8;
        private static final int MY_HOTKEY_INDEX_9 = 9;
        private static final int MY_HOTKEY_INDEX_100 = 100;
        private static boolean hotkeyEventReceived = false;
        
        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) throws Exception {
            //Load JXGrabKey lib
            System.load(new File("lib/libJXGrabKey.so").getCanonicalPath());
            
            //Enable Debug Output
            JXGrabKey.setDebugOutput(true);
            
            //Register some Hotkey
            try{
                //int key = KeyEvent.VK_K, mask = KeyEvent.CTRL_MASK | KeyEvent.ALT_MASK | KeyEvent.SHIFT_MASK;
                //int key = KeyEvent.VK_F2, mask = KeyEvent.ALT_MASK; //Conflicts on GNOME
                
                JXGrabKey.getInstance().registerAwtHotkey(MY_HOTKEY_INDEX_0, KeyEvent.KEY_LOCATION_UNKNOWN, KeyEvent.VK_0);
                JXGrabKey.getInstance().registerAwtHotkey(MY_HOTKEY_INDEX_1, KeyEvent.KEY_LOCATION_UNKNOWN, KeyEvent.VK_1);
                JXGrabKey.getInstance().registerAwtHotkey(MY_HOTKEY_INDEX_2, KeyEvent.KEY_LOCATION_UNKNOWN, KeyEvent.VK_2);
                JXGrabKey.getInstance().registerAwtHotkey(MY_HOTKEY_INDEX_3, KeyEvent.KEY_LOCATION_UNKNOWN, KeyEvent.VK_3);
                JXGrabKey.getInstance().registerAwtHotkey(MY_HOTKEY_INDEX_4, KeyEvent.KEY_LOCATION_UNKNOWN, KeyEvent.VK_4);
                JXGrabKey.getInstance().registerAwtHotkey(MY_HOTKEY_INDEX_5, KeyEvent.KEY_LOCATION_UNKNOWN, KeyEvent.VK_5);
                JXGrabKey.getInstance().registerAwtHotkey(MY_HOTKEY_INDEX_6, KeyEvent.KEY_LOCATION_UNKNOWN, KeyEvent.VK_6);
                JXGrabKey.getInstance().registerAwtHotkey(MY_HOTKEY_INDEX_7, KeyEvent.KEY_LOCATION_UNKNOWN, KeyEvent.VK_7);
                JXGrabKey.getInstance().registerAwtHotkey(MY_HOTKEY_INDEX_8, KeyEvent.KEY_LOCATION_UNKNOWN, KeyEvent.VK_8);
                JXGrabKey.getInstance().registerAwtHotkey(MY_HOTKEY_INDEX_9, KeyEvent.KEY_LOCATION_UNKNOWN, KeyEvent.VK_9);
                JXGrabKey.getInstance().registerAwtHotkey(MY_HOTKEY_INDEX_100, KeyEvent.KEY_LOCATION_UNKNOWN, KeyEvent.VK_ENTER);
            }catch(HotkeyConflictException e){
                JOptionPane.showMessageDialog(null, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE);
                
                JXGrabKey.getInstance().cleanUp(); //Automatically unregisters Hotkeys and Listeners
                //Alternatively, just unregister the key causing this or leave it as it is 
                //the key may not be grabbed at all or may not respond when numlock, capslock or scrollock is on
                return;
            }
                    
            //Implement HotkeyListener
            HotkeyListener hotkeyListener = new jxgrabkey.HotkeyListener(){
                public void onHotkey(int hotkey_idx) {
                    switch(hotkey_idx) {
                        case MY_HOTKEY_INDEX_0:
                            singleInput.add((char) 0);
                        case MY_HOTKEY_INDEX_1:
                            singleInput.add((char) 1);
                        case MY_HOTKEY_INDEX_2:
                            singleInput.add((char) 2);
                        case MY_HOTKEY_INDEX_3:
                            singleInput.add((char) 3);
                        case MY_HOTKEY_INDEX_4:
                            singleInput.add((char) 4);
                        case MY_HOTKEY_INDEX_5:
                            singleInput.add((char) 5);
                        case MY_HOTKEY_INDEX_6:
                            singleInput.add((char) 6);
                        case MY_HOTKEY_INDEX_7:
                            singleInput.add((char) 7);
                        case MY_HOTKEY_INDEX_8:
                            singleInput.add((char) 8);
                        case MY_HOTKEY_INDEX_9:
                            singleInput.add((char) 9);
                        case MY_HOTKEY_INDEX_100:
                            System.out.println(caseCode());
                            singleInput.clear();
                    }
                    //hotkeyEventReceived = true;
                }
            };
            
            //Add HotkeyListener
            JXGrabKey.getInstance().addHotkeyListener(hotkeyListener);
            
    //        //Wait for Hotkey Event
    //        while(!hotkeyEventReceived){
    //            Thread.sleep(1000);
    //        }
    //        
    //        // Shutdown JXGrabKey
    //        JXGrabKey.getInstance().unregisterHotKey(MY_HOTKEY_INDEX); //Optional
    //        JXGrabKey.getInstance().removeHotkeyListener(hotkeyListener); //Optional
    //        JXGrabKey.getInstance().cleanUp();
        }
    }

     

    转载于:https://www.cnblogs.com/plumsq/p/10709122.html

    展开全文
  • Java中面向USB设备编程实例

    热门讨论 2010-12-10 15:16:53
    java也可以扫描usb设备做到片底层的功能
  • java usb扫码枪数据

    2018-11-09 10:11:03
    这是一个WEB扫码器DEMO,启动该项目,用外置的扫码枪进行扫码,可以识别出二维码里的内容并输出。经过反复测试,没有发现什么问题。
  • 以下是其功能选项:需要在命令提示符下执行-java -jar /YourPath/xSmbus-m01-1.0p.jar帮助-列出参数表验证-验证产品是否正常工作测试-用于系统提前维护,检查-确定I2C位置上是否有设备扫描-在00-FF范围内搜索,在I2...
  • 基于usb4java实现的java下的usb通信

    千次阅读 2019-04-02 15:53:42
    基于usb4java实现的java下的usb通信 项目地址:点击打开 使用java开发的好处就是跨平台,基本上java的开发的程序在linux、mac、MS上都可以运行,对应这java的那句经典名言:一次编写,到处运行。这个...

    转https://www.cnblogs.com/sowhat4999/p/4572720.html

    项目地址:点击打开

    使用java开发的好处就是跨平台,基本上java的开发的程序在linux、mac、MS上都可以运行,对应这java的那句经典名言:一次编写,到处运行。这个项目里面有两种包选择,一个是low-level(libus)一个是high-level(javax-usb),相关的优缺点在官方网站上已经说明了,我这里就不翻译了,不过前者好像基于libusb已经好久不更新了,所以还是选择后者。

    配置:你需要在你包的根目录下新建一个名为:javax.usb.properties的文件,里面的内容是这样的:

    javax.usb.services = org.usb4java.javax.Services

    查找usb设备,其实通过usb通信流程大体上都是一致,之前我做过android与arduino通过usb通信,然后java通信走了一遍之后发现是一样的。USB 设备棵树上进行管理所有物理集线器连接一个虚拟的 USB集线器更多集线器可以连接这些集线器任何集线器可以大量连接的 USB设备

    通常需要使用之前搜索特定设备,下面的一个例子如何扫描一个特定供应商产品 id 第一个设备设备:

    复制代码
    public UsbDevice findDevice(UsbHub hub, short vendorId, short productId)
    {
        for (UsbDevice device : (List<UsbDevice>) hub.getAttachedUsbDevices())
        {
            UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor();
            if (desc.idVendor() == vendorId && desc.idProduct() == productId) return device;
            if (device.isUsbHub())
            {
                device = findDevice((UsbHub) device, vendorId, productId);
                if (device != null) return device;
            }
        }
        return null;
    }
    复制代码

    接口

    当你想要与一个接口或者这个接口的端点进行通信时,那么你在使用它之前必须要claim它,并且当你结束时你必须释放它。比如:下面的代码:

    复制代码
    UsbConfiguration configuration = device.getActiveUsbConfiguration();
    UsbInterface iface = configuration.getUsbInterface((byte) 1);
    iface.claim();
    try
    {
        ... Communicate with the interface or endpoints ...
    }
    finally        
    {
        iface.release();
    }
    复制代码

    可能出现的一种情况是你想要通信的接口已经被内核驱动使用,在这种情况下你可能需要通过传递一个接口策略到claim方法以此尝试强制claim:

    复制代码
    iface.claim(new UsbInterfacePolicy()
    {            
        @Override
        public boolean forceClaim(UsbInterface usbInterface)
        {
            return true;
        }
    });
    复制代码

    需要注意的是,接口策略只是为了实现基础USB的一个提示.接口策略在MS-Windows上将被忽略,因为libusb在windows上不支持分派驱动。

    同步 I/O

    这个example发送8个字节到端点0x03:

    复制代码
    UsbEndpoint endpoint = iface.getUsbEndpoint(0x03);
    UsbPipe pipe = endpoint.getUsbPipe();
    pipe.open();
    try
    {
        int sent = pipe.syncSubmit(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
        System.out.println(sent + " bytes sent");
    }
    finally
    {
        pipe.close();
    }
    复制代码

    这个example是从端点0x83读取8个字节:

    复制代码
    UsbEndpoint endpoint = iface.getUsbEndpoint((byte) 0x83);
    UsbPipe pipe = endpoint.getUsbPipe();
    pipe.open();
    try
    {
        byte[] data = new byte[8];
        int received = pipe.syncSubmit(data);
        System.out.println(received + " bytes received");
    }
    finally
    {
        pipe.close();
    }
    复制代码

    异步 I/O

    同步I/O操作与异步I/O操作类似,仅仅是使用asyncSubmint方法取代syncSubmit方法。syncSubmit方法将会阻塞直到请求完成,而asyncSubmit不会阻塞并且立即返回,为了接受请求的返回,你必须为Pipe添加一个监听器,像下面这样:

    复制代码
    pipe.addUsbPipeListener(new UsbPipeListener()
    {            
        @Override
        public void errorEventOccurred(UsbPipeErrorEvent event)
        {
            UsbException error = event.getUsbException();
            ... Handle error ...
        }
    
    @Override
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> dataEventOccurred(UsbPipeDataEvent event)
    {
        </span><span style="color: #0000ff;">byte</span>[] data =<span style="color: #000000;"> event.getData();
        ... Process received data ...
    }
    

    });

    复制代码

    遇到的问题:在Linux上不能打开设备Device,其实是权限的问题导致的,你应该知道在Linux下权限分配是一门很重要的学问,其实该问题在官方网站的FAQ一栏已经提供了解决的办法,地址:点击打开

    在Linux环境下,你需要给你想要通信的usb设备写一个许可文件。在此之前,你可以以root用户运行你的程序检查设备是否可以获取,如果有上述操作有作用,那么我推荐配置下udev以便当设备连接上后你的用户拥有对设备写的权限

      SUBSYSTEM=="usb",ATTR{idVendor}=="89ab",ATTR{idProduct}=="4567",MODE="0660",GROUP="wheel"

    需要该更改的就是PID、VID、GROUP,关于PID和VID信息以及查看相关的接口、端口信息的查看,linux下可以使用一个叫usbview的软件,软件安装很简单,仅仅一条命令:

    sudo apt-get insall usbview

    注意启动的时候需要权限,而且还需要以图形界面显示(sudo usbview在我的Linux Mint没有反应的):

    sudo gksu usbview

     参考官方写的一段简单的代码:

    复制代码
    package nir.desktop.demo;
    

    import java.util.List;

    import javax.usb.UsbConfiguration;
    import javax.usb.UsbConst;
    import javax.usb.UsbControlIrp;
    import javax.usb.UsbDevice;
    import javax.usb.UsbDeviceDescriptor;
    import javax.usb.UsbEndpoint;
    import javax.usb.UsbException;
    import javax.usb.UsbHostManager;
    import javax.usb.UsbHub;
    import javax.usb.UsbInterface;
    import javax.usb.UsbInterfacePolicy;
    import javax.usb.UsbPipe;
    import javax.usb.event.UsbPipeDataEvent;
    import javax.usb.event.UsbPipeErrorEvent;
    import javax.usb.event.UsbPipeListener;

    public class UsbConn {
    private static final short VENDOR_ID = 0x2341;
    / The product ID of the missile launcher. */
    private static final short PRODUCT_ID = 0x43;
    // private static final short VENDOR_ID = 0x10c4;
    // // / The product ID of the missile launcher. */
    // private static final short PRODUCT_ID = -5536;
    private static UsbPipe pipe81, pipe01;

    </span><span style="color: #008000;">/**</span><span style="color: #008000;">
     * 依据VID和PID找到设备device
     * 
     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> hub
     * </span><span style="color: #808080;">@return</span>
     <span style="color: #008000;">*/</span><span style="color: #000000;">
    @SuppressWarnings(</span>"unchecked"<span style="color: #000000;">)
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> UsbDevice findMissileLauncher(UsbHub hub) {
        UsbDevice launcher </span>= <span style="color: #0000ff;">null</span><span style="color: #000000;">;
    
        </span><span style="color: #0000ff;">for</span> (UsbDevice device : (List&lt;UsbDevice&gt;<span style="color: #000000;">) hub.getAttachedUsbDevices()) {
            </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (device.isUsbHub()) {
                launcher </span>=<span style="color: #000000;"> findMissileLauncher((UsbHub) device);
                </span><span style="color: #0000ff;">if</span> (launcher != <span style="color: #0000ff;">null</span><span style="color: #000000;">)
                    </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> launcher;
            } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
                UsbDeviceDescriptor desc </span>=<span style="color: #000000;"> device.getUsbDeviceDescriptor();
                </span><span style="color: #0000ff;">if</span> (desc.idVendor() ==<span style="color: #000000;"> VENDOR_ID
                        </span>&amp;&amp; desc.idProduct() ==<span style="color: #000000;"> PRODUCT_ID) {
                    System.out.println(</span>"找到设备:" +<span style="color: #000000;"> device);
                    </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> device;
                }
            }
        }
        </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">;
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> sendMessage(UsbDevice device, <span style="color: #0000ff;">byte</span><span style="color: #000000;">[] message)
            </span><span style="color: #0000ff;">throws</span><span style="color: #000000;"> UsbException {
        UsbControlIrp irp </span>=<span style="color: #000000;"> device
                .createUsbControlIrp(
                        (</span><span style="color: #0000ff;">byte</span>) (UsbConst.REQUESTTYPE_TYPE_CLASS |<span style="color: #000000;"> UsbConst.REQUESTTYPE_RECIPIENT_INTERFACE),
                        (</span><span style="color: #0000ff;">byte</span>) 0x09, (<span style="color: #0000ff;">short</span>) 2, (<span style="color: #0000ff;">short</span>) 1<span style="color: #000000;">);
        irp.setData(message);
        device.syncSubmit(irp);
    }
    
    </span><span style="color: #008000;">/**</span><span style="color: #008000;">
     * 注意权限的配置问题,在linux下可能无法打开device,解决办法参考官方的FAQ
     * 
     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> args
     </span><span style="color: #008000;">*/</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
        </span><span style="color: #008000;">//</span><span style="color: #008000;"> TODO Auto-generated method stub</span>
    

    UsbDevice device;
    try {
    device = findMissileLauncher(UsbHostManager.getUsbServices()
    .getRootUsbHub());
    if (device == null) {
    System.out.println(“Missile launcher not found.”);
    System.exit(1);
    return;
    }
    UsbConfiguration configuration = device.getActiveUsbConfiguration();//获取配置信息
    UsbInterface iface = configuration.getUsbInterface((byte) 1);//接口
    iface.claim(new UsbInterfacePolicy() {

                @Override
                </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;"> forceClaim(UsbInterface arg0) {
                    </span><span style="color: #008000;">//</span><span style="color: #008000;"> TODO Auto-generated method stub</span>
                    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;
                }
            });
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> for (UsbEndpoint endpoints : (List&lt;UsbEndpoint&gt;) iface
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> .getUsbEndpoints()) {
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> System.out.println("---&gt;"+endpoints.getUsbEndpointDescriptor());
            </span><span style="color: #008000;">//</span><span style="color: #008000;"> }</span>
            UsbEndpoint endpoint81 = iface.getUsbEndpoint((<span style="color: #0000ff;">byte</span>) 0x83);<span style="color: #008000;">//</span><span style="color: #008000;">接受数据地址</span>
            UsbEndpoint endpoint01 = iface.getUsbEndpoint((<span style="color: #0000ff;">byte</span>)0x04);<span style="color: #008000;">//</span><span style="color: #008000;">发送数据地址</span>
            pipe81 =<span style="color: #000000;"> endpoint81.getUsbPipe();
            pipe81.open();
            pipe01 </span>=<span style="color: #000000;"> endpoint01.getUsbPipe();
            pipe01.open();
            </span><span style="color: #0000ff;">byte</span>[] dataSend = { (<span style="color: #0000ff;">byte</span>) 0x00 };<span style="color: #008000;">//</span><span style="color: #008000;">需要发送的数据</span>
    

    pipe01.asyncSubmit(dataSend);
    pipe81.addUsbPipeListener(new UsbPipeListener() {

                @Override
                </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> errorEventOccurred(UsbPipeErrorEvent arg0) {
                    </span><span style="color: #008000;">//</span><span style="color: #008000;"> TODO Auto-generated method stub</span>
    

    System.out.println(arg0);
    }

                @Override
                </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> dataEventOccurred(UsbPipeDataEvent arg0) {
                    </span><span style="color: #008000;">//</span><span style="color: #008000;"> TODO Auto-generated method stub</span>
                    System.out.println(<span style="color: #0000ff;">new</span><span style="color: #000000;"> String(arg0.getData()));
                }
            });
    

    // pipe81.close();
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } finally {
    //
    }
    }
    }

    复制代码

    其中的一些接口、端口都是依据usbview写的,数据是发成功了(RX灯亮了),但是因为我使用的是arduino,里面的代码不知道怎么写,如果有这方便的高手还请帮我一下,谢谢。FQ看了下有的人用的是同步传输出现的问题,相关的解决办法,这里我就完全粘贴、复制了:Here is an abbreviated example. Note that I have removed from this, allchecks, error handling, and such.It is just the logic of creating two pipes for two endpoints. One IN andone OUT. Then using them to do a write and a read.It assumes that endpoint 2 is an OUT and endpoint 4 is an IN.Note also that the name of an IN endpoint is OR'd with 0x80:

    import javax.usb.*;
    

    public class Example {

    public static void main(String[] args) throws Exception {
    UsbDevice usbDevice = …getUsbDevice by matching vID, pID, knowing
    the path… or whatever works for you…
    usbDevice.getUsbConfigurations();
    UsbConfiguration config = usbDevice.getActiveUsbConfiguration();
    UsbInterface xface = config.getUsbInterface((byte)0);
    xface.claim();

    UsbEndpoint endPt2 = xface.getUsbEndpoint((byte)2); //OUT
    endpoint
    UsbEndpoint endPt4 = xface.getUsbEndpoint((byte)(4 | 0x80) ); //IN
    endpoint

    UsbPipe pipe2 = endPt2.getUsbPipe();
    pipe2.open();
    UsbPipe pipe4 = endPt4.getUsbPipe();
    pipe4.open();

    //Use the pipes:
    byte[] bytesToSend = new byte[] {1,2,3}; //Going to send out these 3
    bytes
    UsbIrp irpSend = pipe2.createUsbIrp();
    irpSend.setData(bytesToSend);
    pipe2.asyncSubmit(irpSend); //Send out some bytes
    irpSend.waitUntilComplete(1000); //Wait up to 1 second

    byte[] bytesToRead = new byte[3]; //Going to read 3 bytes into here
    UsbIrp irpRead = pipe2.createUsbIrp();
    irpRead.setData(bytesToRead);
    pipe4.asyncSubmit(irpRead); //Read some bytes
    irpRead.waitUntilComplete(1000); //Wait up to 1 second
    }
    }

    View Code

    下面是我监听数据返回点完整代码:

     UsbConn.java:

    package DemoMath;
    

    import java.util.List;

    import javax.usb.UsbConfiguration;
    import javax.usb.UsbConst;
    import javax.usb.UsbControlIrp;
    import javax.usb.UsbDevice;
    import javax.usb.UsbDeviceDescriptor;
    import javax.usb.UsbEndpoint;
    import javax.usb.UsbException;
    import javax.usb.UsbHostManager;
    import javax.usb.UsbHub;
    import javax.usb.UsbInterface;
    import javax.usb.UsbInterfacePolicy;
    import javax.usb.UsbPipe;
    import javax.usb.util.UsbUtil;

    public class UsbConn {
    private static final short VENDOR_ID = 0x04b4;
    private static final short PRODUCT_ID = 0x1004;
    private static final byte INTERFACE_AD= 0x00;
    private static final byte ENDPOINT_OUT= 0x02;
    private static final byte ENDPOINT_IN= (byte) 0x86;
    private static final byte[] COMMAND = {0x01,0x00};

    @SuppressWarnings(</span><span style="color: #800000;">"</span><span style="color: #800000;">unchecked</span><span style="color: #800000;">"</span><span style="color: #000000;">)
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> UsbDevice findMissileLauncher(UsbHub hub) {
        UsbDevice launcher </span>= <span style="color: #0000ff;">null</span><span style="color: #000000;">;
    
        </span><span style="color: #0000ff;">for</span> (UsbDevice device : (List&lt;UsbDevice&gt;<span style="color: #000000;">) hub.getAttachedUsbDevices()) {
            </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (device.isUsbHub()) {
                launcher </span>=<span style="color: #000000;"> findMissileLauncher((UsbHub) device);
                </span><span style="color: #0000ff;">if</span> (launcher != <span style="color: #0000ff;">null</span><span style="color: #000000;">)
                    </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> launcher;
            } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
                UsbDeviceDescriptor desc </span>=<span style="color: #000000;"> device.getUsbDeviceDescriptor();
                </span><span style="color: #0000ff;">if</span> (desc.idVendor() ==<span style="color: #000000;"> VENDOR_ID
                        </span>&amp;&amp; desc.idProduct() ==<span style="color: #000000;"> PRODUCT_ID) {
                    System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">发现设备</span><span style="color: #800000;">"</span> +<span style="color: #000000;"> device);
                    </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> device;
                }
            }
        }
        </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">;
    }
    </span><span style="color: #008000;">//</span><span style="color: #008000;">command for controlTransfer</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> sendMessage(UsbDevice device, <span style="color: #0000ff;">byte</span><span style="color: #000000;">[] message)
            throws UsbException {
        UsbControlIrp irp </span>=<span style="color: #000000;"> device
                .createUsbControlIrp(
                        (</span><span style="color: #0000ff;">byte</span>) (UsbConst.REQUESTTYPE_TYPE_CLASS |<span style="color: #000000;"> UsbConst.REQUESTTYPE_RECIPIENT_INTERFACE),
                        (</span><span style="color: #0000ff;">byte</span>) <span style="color: #800080;">0x09</span>, (<span style="color: #0000ff;">short</span>) <span style="color: #800080;">2</span>, (<span style="color: #0000ff;">short</span>) <span style="color: #800080;">1</span><span style="color: #000000;">);
        irp.setData(message);
        device.syncSubmit(irp);
    }
    </span><span style="color: #008000;">/*</span><span style="color: #008000;">*
     * Class to listen in a dedicated Thread for data coming events.
     * This really could be used for any HID device.
     </span><span style="color: #008000;">*/</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> HidMouseRunnable implements Runnable
    {
        </span><span style="color: #008000;">/*</span><span style="color: #008000;"> This pipe must be the HID interface's interrupt-type in-direction endpoint's pipe. </span><span style="color: #008000;">*/</span>
        <span style="color: #0000ff;">public</span> HidMouseRunnable(UsbPipe pipe) { usbPipe =<span style="color: #000000;"> pipe; }
        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run()
        {
            </span><span style="color: #0000ff;">byte</span>[] buffer = <span style="color: #0000ff;">new</span> <span style="color: #0000ff;">byte</span><span style="color: #000000;">[UsbUtil.unsignedInt(usbPipe.getUsbEndpoint().getUsbEndpointDescriptor().wMaxPacketSize())];
            @SuppressWarnings(</span><span style="color: #800000;">"</span><span style="color: #800000;">unused</span><span style="color: #800000;">"</span><span style="color: #000000;">)
            </span><span style="color: #0000ff;">int</span> length = <span style="color: #800080;">0</span><span style="color: #000000;">;
    
            </span><span style="color: #0000ff;">while</span><span style="color: #000000;"> (running) {
                </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
                    length </span>=<span style="color: #000000;"> usbPipe.syncSubmit(buffer);
                } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> ( UsbException uE ) {
                    </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (running) {
                        System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">Unable to submit data buffer to HID mouse : </span><span style="color: #800000;">"</span> +<span style="color: #000000;"> uE.getMessage());
                        </span><span style="color: #0000ff;">break</span><span style="color: #000000;">;
                    }
                }
                </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (running) {
    

    // System.out.print(“Got " + length + " bytes of data from HID mouse :”);
    // for (int i=0; i<length; i++)
    // System.out.print(" 0x" + UsbUtil.toHexString(buffer[i]));
    try {
    String result = DataFix.getHexString(buffer);
    System.out.println(result);
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }
    /
    * Stop/abort listening for data events.
    /
    public void stop()
    {
    running = false;
    usbPipe.abortAllSubmissions();
    }
    public boolean running = true;
    public UsbPipe usbPipe = null;
    }
    /*
    * get the correct Interface for USB
    * @param device
    * @return
    * @throws UsbException
    /
    public static UsbInterface readInit() throws UsbException{
    UsbDevice device = findMissileLauncher(UsbHostManager.getUsbServices()
    .getRootUsbHub());
    if (device == null) {
    System.out.println(“Missile launcher not found.”);
    System.exit(1);
    }
    UsbConfiguration configuration = device.getActiveUsbConfiguration();
    UsbInterface iface = configuration.getUsbInterface(INTERFACE_AD);//Interface Alternate Number
    //if you using the MS os,may be you need judge,because MS do not need follow code,by tong
    iface.claim(new UsbInterfacePolicy() {
    @Override
    public boolean forceClaim(UsbInterface arg0) {
    // TODO Auto-generated method stub
    return true;
    }
    });
    return iface;
    }
    /*
    * 异步bulk传输,by tong
    * @param usbInterface
    * @param data
    /
    public static void syncSend(UsbInterface usbInterface,byte[] data) {
    UsbEndpoint endpoint = usbInterface.getUsbEndpoint(ENDPOINT_OUT);
    UsbPipe outPipe = endpoint.getUsbPipe();
    try {
    outPipe.open();
    outPipe.syncSubmit(data);
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }finally{
    try {
    outPipe.close();
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    public static HidMouseRunnable listenData(UsbInterface usbInterface) {
    UsbEndpoint endpoint = usbInterface.getUsbEndpoint(ENDPOINT_IN);
    UsbPipe inPipe = endpoint.getUsbPipe();
    HidMouseRunnable hmR = null;
    try {
    inPipe.open();
    hmR = new HidMouseRunnable(inPipe);
    Thread t = new Thread(hmR);
    t.start();
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return hmR;
    }
    /*
    * 主程序入口
    *
    * @param args
    */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    UsbInterface iface;
    try {
    iface = readInit();
    listenData(iface);
    syncSend(iface, COMMAND);
    } catch (UsbException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }

    View Code

     

    展开全文
  • java调用扫描仪1

    千次阅读 2013-10-26 18:39:15
    基于Applet的Web在线扫描仪控件 基于JAVAEE的B/S架构由于java语言的跨平台性 所以操控Window客户端资源能力有限, 目前比较流行是用其他语言如Delphi,VB,C++开发客户端控件 然后再html中用js调用。  但对于java...

    基于Applet的Web在线扫描仪控件

    基于JAVAEE的B/S架构由于java语言的跨平台性

    所以操控Window客户端资源能力有限,
    目前比较流行是用其他语言如Delphi,VB,C++开发客户端控件
    然后再html中用js调用。
        但对于java开发者而言,这种方式比较不方便,尤其在分工合作
    而对方开发水平也有限的情况下,调试比较繁琐。
    统观现在的在线扫描控件,大部分都是收费的,无论国内还是国外。
      收费,代码不可见应该是JAVA程序员比较反感的吧,总感觉受制于人,至少我是这样的啊。

    Applet现在虽然不流行被ActiveX所替代,但对java程序员开发B/S架构
    需要操纵客户端资源,还是比较可行的。
    尤其是在HtmlConvert的出现后,其编程方式可以把Applet标签转换成
    object标签。

    虽说需要客户端下载并安装JRE,下载速度比较慢,但由于是在企业级应用的局域网的
    环境下,这些并不是最大的缺点。(现在jre可以通过cab包的形式在客户端自动下载及安装jre,通过改变url让此cab在局域网内下载
    html中如下:<object
        classid = "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
        codebase = "http://localhost:8090/emr-archive-app/arc/cabs/jinstall-1_5-windows-i586.cab#Version=5,0,0,5"
        WIDTH = "240" VSPACE = "20" ALT = "Sorry" >
        <PARAM NAME = CODE VALUE = "com.founder.applet.scan.ScannerApplet.class" >
        <PARAM NAME = ARCHIVE VALUE = "scanner.jar" >
        <param name = "type" value = "application/x-java-applet;version=1.5">
        <param name = "scriptable" value = "false">
    </object>)

    目前所做的项目是基于JAVA EE的应用,需要在客户端进行文档扫描并提交到客户端
    进行进一步处理,如进行OCR文字识别,建立基于内容检索的索引创建等应用。

    目前能用的反应普遍比较好的是ScanOnWeb控件,做到确实比较好,好处就不再细说。,
    但我试用完后发现的缺点如下:
    1.收费,虽说不贵,但对比较大的管理规范的公司,由于售后服务产品保障方面,购买审批难。
    2.通用性并不好,同样是遵循Twain协议的扫描仪器,有的扫描仪并不能很好的识别
    我用的摄像头,带独立电源的Microtek,和USB供电的Canon进行测试
    其中的最新的Canon他无法识别,需要先进入控件的界面然后再插上扫描仪,如果一直
    连着扫描仪,将报错。
    3.扫描的文件太大了,普通的一页纸张可以达到2M。

    由于目前的扫描仪或者摄像头都支持Twain协议,同时也有一个开源的mmsc_tawin工java开发者使用
    所以开发基于Applet的扫描仪控件是可行的。

    开发步骤如下:
    1.基于mmsc_twain开发扫描Applet
    2.把mmsc_twain的jar包及相关依赖的jar包中class按
    包的结构解压到一个目录下。
    3.把这些class打包成一个jar包
    3.对这个jar包进行数字签名
    4.通过html_conv把html中的applet标签,转换成object
    通过以上步骤即可完成在线扫描的控件。
    下面代码是通过applet及servlet把扫描的文件
    转成PDF格式然后上传到web服务器,进行进一步的文字识别
    及基于内容检索。

    经过测试,基于applet的在线扫描的优点是硬件识别率高,扫描的文件小,速度快,秉承b/s架构易于维护特性,对java开着者而言最重要的是灵活,
    可以自由控制。
    缺点也比较明显就是对扫描的文件不能像scanOnWeb那样进行图像的进一步处理。但对于只是简单的纸质文档扫描的应用来说这并不是应用的重点。
    如果有需要比较完整的代码的可以继续交流。
    ======================================================================
    代码参考如下:

    (htmlConvert,及jar包的数字签名,mmsc_twain的源码网上都可以找到)
    测试代码如下:
    import java.applet.Applet;
    import java.awt.Button;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.awt.print.PrinterException;
    import java.io.BufferedWriter;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.URLConnection;

    import javax.imageio.ImageIO;

    import org.apache.pdfbox.pdmodel.PDDocument;

    import com.lowagie.text.Document;
    import com.lowagie.text.Font;
    import com.lowagie.text.Image;
    import com.lowagie.text.Paragraph;
    import com.lowagie.text.pdf.PdfWriter;

    import uk.co.mmscomputing.device.scanner.Scanner;
    import uk.co.mmscomputing.device.scanner.ScannerDevice;
    import uk.co.mmscomputing.device.scanner.ScannerIOException;
    import uk.co.mmscomputing.device.scanner.ScannerIOMetadata;
    import uk.co.mmscomputing.device.scanner.ScannerListener;

    public class ScannerApplet extends Applet {
    Scanner scanner = Scanner.getDevice();
    public void init() {
    Button btn = new Button();
    btn.setLabel("扫描");
    btn.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent event) {
    System.out.println(event.getActionCommand() + "||"
    + event.getSource() + "MouseClick");
    try {
    scan();
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    });
    add(btn);
    }

    public void paint(Graphics g) {
    }

    private void scan() throws ScannerIOException {

    scanner.select();
    scanner.addListener(new ScannerListener() {
    public void update(ScannerIOMetadata.Type type,
    ScannerIOMetadata metadata) {
    System.out.println("*********Type:"+type.msg);
    if (type.equals(ScannerIOMetadata.ACQUIRED)) {
    BufferedImage image = metadata.getImage();
    System.out.println("Have an image now!");
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    try {
    ImageIO.write(image, "jpg", os);
    } catch (Exception e) {
    e.printStackTrace();
    }
    // 创建PDF
    ByteArrayOutputStream bop = createPDF(os);

    // 文件上传
    upLoad(bop);
    } else if (type.equals(ScannerIOMetadata.NEGOTIATE)) {
    ScannerDevice device = metadata.getDevice();
    /**
    try {
    device.setShowUserInterface(true);
    device.setShowProgressBar(true);
    device.setResolution(100);
    } catch (Exception e) {
    e.printStackTrace();
    }
    ***/
    } else if (type.equals(ScannerIOMetadata.STATECHANGE)) {
    System.err.println(metadata.getStateStr());
    if (metadata.isFinished()) {
    BufferedImage image = metadata.getImage();
    System.out.println("###//Have an image now!");
    }
    } else if (type.equals(ScannerIOMetadata.EXCEPTION)) {
    metadata.getException().printStackTrace();
    }
    }

    });

    scanner.acquire();
    }

    private ByteArrayOutputStream createPDF(ByteArrayOutputStream os) {
    Document document = new Document();
    ByteArrayOutputStream bop = new ByteArrayOutputStream();
    try {
    PdfWriter.getInstance(document, bop);
    // PdfWriter.getInstance(document,new FileOutputStream(
    // "E:/study/applet/TestPDF.PDF"));
    document.open();

    // Font fnt = new Font();
    // document.add(new Paragraph("load a tif image file"));
    Image img = Image.getInstance(os.toByteArray());
    // img.setWidthPercentage(100);
    document.addAuthor("EmrArchiveApplication");
    document.addCreationDate();
    document.addCreator("iText library");
    document.addTitle("ScannerImg");
    document.add(img);

    // PDDocument pdoc = PDDocument.load(new File(
    // "E:/study/applet/TestPDF.PDF"));
    //
    // pdoc.print();

    } catch (Exception e) {
    System.err.println(e.getMessage());
    }
    document.close();
    return bop;
    }

    private void upLoad(ByteArrayOutputStream pdf) {
    try {
    URLConnection con = getConnection();
    FileOutputStream fo = new FileOutputStream("C:/archive/APT.pdf");

    fo.write(pdf.toByteArray(), 0, pdf.toByteArray().length);
    fo.close();

    OutputStream os = con.getOutputStream();
    DataOutputStream ds = new DataOutputStream(os); 
    ds.write(pdf.toByteArray());
    ds.flush();

    // 关闭发送流,提交数据
    ds.close();
    // 调用HttpURLConnection连接对象的getInputStream()函数,
    // 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。
    InputStream is = con.getInputStream(); // <===注意,实际发送请求的代码段就在这里

    System.out.println("###EEEEEE");
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }

    private static HttpURLConnection getConnection() throws IOException {
    URL url = new URL(
    "http://127.0.0.1:8090/emr-archive-app/PDFScanerServlet");
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    // 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在
    // http正文内,因此需要设为true, 默认情况下是false;
    con.setDoOutput(true);

    // 设置是否从httpUrlConnection读入,默认情况下是true;
    con.setDoInput(true);

    // Post 请求不能使用缓存
    con.setUseCaches(false);

    // 设定传送的内容类型是可序列化的java对象
    // (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
    con.setRequestProperty("Content-Type ", "application/octet-stream ");

    // 设定请求的方法为"POST",默认是GET
    con.setRequestMethod("POST");

    return con;
    }

    public static void main(String[] avs) throws IOException {
    FileInputStream fi = new FileInputStream("C:/archive/BH.pdf");
    ByteArrayOutputStream bo = new ByteArrayOutputStream();
    int index = 0;
    byte[] tmp = new byte[1024];
    while((index = fi.read(tmp))>-1){
    bo.write(tmp, 0, index);
    };

    new ScannerApplet().upLoad(bo);

    }

    展开全文
  • JAVA实现监听U盘插入 扫描文件

    千次阅读 2019-04-02 16:29:55
    想用Java实现监听USB端口是否有移动设备插入,然后操作移动设备内的文件。网站查找资料后发现有个jsr-80的项目,下面先介绍一下什么是JSR:JSR是Java Specification Requests的缩写,意思是Java 规范请求。是指向JCP...
  • windows(7/xp)(32/64)系统下,有个扫码枪,是usb接口.运行tomcat后,当扫码枪扫描到条码,就将条码的数据保存下来.准确获取到扫码枪,用纯java开发.
  • Chipscope扫描JTAG时出现如下错误 COMMAND: open_cable INFO: Attempting to connect to an existing server. INFO: Successfully opened connection to server: localhost:50001 (localhost/127.0.0.1) ERROR: ...
  • usb接二维码扫描要驱动吗It’s a common sight for many Windows users: you pop in your flash drive or the memory card from your camera and Windows insists there is some problem that needs fixing....
  • 这个工具包可以帮助开发人员,通过基于USB的硬件扫描,轻松的添加文档扫描到Android apps上。开发人员可以按照这个工具包中一步一步的提示,将USB扫描集成到现有的Android应用程序上,或者是建立一个新的带有扫描...
  • Java 应用程序中访问USB设备
  • Java制作了一个可以自动在探探评分颜值的程序 通过adb操作,手机和模拟器都可以 规则  可以自己设定颜值分数, 达到标准自动划到喜欢  不达标或者无法识别人脸自动拉到不喜欢  部分代码  全部源码文件在下方,...
  • 在本文通过提供使Java 应用程序可以使用 USB 设备的 API 而使这个过程变得更容易.  Java 平台一直都以其平台无关性自豪。虽然这种无关性有许多好处,但是它也使得编写与硬件交互的 Java 应用程序的过程变得相当...
  • 原文出处:http://www.ibm.com/developerworks/cn/java/j-usb/在 Java 应用程序中访问 USB 设备介绍 USB、jUSB 和 JSR-80Java 平台一直都以其平台无关性自豪。虽然这种无关性有许多好处,但是它也使得编写与硬件交互...
  • 从Javascript打印命令和文件,管理打印机和扫描文档 是针对客户端打印和扫描方案的Javascript + Client App解决方案,旨在用于在任何Web平台(如ASP.NET,PHP,Django,Ruby On Rails(RoR),Express.js和更多的! ...
  • java应用程序怎样获取外接设备信号(通过usb) 谁说JAVA不能够操作底层硬件,这几个就是实例。 1、http://today.java.net/pub/a/today/2006/07/06/java-and-usb.html?page=2 (IBM的JCP:Java Community Process):...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,916
精华内容 3,166
关键字:

java扫描usb

java 订阅