Android Native获取Event事件

有时候需要在C环境下获取按键事件,但是又不能更改Activity。
1、获取InputQueue并轮询获取按键信息
通过Window中的takeInputQueue接口注册回调

public class KeyEventObserver implements InputQueue.Callback {
    private static final String TAG = KeyEventObserver.class.getSimpleName();
    private long mInputQueuePtr = 0;
    private QueryKeyEventHandler mQueryKeyEventHandler;

    public KeyEventObserver(Activity activity) {
        mQueryKeyEventHandler = new QueryKeyEventHandler(Looper.getMainLooper());
        activity.getWindow().takeInputQueue(this);
    }

    @Override public void onInputQueueCreated(InputQueue queue) {
        mInputQueuePtr = getInputQueuePtr(queue);
        Log.d(TAG, "onInputQueueCreated " + mInputQueuePtr);
        mQueryKeyEventHandler.start();
    }

    @Override public void onInputQueueDestroyed(InputQueue queue) {
        mQueryKeyEventHandler.stop();
        mInputQueuePtr = 0;
        Log.d(TAG, "onInputQueueDestroyed " + mInputQueuePtr);
    }

    private long getInputQueuePtr(InputQueue queue) {
        try {
            Method getNativePtr = InputQueue.class.getMethod("getNativePtr");
            return (long) getNativePtr.invoke(queue);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return 0;
    }

    private class QueryKeyEventHandler extends Handler {
        private static final int MSG_START_QUERY = 10;

        public QueryKeyEventHandler(Looper looper) {
            super(looper);
        }

        @Override public void handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case MSG_START_QUERY:
                    start();
                    nativeQueryKeyEvent(mInputQueuePtr);
                    break;
            }
        }

        public void start() {
            removeMessages(MSG_START_QUERY);
            sendEmptyMessageDelayed(MSG_START_QUERY, 100);
        }

        public void stop() {
            removeMessages(MSG_START_QUERY);
        }
    }

    private native void nativeQueryKeyEvent(long inputQueuePtr);

    static {
        System.loadLibrary("svr_input_observer");
    }
}

2、在C实际获取按键等event信息

#include 
#include 
extern "C" {
AInputQueue *pInputQueue = NULL;
JNIEXPORT void JNICALL Java_com_demossnwt_demo_1surface_KeyEventObserver_nativeQueryKeyEvent(JNIEnv *env, jobject clazz, jlong ptr) {
    if (pInputQueue == NULL) {
        pInputQueue = reinterpret_cast(ptr);
    }
    if (AInputQueue_hasEvents(pInputQueue)) {
        AInputEvent *event;
        jint handle = AInputQueue_getEvent(pInputQueue, &event);
        jint type = AInputEvent_getType(event);
        jint keycode = -1;
        jint action = -1;
        if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) {
            keycode = AKeyEvent_getKeyCode(event);
            action = AKeyEvent_getAction(event);
        }
        AInputQueue_finishEvent(pInputQueue, event, handle); // 每次AInputQueue_getEvent之后必须调用AInputQueue_finishEvent
        LOGD("type=%d, keycode=%d, action=%d", type, keycode, action);
    }
}
}

你可能感兴趣的:(Android Native获取Event事件)