1. 程式人生 > >Android App層通過JNI從驅動獲取Input Event

Android App層通過JNI從驅動獲取Input Event

package com.jiagutech.input;
 
import java.util.LinkedList;
 
import android.os.Handler;
 
 
public class InputPen {
 
    /**********************************************************************************/
    private static InputPen instance = null;
 
    private boolean mStarted = false;
 
    private final static String TAG = "InputPen";
 
    //主執行緒Handler
    private Handler mHandler = null;
    //PenEvent列表
    private LinkedList<PenEvent> mEventList = new LinkedList<PenEvent>();
    //鎖
    private Object mListLock = new Object();
 
    /*******************************************************************/
    //以下定義請參考input_event.h檔案
    private final static int EV_SYN = 0x0;
    private final static int EV_KEY = 0x01;
 
    private final static int EV_ABS = 0x03;
 
 
    private final static int  ABS_X = 0x00;
    private final static int  ABS_Y = 0x01;
    private final static int  ABS_PRESSURE = 0x18;
    private final static int  BTN_TOUCH = 0x14a;
    private final static int  BTN_TOOL_PEN = 0x140;
    private final static int  BTN_STYLUS = 0x14b;
    /*******************************************************************/
    //原始的x最大解析度
    private static final float MAX_X = 15360.0f;
    //螢幕x最大解析度
    private static final float MAX_X_STANDARD = 1280.0f;
 
    //原始的y最大解析度
    private static final float MAX_Y = 9600.0f;
    //螢幕y最大解析度
    private static final float MAX_Y_STANDARD = 800.0f;
 
    //原始的最大壓力資料
    private static final float MAX_PRESSURE = 1023.0f;
    //Android標準最大壓力資料
    private static final float MAX_PRESSURE_STANDARD= 1.0f;
 
    private int _x=-1,_y=-1,_pressure=-1;
    private int _bintouch = 0, _lastBinTouch = 0;
    //x軸轉換系數
    private float xScale = MAX_X_STANDARD / MAX_X;
    //y軸轉換系數
    private float yScale = MAX_Y_STANDARD / MAX_Y;
    //壓力值轉換系統
    private float pScale = MAX_PRESSURE_STANDARD / MAX_PRESSURE;
 
    //y軸便宜
    private float yOffset = 73.0f;
 
    /**
     * 載入libinput_pen.so,並初始化回撥函式
     */
    static {
        try {
            System.loadLibrary("input_pen");
            class_init_native();
 
 
        } catch (UnsatisfiedLinkError e) {
            e.printStackTrace();
        }
 
    }
 
    private InputPen() {
    }
 
    /**
     * 單例模式
     * @return
     */
    public static synchronized InputPen getInstance() {
        if (instance == null) {
            instance = new InputPen();
        }
        return instance;
    }
 
    /**
     * 通知主執行緒獲取PenEvent進行處理
     *
     */
    private void onPenTouch() {
        if (mHandler != null) {
            mHandler.sendEmptyMessage(0);
        }
 
    }
 
    /**
     * 設定主執行緒handler
     * @param handler
     */
    public void setHandler(Handler handler) {
        mHandler = handler;
    }
 
    /**
     * 新增PenEvent到list
     * @param event
     */
    private void addPenEvent(PenEvent event) {
        synchronized (mListLock) {
            mEventList.add(event);
        }
    }
 
    /**
     * 從list獲取最舊的PenEvent
     * @return
     */
    public PenEvent getPenEvent() {
        PenEvent event = null;
        synchronized (mListLock) {
            if (mEventList.size() > 0) {
                event = mEventList.removeFirst();
            }
        }
 
        return event;
    }
 
 
    /*******************************************************************/
    //public method
 
    /**
     * 座標轉換,並生成PenEvent資料
     * @param event
     */
    protected void transform(PenEvent event) {
        float x = MAX_Y_STANDARD - ((float)_y) * yScale;
        float y = (float)_x * xScale - yOffset;
        float p = (float)_pressure * pScale;
        event.setX(x);
        event.setY(y);
        event.setPressure(p);
    }
 
    /**
     * 處理input_event資料
     */
    protected void processEvent() {
 
        if (_bintouch != _lastBinTouch ) {
            _lastBinTouch = _bintouch;
            //Log.d(TAG, String.format("x=%d,y=%d,pressure=%d,bintouch=%d", _x,_y,_pressure,_bintouch));
            if (_bintouch == 1) { //down事件
                PenEvent event = new PenEvent();
                event.setAction(PenEvent.ACTION_DOWN);
                transform(event);
                addPenEvent(event);
                onPenTouch();
 
            } else { //up事件
                PenEvent event = new PenEvent();
                event.setAction(PenEvent.ACTION_UP);
                transform(event);
                addPenEvent(event);
                onPenTouch();
            }
        } else if (_bintouch == 1) { //move事件
            PenEvent event = new PenEvent();
            event.setAction(PenEvent.ACTION_MOVE);
            transform(event);
            addPenEvent(event);
            onPenTouch();
 
        }
 
 
 
 
    }
 
    /**
     * 獲取input_event資料,由jni層呼叫此函式
     * @param type
     * @param code
     * @param value
     */
    protected void getEvent(int type, int code, int value) {
        switch (type) {
 
        case EV_SYN:
            processEvent();
            break;
 
        case EV_KEY:
            if (code == BTN_TOUCH) {
                _bintouch = value;
            }
            break;
        case EV_ABS:
            if (code == ABS_X) {
                _x = value;
            } else if (code == ABS_Y) {
                _y = value;
            } else if (code == ABS_PRESSURE) {
                _pressure = value;
            }
            break;
        default:
            break;
        }
    }
 
    /**
     * 啟動執行緒
     */
    protected void start() {
        if (!mStarted) {
            if (native_input_pen_init()) {
                mStarted = true;
            }
 
        }
 
 
    }
 
    /**
     * 停止執行緒
     */
    protected void stop() {
        if (mStarted) {
            native_input_pen_exit();
            mStarted = false;
        }
 
    }
 
    public void dispose() {
        stop();
    }
 
    @Override
    protected void finalize() throws Throwable {
 
        stop();
        // TODO Auto-generated method stub
        super.finalize();
    }
 
 
    /*******************************************************************/
    //native method
    protected  static native void class_init_native();
 
    protected  native boolean native_input_pen_init();
 
    protected  native void native_input_pen_exit();
}
 
 
 


相關推薦

Android App通過JNI驅動獲取Input Event

package com.jiagutech.input; import java.util.LinkedList; import android.os.Handler; public class InputPen { /*******************************

請問如何在Android APP獲取Framework中的滑鼠位置資訊。

這個問題,困擾我幾天了,我們是在Android5.1的平臺寫一個應用,SDK已經root,需要在APP上以獲取當前滑鼠的X,Y值,已經通過JNI獲取到滑鼠動作,按鍵,觸控式螢幕的動作,並且可以分發給其它的APP,現在客

Android中APK直接通過JNI訪問驅動

1.新建檔案LED-JNI.c,內容如下:#include <jni.h>  /* /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ */ #include <stdio.h> #include <s

Android下如何通過JNI方法向上提供介面總結

1 什麼是JNI JNI是Java Native Interface的縮寫,即Java本地介面.從Java1.1開始,JNI標準成為Java平臺的一部分,它允許java程式碼和用其它語言編寫的程式碼進行互動.JNI是本地程式設計介面,它使得在Java虛擬機

Android App之間通過Intent互動

Android 最重要的功能之一是應用能夠基於它要執行的“操作”向另一個應用傳送使用者。 例如,如果您的應用有您要在地圖上顯示的公司地址,您無需在顯示地圖的應用中構建 Activity。 而是可以建立使用 Intent 檢視地址的請求。Android 系統之後啟

通過AjaxServlet獲取資料完成登入例項

Ajax的好處就是可以在頁面不進行重新整理的情況下,完成當前頁面某些收據的更新,速度快且使用者體驗好。 剛開始學習,就著幾行程式碼也要搞很長時間才能明白。 login.jsp--登入介面 <span style="white-space:pre"> </

android實現app通過jni呼叫C/C++方法

本文實現在android app中使用呼叫jni庫呼叫本地C/C++方法。 1.新建android工程 2.新建java上層方法 本例子在工程中新建 cn.landsem.jnistudy 包,在其中新建TestManager類用於呼叫本地C/C++方法,該類的程式碼如下:

Android CameraApp到framework到HAL的初始化過程

Android camera 從上到下可以分為四個部分: Application層、 framework層、 HAL(hardware abstract layer)層、 Kernel層 一般面向開發者的話主要集中在Application層和frame

Android 底層驅動開發步驟——linux核心層、HALJNI

1.Linux驅動實現2.Linux核心驅動測試3.Android HAL層實現4.Aidl實現5.Service java實現6.Service jni 實現7.註冊service和jni方法8.Android App呼叫測試1.linux驅動實現。2.Linux核心驅動測

android 系統驅動app 新增一個系統服務

注:整理自某個pdfandroid系統從下至上分層:kernel → HAL -->routime(虛擬機器和一些其他的庫)-->framework-->app 我們要新增的服務為 LedService在 app 中直接可以這樣使用LedManager le

怎樣C++代碼直接訪問android framework的WifiService

-a namespace cpi 編譯 pla desc argc 封裝 conf 說究竟,Java層的service就是就C++層的binder的封裝。所以從原理上來講通過C++代碼直接訪問android framework層的service是全然可能的,這篇

Android Studio2.2.3 通過JNI引用ffmpeg庫小結

android studio;ffmpeg;ndk;jni修改步驟:首先通過NDK14編譯出libffmpeg.so ,將include目錄取出通過AS建立基於jni的工程項目,將include目錄放到cpp下;創建jniLibs/armeabi目錄,將libffmpeg.so放到裏邊 3.配置CMak

Android開發實踐:JNI線程回調Java函數示例

lan 並且 進行 img 工程 stat 責任 3.5 jpg 原創作品,允許轉載,轉載時請務必以超鏈接形式標明文章 原始出處 、作者信息和本聲明。否則將追究法律責任。http://ticktick.blog.51cto.com/823160/1358558 JNI是Ja

monkey測試===如何獲取android app的Activity

.apk 推薦 eight nbsp mon 重命名 androi 最新 windows 本文轉自:http://www.cnblogs.com/nbkhic/p/3806951.html 有時候在appium的Desired Capabilities中需要指定被測app

jenkins 自動svn獲取源碼通過maven打包後發布到遠端tomcat

文件 webapp release manage 內容 ner name 協商 -a 手動生成web的war源碼文件。mvn archetype:generate -DgroupId=com.companyname.automobile -DartifactId=truck

javajni中傳遞GLSurfaceView的方法

bool 很多 code http codec android class ble extern 從java朝jni中傳遞各種數據,是在android開發中經常需要面對的事情。對於一些典型的數據類型,網上已經有很多文章介紹,這裏列出一些數據類型: 對於GLSurfa

Android APP和 Weex混合開發環境搭建到APP工程執行

一、簡言 目前Android可行的混合程式設計方案有Weex和ReactNative兩種方案,兩者基本類同,只是使用框架技術有點不一樣。從網上的資料可以查知到Weex相比ReactNative更容易上手,另外ReactNative在處理IOS端的長列表時容易出現記憶體洩漏。關於Weex和

我的新書《Android App開發入門到精通》終於出版啦

前言 經過了兩年多終於完成了這本書,2016年9月份開始寫的,到今天為止2年零2個月,本書的內容大部分是去年完成的,看過我去年總結的讀者可能知道,去年事情很多太忙了,導致本命年這本書沒有上架(有點小小的遺憾)。 工作之餘喜歡寫寫技術文章,對自己的技術做一個總結同時也讓後來者站在我的肩膀上,之前一直在CSD

ImportNew Android App 0到1

ImportNew是一個專注於 Java 相關技術分享的部落格,平常自己關注ImportNew比較多,曾經有想過自己開發一個客戶端出來,可以隨時隨地方便在移動裝置上閱讀,不過很多時候僅僅想想就過去了,但這次是玩真的,從零開始寫ImportNew客戶端,前後斷斷續續用業餘時間花了兩週多時間把D

Android framework自定義jni

framework新增自定jni    本文章適用於在原始碼環境下在framework新增自定的jni供上層Apk呼叫。 1 framework新增自定jni 新增自定義的jni檔案和Androidmk 新增系統編譯配置 新增自定義的jni檔案和Android.mk 首先在f