使用JNI做打卡器简单SDK

来源:互联网 发布:java httpclient ssl 编辑:程序博客网 时间:2024/06/06 01:43
      几天之前,有个别的公司的人寻求帮助,说不懂如何获取打卡器的内容,打卡器公司也没SDK,然后让我试着帮忙做一个SDK和demo,然后这就是其中的内容了。

     原理是通过Linux C的程序设计,然后捕获这个打卡器(其实就是个假的键盘)在/dev/input/event?中的按键数据,并整理出来而已。

//// Created by 陈杰柱 on 2017/11/7.//#include "jni.h"#include <stdio.h>#include <linux/input.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <android/log.h>#define DEV_PATH "/dev/input/event4"   //difference is possible/** *  *env JNI环境 *  obj 调用这个函数的类的对象,类似上下文 *  devPath 设备文件路径 */JNIEXPORT void JNICALL Java_com_cjz_testdicard_MonitorFakeKeyboard_startCatchCard(JNIEnv *env, jobject obj, jstring devPath){    int keys_fd;    char ret[2];    struct input_event t;    //传入一个jclass对象表示native()方法所在的类(获取到调用这个函数的类)    jclass native_clazz = (*env)->GetObjectClass(env, obj);    //jclass native_clazz = (*env)->FindClass(env, "com/cjz/testdicard/MonitorFakeKeyboard");    //得到jmethodID    jmethodID callback=(*env)->GetMethodID(env, native_clazz, "callback", "(I)V"); //参数为一个int,返回值为void    keys_fd=open((*env)->GetStringUTFChars(env, devPath, 0), O_RDONLY);    if(keys_fd <= 0)    {        printf("open /dev/input/event device error!\n");        return ;    }    while(1)    {        if(read(keys_fd,&t, sizeof(t)) == sizeof(t))        {            if(t.type==EV_KEY)                if(t.value==0 || t.value==1)                {                    printf("key %d %s\n", t.code, (t.value) ? "Pressed" : "Released");                    //调用java方法回调keyCode给使用方,使用方只要按压后的按键                    if(t.value == 1)                    {                        /*(*env)->CallVoidMethod(env, obj, callback, t.code - 1);*/                        (*env)->CallVoidMethod(env, obj, callback, t.code);                    }                }        }    }    close(keys_fd);    return ;}JNIEXPORT jstring JNICALL Java_com_cjz_testdicard_MonitorFakeKeyboard_test(JNIEnv *env, jobject obj){    return (*env)->NewStringUTF(env, "TestSuccess");}



