Java后台獲取USB二維碼掃描槍內容(Java監聽系統鍵盤操作)


上一篇文章中用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();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM