
为了实现键盘的监控,从新开发一个输入法是不现实的,一般的 *** 作就是在系统的输入法机制中添加接口回调。我们知道,再应用程序中拿到按键的回调一般是监听onKeyDown的接口,如下所示:
public boolean onKeyDown(int keyCode, KeyEvent event)
开发者就可以根据回调方法中的参数, keyCode与KeyEvent来判断具体事件。但是,由于事件的回调机制在其的沙箱中运行,在其他应用中是无法拿到当前应用事件回调的。
那么我们就从上到下,具体的看看事件的传递机制。如下图所示,用户点击后,软键盘或物理按键的输入驱动就会产生一个中断,且向/dev/input/event*中写入一个相应的信号量。Android *** 作系统则会循环的读取其中的事件,再分发给WindowManagerServer。由WindowManagerServer根据事件的来源分发到各个不同的ViewGroup与View中,从而产生不同的OnClick、OnKeyDown和OnTouch等事件。
这个时候很自然的想到,黑客们希望做凳蠢键盘监控,一定会向Linux底层增加自定义的事件。这里我们使用悉神的是枣陆陪Linux中的getevent获得/dev/input/eventX设备汇报的事件,这个命令还会输出所有event设备的基本信息。包括触屏、按键、耳机插入等等。其基本用法如下:
Usage: getevent [-t] [-n] [-sswitchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-q] [-c count] [-r] [device]
-t: show time stamps
-n: don't print newlines
-s: print switch states for given bits
-S: print all switch states
-v: verbosity mask (errs=1, dev=2, name=4, info=8, vers=16, pos. events=32,props=64)
-d: show HID descriptor, if available
-p: show possible events (errs, dev, name, pos. events)
-i: show all device info and possible events
-l: label event types and names in plain text
-q: quiet (clear verbosity mask)
-c: print given number of events then exit
-r: print rate events are received
键入getevent后,我们能够看到设备中的一些列输入硬件驱动信息,同样下面会出现很多输入指令信号,通常情况下,这些信号量都在刷屏,如下图所示:
这些信号量的表示我们无法直接看懂,输入getevent –l加入Label我们能够看到一些添加的标签,如下所示:
其实这些Lable已经在其input.h头文件中定义好,其中type的定义如下:
/*
* Event types
*/
#define EV_SYN 0x00
#define EV_KEY 0x01
#define EV_REL 0x02
#define EV_ABS 0x03
#define EV_MSC 0x04
#define EV_SW 0x05
#define EV_LED 0x11
#define EV_SND 0x12
#define EV_REP 0x14
#define EV_FF 0x15
#define EV_PWR 0x16
#define EV_FF_STATUS 0x17
#define EV_MAX 0x1f
#define EV_CNT (EV_MAX+1)
一般来说,常用的是EV_KEY、EV_REL、EV_ABS、EV_SYN,分别对应键盘按键、相对坐标、绝对坐标、同步事件。EV_SYN则表示一组完整事件已经完成,需要处理,EV_SYN的code定义事件分发的类型。
重写activty的onkeydown在用户按下返回键的时候调用,所以我们可以通过重写onkeydown的方法实现,还枣渗毕有可能到了MainActivity前面还有其他acitivty存活这,我喊告们需要在凳芹onkeydown的时候把所有的activity都结束掉,为了实现这个我们先定义一个BaseActivity,在Oncreate和ondestroy生命周期里存储acitivty的引用用一个List集合存储存活的acitivity,我们把list作为application成员写一个MyApp类,作为程序启动的applicationpublic class MyApp extends Application{private List<Activity>activities = new ArrayList<Activity>() public List<Activity>getActivities(){ return activities }}BaseActivity代码如下class BaseActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState) ((MyApp)getApplication()).getActivities().add(this) } @Override protected void onDestroy() { super.onDestroy() ((MyApp)getApplication()).getActivities().remove(this) } }以后工程里的所有Activity都继承于BaseActivity即可最后是MainAcitivty的代码,在onkeydown方法里遍历list集合,调用每个activity的finish方法即可public class MyActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_two) } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { List<Activity>activities = ((MyApp)getApplication()).getActivities() for(Activity activity:activities){ activity.finish() } return super.onKeyDown(keyCode, event) }}欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)