有时候需要在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 <jni.h>
#include <android/input.h>
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<AInputQueue *>(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);
}
}
}
网友评论