使用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); }}
阅读全文
0 0
- 使用JNI做打卡器简单SDK
- Android SDK、NDK、JNI的简单介绍
- Android SDK、NDK、JNI的简单介绍
- JNI 简单使用小结
- jni得简单使用
- JNI的简单使用
- 简单使用JNI
- jni简单使用
- jni的简单使用
- JNI的简单使用
- jni的简单使用
- JNI简单使用
- Bmob SDK 简单使用
- solidworks二次开发 学习日记--3使用solidworks sdk api 和vc做简单开发
- 一个简单的JNI使用
- Android-JNI的简单使用
- Jni的简单使用步骤
- Android JNI/NDK 简单使用
- SOA、SOAP、RPC、REST、DUBBO的区别与联系
- Spring Boot Jpa 常用操作语句
- 进程池线程池
- Hibernate-validator校验框架使用教程
- 二叉树创建、遍历、深度、销毁
- 使用JNI做打卡器简单SDK
- 蓝桥杯 历届试题 回文数字 (Java解题)
- 安卓启动activity的方式(显式和隐式)
- 加一乘二平方
- android-开发一个小项目
- HUD2222(ac自动机)
- C#-WinForm跨线程修改UI界面
- 获取文件的MD5
- Java 注解