Android getevent拦截输入事件
来源:互联网 发布:陈少南 赤兔 知乎7p 编辑:程序博客网 时间:2024/06/06 00:59
上篇文章《Android AccessibilityService拦截事件及VR眼镜返回按键捕捉》我们介绍了如何用AccessibilityService来拦截事件。
本篇我们来介绍另一种拦截按键的方式,就是在shell的状态下,使用getevent命令对输入事件进行分析。必须要说明的是getevent命令使用场景有:
1.在PC端shell环境下,不必root
2.在APP端使用必须要root权限
package com.jason.btnmonitor;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initMonitor(); Button get = (Button) findViewById(R.id.get); Button start = (Button) findViewById(R.id.start); Button stop = (Button) findViewById(R.id.stop); get.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { getDevices(); } }); start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startMonitor(); } }); stop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { stopMonitor(); } }); } private void getDevices(){ BtnMonitorController.getInstance().getVRDevice(); } private void initMonitor(){ BtnMonitorController.getInstance().init(); } public void startMonitor(){ BtnMonitorController.getInstance().start(); } public void stopMonitor(){ BtnMonitorController.getInstance().stop(); } private void releaseMonitor(){ BtnMonitorController.getInstance().release(); } @Override protected void onDestroy() { super.onDestroy(); releaseMonitor(); }}
MainActivity的实现。
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.jason.btnmonitor.MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="get" android:id="@+id/get" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="start" android:id="@+id/start" android:layout_toRightOf="@+id/get" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="stop" android:layout_toRightOf="@+id/start" android:id="@+id/stop" /></RelativeLayout>
layout的实现。
package com.jason.btnmonitor;import android.os.Handler;import android.os.Message;import android.util.Log;import com.stericson.RootTools.RootTools;import com.stericson.RootTools.exceptions.RootDeniedException;import com.stericson.RootTools.execution.Command;import com.stericson.RootTools.execution.Shell;import java.io.IOException;import java.util.concurrent.TimeoutException;public class BtnMonitorController { private static final String COMMAND_GET_DEVICE_VR = "getevent"; private static final String COMMAND_GET_VR_EVENT = "getevent -l -t "; public static final int MSG_EVENT_INPUT = 9000; private String deviceName="/dev/input/event19"; //demo监听的是event19,这里可以改为你所要监听的event private static boolean isMonitorStart = false; private static boolean hasVR = false; private Shell shell; private Command command; private Handler handler; private static BtnMonitorController instance ; private BtnMonitorController(){ } public static BtnMonitorController getInstance(){ if (instance == null) { synchronized (BtnMonitorController.class){ if (instance == null) { instance = new BtnMonitorController() ; } } } return instance ; } public void init(){ try { shell = RootTools.getShell(true);//getevent命令必须要root } catch (IOException e) { e.printStackTrace(); LogUtil.e("shell init error"); } catch (TimeoutException e) { e.printStackTrace(); LogUtil.e("shell init error"); } catch (RootDeniedException e) { e.printStackTrace(); LogUtil.e("shell init error"); } handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case MSG_EVENT_INPUT: LogUtil.i(""+msg.obj); break; } super.handleMessage(msg); } }; }//getVRDevice会输出你的inputdevice的列表,选中你想要监听的设备,替换deviceName public void getVRDevice(){ LogUtil.i("BtnMonitor getVRDevice" ); if(isMonitorStart){ LogUtil.e("BtnMonitor is started already!"); return; } startCMD(COMMAND_GET_DEVICE_VR); } public void start(){ LogUtil.i("BtnMonitor start" ); if(isMonitorStart){ LogUtil.e("BtnMonitor is started already!"); return; } startCMD(COMMAND_GET_VR_EVENT+deviceName); } public void stop(){ LogUtil.i("BtnMonitor stop" ); if(command.isFinished()){ LogUtil.e("BtnMonitor is stopped already!"); return; } command.terminate("stop"); } public void release(){ LogUtil.i("BtnMonitor release" ); if(handler != null && handler.hasMessages(MSG_EVENT_INPUT)){ handler.removeMessages(MSG_EVENT_INPUT); handler = null; } if(isMonitorStart){ command.terminate("exit"); isMonitorStart = false; } try { if(shell != null) shell.close(); } catch (IOException e) { e.printStackTrace(); LogUtil.e("shell close IOException"); } } private void startCMD(String cmd){ isMonitorStart = true; command = new Command(0, 0, cmd) { @Override public void output(int id, String line) { LogUtil.e("MainActivity.java:output, id:" + id + ", output:" + line); Message m = new Message(); m.what = MSG_EVENT_INPUT; m.obj = line + "\n"; handler.sendMessage(m); } @Override public void commandCompleted(int arg0, int arg1) { // TODO Auto-generated method stub LogUtil.e("MainActivity.java:commandCompleted, arg0:" + arg0 + ", arg1:" + arg1); Message m = new Message(); m.what = MSG_EVENT_INPUT; m.obj = "commandCompleted\n" + "================================\n"; handler.sendMessage(m); isMonitorStart = false; } @Override public void commandOutput(int arg0, String arg1) { // TODO Auto-generated method stub LogUtil.e( "MainActivity.java:commandOutput, arg0:" + arg0 + ", arg1:" + arg1); Message m = new Message(); m.what = MSG_EVENT_INPUT; m.obj = "commandOutput, arg0:" + arg0 + ", arg1:" + arg1 + "\n"; handler.sendMessage(m); } @Override public void commandTerminated(int arg0, String arg1) { // TODO Auto-generated method stub LogUtil.e("MainActivity.java:commandTerminated, arg0:" + arg0 + ", arg1:" + arg1); Message m = new Message(); m.what = MSG_EVENT_INPUT; m.obj = "commandTerminated, reason:" + arg1 + "\n" + "================================\n"; handler.sendMessage(m); isMonitorStart = false; } }; try { shell.add(command); } catch (IOException e) { e.printStackTrace(); } }}
BtnMonitorController的实现,使用的是开源项目的RootTools。github工程地址
https://github.com/graygray/getevent.git
$ getevent /dev/input/event19 0004 0004 000900020001 0111 000000010000 0000 000000000004 0004 000900020001 0111 000000000000 0000 00000000监听到的VR设备(默认类型为鼠标)单击返回键的内容
$ getevent -l -t /dev/input/event19 [ 17437.061273] EV_MSC MSC_SCAN 00090002 [ 17437.061273] EV_KEY BTN_RIGHT DOWN [ 17437.061273] EV_SYN SYN_REPORT 00000000 [ 17437.156346] EV_MSC MSC_SCAN 00090002 [ 17437.156346] EV_KEY BTN_RIGHT UP [ 17437.156346] EV_SYN SYN_REPORT 00000000 [ 17444.748923] EV_MSC MSC_SCAN 00090002 [ 17444.748923] EV_KEY BTN_RIGHT DOWN [ 17444.748923] EV_SYN SYN_REPORT 00000000 [ 17446.244327] EV_MSC MSC_SCAN 00090002 [ 17446.244327] EV_KEY BTN_RIGHT UP [ 17446.244327] EV_SYN SYN_REPORT 00000000监听到的VR设备(默认类型为鼠标)返回键长按的内容,-t加上了时间戳用于判断是否是长按
针对收到的message内容可以判断BACK键的单击和长按。
0 0
- Android getevent拦截输入事件
- android跨进程事件注入(程序模拟用户输入,getevent与sendevent)
- android跨进程事件注入(程序模拟用户输入,getevent与sendevent)
- 使用getevent监听Android输入设备文件
- Android getevent命令分析Input事件
- Android input输入设备getevent 和sendevent用法
- Android 下收发input事件的工具 getevent 和 sendevent
- Android 下收发input事件的工具 getevent 和 sendevent
- Android 下收发input事件的工具 getevent 和 sendevent
- Android 下收发input事件的工具 getevent 和 sendevent
- Android输入事件从读取到分发五:事件分发前的拦截过程
- Android输入事件从读取到分发五:事件分发前的拦截过程
- android事件拦截
- Android 事件拦截
- Android 事件拦截分发
- Android 拦截onClick事件
- Android 事件拦截机制
- Android 事件拦截机制
- AsyncTask的原理及优缺点解析
- 【Python&NLP】nltk的几个基础函数
- 抽象
- java基础---->Java Collections Framework 概述
- 模糊逻辑:基础理论
- Android getevent拦截输入事件
- MultifunctionalActivity---------多功能Activity
- Sql 语句
- PopupWindow在Android7.0和7.1系统上显示位置不正确的问题解决
- 翁凯_面向对象程序设计_有秒计时的数字时钟
- Linux 基础命令
- 【错误总结】expected specifier-qualifier-list before sth
- 文件操作C语言 在txt文档中写入hello字符
- springmvc常用注解