package com.cjz.testdicard;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.support.annotation.Nullable;import android.util.Log;import java.util.Queue;import java.util.concurrent.LinkedBlockingDeque;/** * Created by ChenJieZhu on 2017/10/16. */public class MonitorFakeKeyboard extends Service {    static {        System.loadLibrary("demo");    }    public native void startCatchCard(String devPath);    public native String test();    /**设备路径**/    public static String DEV_PATH = "/dev/input/event4";    /**底层功能要开root权限的,使用时要注意su命令的路径有没有搞错啊**/    public static String OPEN_ROOT_POWER = "/system/xbin/su";    private Queue<String> stringQueue = new LinkedBlockingDeque<>();    private StringBuffer stringBuffer = new StringBuffer();    private static InputFinishedCallback inputFinishedCallback = null;    @Nullable    @Override    public IBinder onBind(Intent intent) {        return null;    }    public interface InputFinishedCallback {        void stringContentCallback(String content);    }    @Override    public void onCreate() {        super.onCreate();        //试图开root权限        new Thread(new Runnable() {            @Override            public void run() {                try {                    Process su = Runtime.getRuntime().exec(OPEN_ROOT_POWER); //仅针对班牌有效,进入su权限,准备执行命令(大部分机器的su命令在/system/bin文件夹中)                    String cmd = "chmod 777 " + DEV_PATH + "\n"   //更改权限为普通用户可读,退出                            +"exit\n";                    su.getOutputStream().write(cmd.getBytes());  //写入命令                }catch (Exception e)                {                    e.printStackTrace();                }            }        }).start();        new Thread(new Runnable() {            @Override            public void run() {                try {                    String cmd = "chmod 777 " + DEV_PATH;                    Runtime.getRuntime().exec(cmd);                }catch (Exception e)                {                    e.printStackTrace();                }            }        }).start();        //用一个线程开启C语言方法        new Thread(new Runnable() {            @Override            public void run() {                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                startCatchCard(DEV_PATH);            }        }).start();        //文本切割线程        new Thread(new Runnable() {            @Override            public void run() {                while (true) {                    try {                        int oldlen = stringBuffer.length();                        Thread.sleep(100);                        int newlen = stringBuffer.length();                        if (oldlen == newlen && stringBuffer.length() > 0) {                            stringQueue.add(stringBuffer.toString());                            stringBuffer = new StringBuffer();                        }                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }).start();        //文本输出线程        new Thread(new Runnable() {            @Override            public void run() {                while (true) {                    try {                        Thread.sleep(10);                        if (!stringQueue.isEmpty()) {                            String content = stringQueue.poll();                            Log.i("卡号:", content);                            if (MonitorFakeKeyboard.inputFinishedCallback != null && content != null) {                                    MonitorFakeKeyboard.inputFinishedCallback.stringContentCallback(content);                            }                        }                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }).start();    }    //监控触摸设备,java被C语言回调    public void callback(int keyCode){        Log.i("cjz_keyCode:", keyCode + "");        switch (keyCode){            //回车的keyCode            case 28:                stringBuffer.append('\n');                break;            case 11:                stringBuffer.append('0');                break;            //数字为keyCode - 1            default:                if(keyCode >= 2 && keyCode <= 10)                    stringBuffer.append((keyCode - 1) + "");                break;        }    }    public static void setInputFinishedCallback(InputFinishedCallback inputFinishedCallback) {        MonitorFakeKeyboard.inputFinishedCallback = inputFinishedCallback;    }    public static String getDevPath() {        return DEV_PATH;    }    public static void setDevPath(String devPath) {        MonitorFakeKeyboard.DEV_PATH = devPath;    }    public static String getOpenRootPower() {        return OPEN_ROOT_POWER;    }    public static void setOpenRootPower(String openRootPower) {        MonitorFakeKeyboard.OPEN_ROOT_POWER = openRootPower;    }}/**  keyCode对应表         * #define KEY_RESERVED 0         #define KEY_ESC 1         #define KEY_1 2         #define KEY_2 3         #define KEY_3 4         #define KEY_4 5         #define KEY_5 6         #define KEY_6 7         #define KEY_7 8         #define KEY_8 9         #define KEY_9 10         #define KEY_0 11         #define KEY_MINUS 12         #define KEY_EQUAL 13         #define KEY_BACKSPACE 14         #define KEY_TAB 15         #define KEY_Q 16         #define KEY_W 17         #define KEY_E 18         #define KEY_R 19         #define KEY_T 20         #define KEY_Y 21         #define KEY_U 22         #define KEY_I 23         #define KEY_O 24         #define KEY_P 25         #define KEY_LEFTBRACE 26         #define KEY_RIGHTBRACE 27         #define KEY_ENTER 28         #define KEY_LEFTCTRL 29         #define KEY_A 30         #define KEY_S 31         #define KEY_D 32         #define KEY_F 33         #define KEY_G 34         #define KEY_H 35         #define KEY_J 36         #define KEY_K 37         #define KEY_L 38         #define KEY_SEMICOLON 39         #define KEY_APOSTROPHE 40         #define KEY_GRAVE 41         #define KEY_LEFTSHIFT 42         #define KEY_BACKSLASH 43         #define KEY_Z 44         #define KEY_X 45         #define KEY_C 46         #define KEY_V 47         #define KEY_B 48         #define KEY_N 49         #define KEY_M 50         #define KEY_COMMA 51         #define KEY_DOT 52         #define KEY_SLASH 53         #define KEY_RIGHTSHIFT 54         #define KEY_KPASTERISK 55         #define KEY_LEFTALT 56         #define KEY_SPACE 57         #define KEY_CAPSLOCK 58         #define KEY_F1 59         #define KEY_F2 60         #define KEY_F3 61         #define KEY_F4 62         #define KEY_F5 63         #define KEY_F6 64         #define KEY_F7 65         #define KEY_F8 66         #define KEY_F9 67         #define KEY_F10 68         #define KEY_NUMLOCK 69         #define KEY_SCROLLLOCK 70         #define KEY_KP7 71         #define KEY_KP8 72         #define KEY_KP9 73         #define KEY_KPMINUS 74         #define KEY_KP4 75         #define KEY_KP5 76         #define KEY_KP6 77         #define KEY_KPPLUS 78         #define KEY_KP1 79         #define KEY_KP2 80         #define KEY_KP3 81         #define KEY_KP0 82         #define KEY_KPDOT 83         #define KEY_ZENKAKUHANKAKU 85         #define KEY_102ND 86         #define KEY_F11 87         #define KEY_F12 88         #define KEY_RO 89         #define KEY_KATAKANA 90         #define KEY_HIRAGANA 91         #define KEY_HENKAN 92         #define KEY_KATAKANAHIRAGANA 93         #define KEY_MUHENKAN 94         #define KEY_KPJPCOMMA 95         #define KEY_KPENTER 96         #define KEY_RIGHTCTRL 97         #define KEY_KPSLASH 98         #define KEY_SYSRQ 99         #define KEY_RIGHTALT 100         #define KEY_LINEFEED 101         #define KEY_HOME 102         #define KEY_UP 103         #define KEY_PAGEUP 104         #define KEY_LEFT 105         #define KEY_RIGHT 106         #define KEY_END 107         #define KEY_DOWN 108         #define KEY_PAGEDOWN 109         #define KEY_INSERT 110         #define KEY_DELETE 111         #define KEY_MACRO 112         #define KEY_MUTE 113         #define KEY_VOLUMEDOWN 114         #define KEY_VOLUMEUP 115         #define KEY_POWER 116 // SC System Power Down        #define KEY_KPEQUAL 117        #define KEY_KPPLUSMINUS 118        #define KEY_PAUSE 119        #define KEY_SCALE 120 // AL Compiz Scale (Expose)        #define KEY_KPCOMMA 121        #define KEY_HANGEUL 122        #define KEY_HANGUEL KEY_HANGEUL        #define KEY_HANJA 123        #define KEY_YEN 124        #define KEY_LEFTMETA 125        #define KEY_RIGHTMETA 126        #define KEY_COMPOSE 127**/
package com.cjz.testdicard;import android.content.Intent;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.widget.TextView;/** * @author 陈杰柱**/public class MainActivity extends AppCompatActivity {    private TextView tv_card_id;    private Handler handlerShowCardMsg = new Handler()    {        @Override        public void handleMessage(Message msg) {            tv_card_id.append((String) msg.obj);            super.handleMessage(msg);        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        tv_card_id = (TextView) findViewById(R.id.tv_card_id);        //开启刷卡服务:        MonitorFakeKeyboard.setDevPath("/dev/input/event4");        MonitorFakeKeyboard.setOpenRootPower("/system/xbin/su");        MonitorFakeKeyboard.setInputFinishedCallback(new MonitorFakeKeyboard.InputFinishedCallback() {            @Override            public void stringContentCallback(String content) {                Message message = new Message();                message.obj = content;                handlerShowCardMsg.sendMessage(message);            }        });        Intent intent = new Intent(getApplicationContext(), MonitorFakeKeyboard.class);        startService(intent);    }}





原创粉丝点击