最近在研究手写功能,对比了一些产品,发现三星的平板上的手写笔在靠近屏幕的时候,会有个圆形光标显示在界面上。这个光标是怎么显示的呢?带这个疑问,在网上搜了一番发现了一些结果。
1.在anroid2.3之前,由于android是针对手机的系统,所以没有绘制光标的模块,有人自己在系统层或者APP层做了一个光标。 例如:https://blog.csdn.net/LuYozone/article/details/18656475 这个篇文章。
2.在android4.0以后,android源码中增加了对光标的支持,但是需要做一些配置。另外我看到有些文章写了《如何实现悬浮图标》的,我想也可以用这个办法自己绘制一个图标吧。
下面是我对4.4系统中android源码中的光标如何显示的研究。
看网上文章说,只有kenrel层支持鼠标设备,比如插上USB鼠标,光标就会显示出来,但是我的设备不支持otg功能,无法插入USB设备。那我就想能否把我的触摸屏设备变成鼠标设备呢?
通过对比鼠标驱动和触摸屏驱动发现有门,在驱动中注册输入设备(input_dev)的时候会设置属性,
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | BIT(EV_REL);
input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
请给input_dev增加红色字体的内容。
在数据上报方法中,请添加如下类似字样:
input_report_key(dev, BTN_TOOL_PEN, 1);
input_report_abs(dev, ABS_X, x);
input_report_abs(dev, ABS_Y, y);
input_report_abs(dev, ABS_PRESSURE, coord->pen_pressure);
input_sync(dev);
input_report_key(dev, BTN_TOOL_PEN, 0);
input_sync(dev);
这样就是实现的鼠标数据的上报。但是还不够,编译代码烧写boot.img后发现还是不显示鼠标。
Andorid4.x Frameworks 中关于鼠标实现的代码在frameworks/base/services/input目录下的
PointerController.cpp,SpriteController.cpp
在InputReader.cpp中 CursorInputMapper类里有个configure方法,
switch (mParameters.mode) {
case Parameters::MODE_POINTER:
mSource = AINPUT_SOURCE_MOUSE;
mPointerController = getPolicy()->obtainPointerController(getDeviceId());
通过这个段代码发现,只有mParameters.mode 等于 Parameters::MODE_POINTER 的情况下,才会生成mPointerController这个实例,继续查找代码,在TouchInputMapper类的configureParameters方法中发现如下代码:
if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"), deviceTypeString)) {
if (deviceTypeString == "touchScreen") {
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
} else if (deviceTypeString == "touchPad") {
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
} else if (deviceTypeString == "touchNavigation") {
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_NAVIGATION;
} else if (deviceTypeString == "pointer") {
mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
...
看到了吧,mParameters.mode的值是在这个地方赋值的,那么这个touch.deviceType是哪里来的,原来是usr/idc目录下输入设备的 idc文件里设置的 “touch.deviceType = pointer”。
把这个设置好,再重新编译系统,鼠标就可以显示了,但是这个鼠标只有在我数据输入的情况下下会显示,如果鼠标不动或者触摸屏没有动作的话,就会自动隐藏。分析代码PointerController.cpp,有个fade函数。
void PointerController::fade(Transition transition) {
AutoMutex _l(mLock);
// Remove the inactivity timeout, since we are fading now.
removeInactivityTimeoutLocked();
// Start fading.
/*if (transition == TRANSITION_IMMEDIATE) {
mLocked.pointerFadeDirection = 0;
mLocked.pointerAlpha = 0.0f;
updatePointerLocked();
} else {
mLocked.pointerFadeDirection = -1;
startAnimationLocked();
}*/
}
这个函数是负责隐藏鼠标图标的,把这个if else判断完全注释掉,就可以实现鼠标图标一直显示了。
呵呵,写下来,做个记录。
友情推广