当前位置: 编程技术>移动开发
本页文章导读:
▪ADROID 2.1 架构解析 八 触摸屏 ADROID 2.1 架构解析 8 触摸屏
8 触摸屏8.1 分类输入事件 文件:frameworks/base/libs/ui/EventHub.cppint EventHub::open_device(const char *deviceName){ ... uint8_t key_bitmask[(KEY_MAX+1)/8]; memset(key_.........
▪ 话音朗读-语音识别-语音控制软件源码 语音朗读-语音识别-语音控制软件源码
完整的一个语音软件
所有文档,包括源代码
,麻雀虽小,五脏俱全。这是Ver 0.1 ,实现功能
主要是文本语音朗读 , 语音识别和控制,目前支持的系.........
▪ 兑现背景渐变的方法 实现背景渐变的方法
经过几天的摸索,终于找到不使用图片实现背景渐变的方法首先建立文件drawable/shape.xml<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/and.........
[1]ADROID 2.1 架构解析 八 触摸屏
来源: 互联网 发布时间: 2014-02-18
ADROID 2.1 架构解析 8 触摸屏
8 触摸屏
8.1 分类输入事件
文件:frameworks/base/libs/ui/EventHub.cpp
int EventHub::open_device(const char *deviceName)
{
...
uint8_t key_bitmask[(KEY_MAX+1)/8];
memset(key_bitmask, 0, sizeof(key_bitmask));
LOGV("Getting keys...");
if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) {
//LOGI("MAP\n");
//for (int i=0; i<((KEY_MAX+1)/8); i++) {
// LOGI("%d: 0x%02x\n", i, key_bitmask[i]);
//}
for (int i=0; i<((BTN_MISC+7)/8); i++) {
if (key_bitmask[i] != 0) {
device->classes |= CLASS_KEYBOARD;
break;
}
}
if ((device->classes & CLASS_KEYBOARD) != 0) {
device->keyBitmask = new uint8_t[sizeof(key_bitmask)];
if (device->keyBitmask != NULL) {
memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
} else {
delete device;
LOGE("out of memory allocating key bitmask");
return -1;
}
}
}
// See if this is a trackball.
if (test_bit(BTN_MOUSE, key_bitmask)) {
uint8_t rel_bitmask[(REL_MAX+1)/8];
memset(rel_bitmask, 0, sizeof(rel_bitmask));
LOGV("Getting relative controllers...");
if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0)
{
if (test_bit(REL_X, rel_bitmask) && test_bit(REL_Y, rel_bitmask)) {
device->classes |= CLASS_TRACKBALL;
}
}
}
uint8_t abs_bitmask[(ABS_MAX+1)/8];
memset(abs_bitmask, 0, sizeof(abs_bitmask));
LOGV("Getting absolute controllers...");
ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
// Is this a new modern multi-touch driver?
if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask)
&& test_bit(ABS_MT_POSITION_X, abs_bitmask)
&& test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
device->classes |= CLASS_TOUCHSCREEN | CLASS_TOUCHSCREEN_MT;
// Is this an old style single-touch driver?
} else if (test_bit(BTN_TOUCH, key_bitmask)
&& test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
device->classes |= CLASS_TOUCHSCREEN;
}
...
}
输入事件有:键盘、轨迹球、单点触摸、多点触摸
8.2 输入事件服务
文件:frameworks/base/services/java/com/android/server/KeyInputQueue.java
8.2.1 获取事件
Thread mThread = new Thread("InputDeviceReader") {
public void run() {
if (DEBUG) Log.v(TAG, "InputDeviceReader.run()");
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
RawInputEvent ev = new RawInputEvent();
while (true) {
try {
...
// block, doesn't release the monitor
readEvent(ev);
...
调用readEvent,将输入事件读取到ev类,即RawInputEvent的变量里,readEvent对应jni的android_server_KeyInputQueue_readEvent
8.2.2 获取触摸点数据
// Process position events from multitouch protocol.
else if (ev.type == RawInputEvent.EV_ABS &&
(classes&RawInputEvent.CLASS_TOUCHSCREEN_MT) != 0) {
if (ev.scancode == RawInputEvent.ABS_MT_TOUCH_MAJOR) {
di.mAbs.changed = true;
di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
+ MotionEvent.SAMPLE_PRESSURE] = ev.value;
} else if (ev.scancode == RawInputEvent.ABS_MT_POSITION_X) {
di.mAbs.changed = true;
di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
+ MotionEvent.SAMPLE_X] = ev.value;
if (DEBUG_POINTERS) Log.v(TAG, "MT @"
+ di.mAbs.mAddingPointerOffset
+ " X:" + ev.value);
} else if (ev.scancode == RawInputEvent.ABS_MT_POSITION_Y) {
di.mAbs.changed = true;
di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
+ MotionEvent.SAMPLE_Y] = ev.value;
if (DEBUG_POINTERS) Log.v(TAG, "MT @"
+ di.mAbs.mAddingPointerOffset
+ " Y:" + ev.value);
} else if (ev.scancode == RawInputEvent.ABS_MT_WIDTH_MAJOR) {
di.mAbs.changed = true;
di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
+ MotionEvent.SAMPLE_SIZE] = ev.value;
}
// Process position events from single touch protocol.
} else if (ev.type == RawInputEvent.EV_ABS &&
(classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) {
if (ev.scancode == RawInputEvent.ABS_X) {
di.mAbs.changed = true;
di.curTouchVals[MotionEvent.SAMPLE_X] = ev.value;
} else if (ev.scancode == RawInputEvent.ABS_Y) {
di.mAbs.changed = true;
di.curTouchVals[MotionEvent.SAMPLE_Y] = ev.value;
} else if (ev.scancode == RawInputEvent.ABS_PRESSURE) {
di.mAbs.changed = true;
di.curTouchVals[MotionEvent.SAMPLE_PRESSURE] = ev.value;
di.curTouchVals[MotionEvent.NUM_SAMPLE_DATA
+ MotionEvent.SAMPLE_PRESSURE] = ev.value;
} else if (ev.scancode == RawInputEvent.ABS_TOOL_WIDTH) {
di.mAbs.changed = true;
di.curTouchVals[MotionEvent.SAMPLE_SIZE] = ev.value;
di.curTouchVals[MotionEvent.NUM_SAMPLE_DATA
+ MotionEvent.SAMPLE_SIZE] = ev.value;
}
}
多点触摸和单点触摸的处理:保存多点或单点触摸的数据。
8.2.3 获取转换后触点数据
if (doMotion) {
// XXX Need to be able to generate
// multiple events here, for example
// if two fingers change up/down state
// at the same time.
do {
me = ms.generateAbsMotion(di, curTime,
curTimeNano, mDisplay,
mOrientation, mGlobalMetaState);
if (DEBUG_POINTERS) Log.v(TAG, "Absolute: x="
+ di.mAbs.mNextData[MotionEvent.SAMPLE_X]
+ " y="
+ di.mAbs.mNextData[MotionEvent.SAMPLE_Y]
+ " ev=" + me);
if (me != null) {
if (WindowManagerPolicy.WATCH_POINTER) {
Log.i(TAG, "Enqueueing: " + me);
}
addLocked(di, curTimeNano, ev.flags,
RawInputEvent.CLASS_TOUCHSCREEN, me);
}
} while (ms.hasMore());
}
获取转换后触摸点数据并加入到输入事件队列。
8.3 读取触摸点数据的流程
文件:frameworks/base/services/java/com/android/server/KeyInputQueue.java
readEvent(ev);
di.curTouchVals[MotionEvent.SAMPLE_X] = ev.value;
文件:frameworks/base/services/jni/com_android_server_KeyInputQueue.cpp
{ "readEvent", "(Landroid/view/RawInputEvent;)Z",
(void*) android_server_KeyInputQueue_readEvent },
..
static jboolean
android_server_KeyInputQueue_readEvent(JNIEnv* env, jobject clazz,
jobject event)
{
...
bool res = hub->getEvent(&deviceId, &type, &scancode, &keycode,
&flags, &value, &when);
...
}
文件:frameworks/base/libs/ui/EventHub.cpp
bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType,
int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
int32_t* outValue, nsecs_t* outWhen)
{
...
res = read(mFDs[i].fd, &iev, sizeof(iev));
...
*outValue = iev.value;
..
}
8.4 触点数据转换
文件:frameworks/base/services/java/com/android/server/InutDevice.java
MotionEvent generateAbsMotion(InputDevice device, long curTime,
long curTimeNano, Display display, int orientation,
int metaState) {
if (mSkipLastPointers) {
mSkipLastPointers = false;
mLastNumPointers = 0;
}
if (mNextNumPointers <= 0 && mLastNumPointers <= 0) {
return null;
}
final int lastNumPointers = mLastNumPointers;
final int nextNumPointers = mNextNumPointers;
if (mNextNumPointers > MAX_POINTERS) {
Log.w("InputDevice", "Number of pointers " + mNextNumPointers
+ " exceeded maximum of " + MAX_POINTERS);
mNextNumPointers = MAX_POINTERS;
}
int upOrDownPointer = updatePointerIdentifiers();
final float[] reportData = mReportData;
final int[] rawData;
if (KeyInputQueue.BAD_TOUCH_HACK) {
rawData = generateAveragedData(upOrDownPointer, lastNumPointers,
nextNumPointers);
} else {
rawData = mLastData;
}
final int numPointers = mLastNumPointers;
if (DEBUG_POINTERS) Log.v("InputDevice", "Processing "
+ numPointers + " pointers (going from " + lastNumPointers
+ " to " + nextNumPointers + ")");
for (int i=0; i<numPointers; i++) {
final int pos = i * MotionEvent.NUM_SAMPLE_DATA;
reportData[pos + MotionEvent.SAMPLE_X] = rawData[pos + MotionEvent.SAMPLE_X];
reportData[pos + MotionEvent.SAMPLE_Y] = rawData[pos + MotionEvent.SAMPLE_Y];
reportData[pos + MotionEvent.SAMPLE_PRESSURE] = rawData[pos + MotionEvent.SAMPLE_PRESSURE];
reportData[pos + MotionEvent.SAMPLE_SIZE] = rawData[pos + MotionEvent.SAMPLE_SIZE];
}
int action;
int edgeFlags = 0;
if (nextNumPointers != lastNumPointers) {
if (nextNumPointers > lastNumPointers) {
if (lastNumPointers == 0) {
action = MotionEvent.ACTION_DOWN;
mDownTime = curTime;
} else {
action = MotionEvent.ACTION_POINTER_DOWN
| (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
}
} else {
if (numPointers == 1) {
action = MotionEvent.ACTION_UP;
} else {
action = MotionEvent.ACTION_POINTER_UP
| (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
}
}
currentMove = null;
} else {
action = MotionEvent.ACTION_MOVE;
}
final int dispW = display.getWidth()-1;
final int dispH = display.getHeight()-1;
int w = dispW;
int h = dispH;
if (orientation == Surface.ROTATION_90
|| orientation == Surface.ROTATION_270) {
int tmp = w;
w = h;
h = tmp;
}
final AbsoluteInfo absX = device.absX;
final AbsoluteInfo absY = device.absY;
final AbsoluteInfo absPressure = device.absPressure;
final AbsoluteInfo absSize = device.absSize;
for (int i=0; i<numPointers; i++) {
final int j = i * MotionEvent.NUM_SAMPLE_DATA;
if (absX != null) {
reportData[j + MotionEvent.SAMPLE_X] =
((reportData[j + MotionEvent.SAMPLE_X]-absX.minValue)
/ absX.range) * w;
}
if (absY != null) {
reportData[j + MotionEvent.SAMPLE_Y] =
((reportData[j + MotionEvent.SAMPLE_Y]-absY.minValue)
/ absY.range) * h;
}
if (absPressure != null) {
reportData[j + MotionEvent.SAMPLE_PRESSURE] =
((reportData[j + MotionEvent.SAMPLE_PRESSURE]-absPressure.minValue)
/ (float)absPressure.range);
}
if (absSize != null) {
reportData[j + MotionEvent.SAMPLE_SIZE] =
((reportData[j + MotionEvent.SAMPLE_SIZE]-absSize.minValue)
/ (float)absSize.range);
}
switch (orientation) {
case Surface.ROTATION_90: {
final float temp = reportData[j + MotionEvent.SAMPLE_X];
reportData[j + MotionEvent.SAMPLE_X] = reportData[j + MotionEvent.SAMPLE_Y];
reportData[j + MotionEvent.SAMPLE_Y] = w-temp;
break;
}
case Surface.ROTATION_180: {
reportData[j + MotionEvent.SAMPLE_X] = w-reportData[j + MotionEvent.SAMPLE_X];
reportData[j + MotionEvent.SAMPLE_Y] = h-reportData[j + MotionEvent.SAMPLE_Y];
break;
}
case Surface.ROTATION_270: {
final float temp = reportData[j + MotionEvent.SAMPLE_X];
reportData[j + MotionEvent.SAMPLE_X] = h-reportData[j + MotionEvent.SAMPLE_Y];
reportData[j + MotionEvent.SAMPLE_Y] = temp;
break;
}
}
}
// We only consider the first pointer when computing the edge
// flags, since they are global to the event.
if (action == MotionEvent.ACTION_DOWN) {
if (reportData[MotionEvent.SAMPLE_X] <= 0) {
edgeFlags |= MotionEvent.EDGE_LEFT;
} else if (reportData[MotionEvent.SAMPLE_X] >= dispW) {
edgeFlags |= MotionEvent.EDGE_RIGHT;
}
if (reportData[MotionEvent.SAMPLE_Y] <= 0) {
edgeFlags |= MotionEvent.EDGE_TOP;
} else if (reportData[MotionEvent.SAMPLE_Y] >= dispH) {
edgeFlags |= MotionEvent.EDGE_BOTTOM;
}
}
if (currentMove != null) {
if (false) Log.i("InputDevice", "Adding batch x="
+ reportData[MotionEvent.SAMPLE_X]
+ " y=" + reportData[MotionEvent.SAMPLE_Y]
+ " to " + currentMove);
currentMove.addBatch(curTime, reportData, metaState);
if (WindowManagerPolicy.WATCH_POINTER) {
Log.i("KeyInputQueue", "Updating: " + currentMove);
}
return null;
}
MotionEvent me = MotionEvent.obtainNano(mDownTime, curTime,
curTimeNano, action, numPointers, mPointerIds, reportData,
metaState, xPrecision, yPrecision, device.id, edgeFlags);
if (action == MotionEvent.ACTION_MOVE) {
currentMove = me;
}
if (nextNumPointers < lastNumPointers) {
removeOldPointer(upOrDownPointer);
}
return me;
}
将原始数据点转化为显示屏对应的数据,一般触摸屏校正就在这里对数据点进行较正的。
8 触摸屏
8.1 分类输入事件
文件:frameworks/base/libs/ui/EventHub.cpp
int EventHub::open_device(const char *deviceName)
{
...
uint8_t key_bitmask[(KEY_MAX+1)/8];
memset(key_bitmask, 0, sizeof(key_bitmask));
LOGV("Getting keys...");
if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) {
//LOGI("MAP\n");
//for (int i=0; i<((KEY_MAX+1)/8); i++) {
// LOGI("%d: 0x%02x\n", i, key_bitmask[i]);
//}
for (int i=0; i<((BTN_MISC+7)/8); i++) {
if (key_bitmask[i] != 0) {
device->classes |= CLASS_KEYBOARD;
break;
}
}
if ((device->classes & CLASS_KEYBOARD) != 0) {
device->keyBitmask = new uint8_t[sizeof(key_bitmask)];
if (device->keyBitmask != NULL) {
memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
} else {
delete device;
LOGE("out of memory allocating key bitmask");
return -1;
}
}
}
// See if this is a trackball.
if (test_bit(BTN_MOUSE, key_bitmask)) {
uint8_t rel_bitmask[(REL_MAX+1)/8];
memset(rel_bitmask, 0, sizeof(rel_bitmask));
LOGV("Getting relative controllers...");
if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0)
{
if (test_bit(REL_X, rel_bitmask) && test_bit(REL_Y, rel_bitmask)) {
device->classes |= CLASS_TRACKBALL;
}
}
}
uint8_t abs_bitmask[(ABS_MAX+1)/8];
memset(abs_bitmask, 0, sizeof(abs_bitmask));
LOGV("Getting absolute controllers...");
ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
// Is this a new modern multi-touch driver?
if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask)
&& test_bit(ABS_MT_POSITION_X, abs_bitmask)
&& test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
device->classes |= CLASS_TOUCHSCREEN | CLASS_TOUCHSCREEN_MT;
// Is this an old style single-touch driver?
} else if (test_bit(BTN_TOUCH, key_bitmask)
&& test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
device->classes |= CLASS_TOUCHSCREEN;
}
...
}
输入事件有:键盘、轨迹球、单点触摸、多点触摸
8.2 输入事件服务
文件:frameworks/base/services/java/com/android/server/KeyInputQueue.java
8.2.1 获取事件
Thread mThread = new Thread("InputDeviceReader") {
public void run() {
if (DEBUG) Log.v(TAG, "InputDeviceReader.run()");
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
RawInputEvent ev = new RawInputEvent();
while (true) {
try {
...
// block, doesn't release the monitor
readEvent(ev);
...
调用readEvent,将输入事件读取到ev类,即RawInputEvent的变量里,readEvent对应jni的android_server_KeyInputQueue_readEvent
8.2.2 获取触摸点数据
// Process position events from multitouch protocol.
else if (ev.type == RawInputEvent.EV_ABS &&
(classes&RawInputEvent.CLASS_TOUCHSCREEN_MT) != 0) {
if (ev.scancode == RawInputEvent.ABS_MT_TOUCH_MAJOR) {
di.mAbs.changed = true;
di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
+ MotionEvent.SAMPLE_PRESSURE] = ev.value;
} else if (ev.scancode == RawInputEvent.ABS_MT_POSITION_X) {
di.mAbs.changed = true;
di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
+ MotionEvent.SAMPLE_X] = ev.value;
if (DEBUG_POINTERS) Log.v(TAG, "MT @"
+ di.mAbs.mAddingPointerOffset
+ " X:" + ev.value);
} else if (ev.scancode == RawInputEvent.ABS_MT_POSITION_Y) {
di.mAbs.changed = true;
di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
+ MotionEvent.SAMPLE_Y] = ev.value;
if (DEBUG_POINTERS) Log.v(TAG, "MT @"
+ di.mAbs.mAddingPointerOffset
+ " Y:" + ev.value);
} else if (ev.scancode == RawInputEvent.ABS_MT_WIDTH_MAJOR) {
di.mAbs.changed = true;
di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
+ MotionEvent.SAMPLE_SIZE] = ev.value;
}
// Process position events from single touch protocol.
} else if (ev.type == RawInputEvent.EV_ABS &&
(classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) {
if (ev.scancode == RawInputEvent.ABS_X) {
di.mAbs.changed = true;
di.curTouchVals[MotionEvent.SAMPLE_X] = ev.value;
} else if (ev.scancode == RawInputEvent.ABS_Y) {
di.mAbs.changed = true;
di.curTouchVals[MotionEvent.SAMPLE_Y] = ev.value;
} else if (ev.scancode == RawInputEvent.ABS_PRESSURE) {
di.mAbs.changed = true;
di.curTouchVals[MotionEvent.SAMPLE_PRESSURE] = ev.value;
di.curTouchVals[MotionEvent.NUM_SAMPLE_DATA
+ MotionEvent.SAMPLE_PRESSURE] = ev.value;
} else if (ev.scancode == RawInputEvent.ABS_TOOL_WIDTH) {
di.mAbs.changed = true;
di.curTouchVals[MotionEvent.SAMPLE_SIZE] = ev.value;
di.curTouchVals[MotionEvent.NUM_SAMPLE_DATA
+ MotionEvent.SAMPLE_SIZE] = ev.value;
}
}
多点触摸和单点触摸的处理:保存多点或单点触摸的数据。
8.2.3 获取转换后触点数据
if (doMotion) {
// XXX Need to be able to generate
// multiple events here, for example
// if two fingers change up/down state
// at the same time.
do {
me = ms.generateAbsMotion(di, curTime,
curTimeNano, mDisplay,
mOrientation, mGlobalMetaState);
if (DEBUG_POINTERS) Log.v(TAG, "Absolute: x="
+ di.mAbs.mNextData[MotionEvent.SAMPLE_X]
+ " y="
+ di.mAbs.mNextData[MotionEvent.SAMPLE_Y]
+ " ev=" + me);
if (me != null) {
if (WindowManagerPolicy.WATCH_POINTER) {
Log.i(TAG, "Enqueueing: " + me);
}
addLocked(di, curTimeNano, ev.flags,
RawInputEvent.CLASS_TOUCHSCREEN, me);
}
} while (ms.hasMore());
}
获取转换后触摸点数据并加入到输入事件队列。
8.3 读取触摸点数据的流程
文件:frameworks/base/services/java/com/android/server/KeyInputQueue.java
readEvent(ev);
di.curTouchVals[MotionEvent.SAMPLE_X] = ev.value;
文件:frameworks/base/services/jni/com_android_server_KeyInputQueue.cpp
{ "readEvent", "(Landroid/view/RawInputEvent;)Z",
(void*) android_server_KeyInputQueue_readEvent },
..
static jboolean
android_server_KeyInputQueue_readEvent(JNIEnv* env, jobject clazz,
jobject event)
{
...
bool res = hub->getEvent(&deviceId, &type, &scancode, &keycode,
&flags, &value, &when);
...
}
文件:frameworks/base/libs/ui/EventHub.cpp
bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType,
int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
int32_t* outValue, nsecs_t* outWhen)
{
...
res = read(mFDs[i].fd, &iev, sizeof(iev));
...
*outValue = iev.value;
..
}
8.4 触点数据转换
文件:frameworks/base/services/java/com/android/server/InutDevice.java
MotionEvent generateAbsMotion(InputDevice device, long curTime,
long curTimeNano, Display display, int orientation,
int metaState) {
if (mSkipLastPointers) {
mSkipLastPointers = false;
mLastNumPointers = 0;
}
if (mNextNumPointers <= 0 && mLastNumPointers <= 0) {
return null;
}
final int lastNumPointers = mLastNumPointers;
final int nextNumPointers = mNextNumPointers;
if (mNextNumPointers > MAX_POINTERS) {
Log.w("InputDevice", "Number of pointers " + mNextNumPointers
+ " exceeded maximum of " + MAX_POINTERS);
mNextNumPointers = MAX_POINTERS;
}
int upOrDownPointer = updatePointerIdentifiers();
final float[] reportData = mReportData;
final int[] rawData;
if (KeyInputQueue.BAD_TOUCH_HACK) {
rawData = generateAveragedData(upOrDownPointer, lastNumPointers,
nextNumPointers);
} else {
rawData = mLastData;
}
final int numPointers = mLastNumPointers;
if (DEBUG_POINTERS) Log.v("InputDevice", "Processing "
+ numPointers + " pointers (going from " + lastNumPointers
+ " to " + nextNumPointers + ")");
for (int i=0; i<numPointers; i++) {
final int pos = i * MotionEvent.NUM_SAMPLE_DATA;
reportData[pos + MotionEvent.SAMPLE_X] = rawData[pos + MotionEvent.SAMPLE_X];
reportData[pos + MotionEvent.SAMPLE_Y] = rawData[pos + MotionEvent.SAMPLE_Y];
reportData[pos + MotionEvent.SAMPLE_PRESSURE] = rawData[pos + MotionEvent.SAMPLE_PRESSURE];
reportData[pos + MotionEvent.SAMPLE_SIZE] = rawData[pos + MotionEvent.SAMPLE_SIZE];
}
int action;
int edgeFlags = 0;
if (nextNumPointers != lastNumPointers) {
if (nextNumPointers > lastNumPointers) {
if (lastNumPointers == 0) {
action = MotionEvent.ACTION_DOWN;
mDownTime = curTime;
} else {
action = MotionEvent.ACTION_POINTER_DOWN
| (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
}
} else {
if (numPointers == 1) {
action = MotionEvent.ACTION_UP;
} else {
action = MotionEvent.ACTION_POINTER_UP
| (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
}
}
currentMove = null;
} else {
action = MotionEvent.ACTION_MOVE;
}
final int dispW = display.getWidth()-1;
final int dispH = display.getHeight()-1;
int w = dispW;
int h = dispH;
if (orientation == Surface.ROTATION_90
|| orientation == Surface.ROTATION_270) {
int tmp = w;
w = h;
h = tmp;
}
final AbsoluteInfo absX = device.absX;
final AbsoluteInfo absY = device.absY;
final AbsoluteInfo absPressure = device.absPressure;
final AbsoluteInfo absSize = device.absSize;
for (int i=0; i<numPointers; i++) {
final int j = i * MotionEvent.NUM_SAMPLE_DATA;
if (absX != null) {
reportData[j + MotionEvent.SAMPLE_X] =
((reportData[j + MotionEvent.SAMPLE_X]-absX.minValue)
/ absX.range) * w;
}
if (absY != null) {
reportData[j + MotionEvent.SAMPLE_Y] =
((reportData[j + MotionEvent.SAMPLE_Y]-absY.minValue)
/ absY.range) * h;
}
if (absPressure != null) {
reportData[j + MotionEvent.SAMPLE_PRESSURE] =
((reportData[j + MotionEvent.SAMPLE_PRESSURE]-absPressure.minValue)
/ (float)absPressure.range);
}
if (absSize != null) {
reportData[j + MotionEvent.SAMPLE_SIZE] =
((reportData[j + MotionEvent.SAMPLE_SIZE]-absSize.minValue)
/ (float)absSize.range);
}
switch (orientation) {
case Surface.ROTATION_90: {
final float temp = reportData[j + MotionEvent.SAMPLE_X];
reportData[j + MotionEvent.SAMPLE_X] = reportData[j + MotionEvent.SAMPLE_Y];
reportData[j + MotionEvent.SAMPLE_Y] = w-temp;
break;
}
case Surface.ROTATION_180: {
reportData[j + MotionEvent.SAMPLE_X] = w-reportData[j + MotionEvent.SAMPLE_X];
reportData[j + MotionEvent.SAMPLE_Y] = h-reportData[j + MotionEvent.SAMPLE_Y];
break;
}
case Surface.ROTATION_270: {
final float temp = reportData[j + MotionEvent.SAMPLE_X];
reportData[j + MotionEvent.SAMPLE_X] = h-reportData[j + MotionEvent.SAMPLE_Y];
reportData[j + MotionEvent.SAMPLE_Y] = temp;
break;
}
}
}
// We only consider the first pointer when computing the edge
// flags, since they are global to the event.
if (action == MotionEvent.ACTION_DOWN) {
if (reportData[MotionEvent.SAMPLE_X] <= 0) {
edgeFlags |= MotionEvent.EDGE_LEFT;
} else if (reportData[MotionEvent.SAMPLE_X] >= dispW) {
edgeFlags |= MotionEvent.EDGE_RIGHT;
}
if (reportData[MotionEvent.SAMPLE_Y] <= 0) {
edgeFlags |= MotionEvent.EDGE_TOP;
} else if (reportData[MotionEvent.SAMPLE_Y] >= dispH) {
edgeFlags |= MotionEvent.EDGE_BOTTOM;
}
}
if (currentMove != null) {
if (false) Log.i("InputDevice", "Adding batch x="
+ reportData[MotionEvent.SAMPLE_X]
+ " y=" + reportData[MotionEvent.SAMPLE_Y]
+ " to " + currentMove);
currentMove.addBatch(curTime, reportData, metaState);
if (WindowManagerPolicy.WATCH_POINTER) {
Log.i("KeyInputQueue", "Updating: " + currentMove);
}
return null;
}
MotionEvent me = MotionEvent.obtainNano(mDownTime, curTime,
curTimeNano, action, numPointers, mPointerIds, reportData,
metaState, xPrecision, yPrecision, device.id, edgeFlags);
if (action == MotionEvent.ACTION_MOVE) {
currentMove = me;
}
if (nextNumPointers < lastNumPointers) {
removeOldPointer(upOrDownPointer);
}
return me;
}
将原始数据点转化为显示屏对应的数据,一般触摸屏校正就在这里对数据点进行较正的。
[2] 话音朗读-语音识别-语音控制软件源码
来源: 互联网 发布时间: 2014-02-18
语音朗读-语音识别-语音控制软件源码
完整的一个语音软件
所有文档,包括源代码
,麻雀虽小,五脏俱全。这是Ver 0.1 ,实现功能
主要是文本语音朗读 , 语音识别和控制,目前支持的系统
命令有打电话拨号,查找联系人
, 启动任意应用
程序
,访问网址,搜索引擎查询,自定义
命令等 。
技术不是很难,主要是练手,但重要的是完整的Android开发
生命周期规范以及架构的设计上,可以给大家做一个借鉴 。
下载
(15.2 KB)
截图
截图
2010-11-20 09:05
android
talk_2010_11_17.rar
(2.54 MB)
androidtalk_source(源代码
)
下载次数: 957
下载次数: 957
2010-11-20 09:03
下载消耗 e币 1 元
上传一个文件
包 , 目录结构解释如下:
Requirement - 需求相关文档
Design - 设计
Planning&Log - 计划,日志,会议
Test - 集成测试,系统测试 , 测试报告 , Buglist
Study - 学习
资料
,Demo等
Deployment - 发布,部署
src - 源代码及单元测试
这个项目
的解释图如下,有不明白的可以和我交流
:
下载
(34.03 KB)
2010-11-20 09:32
部分类图:
下载
(55.12 KB)
2010-11-20 12:32
下载
(68.09 KB)
2010-11-20 12:33
项目还有如下优点及借鉴学习之处:
1,软件开发生命周期按照WRUP(我基于RUP自己设计的一套模式)
2,架构设计及模式应用上
3,语音引擎的封装(jar包大家直接就可以打来用,开发语音程序几行代码搞定)
4,项目管理上全程使用UML ,从需求到设计,文档详细而又全面,但不冗余 。
也有如下缺点:
1,因为是两周的时间
做的东西,没有QC,不能达到商用要求,虽然我们跑没有问题。
2,这个版本不支持中文
语音,我们计划下个版本实现,实现周期还要2周,下个版本还会引入跨进程Handle捕获
1 楼
zhaoxuan132
2012-05-29
androidtalk_2010_11_17.rar
[3] 兑现背景渐变的方法
来源: 互联网 发布时间: 2014-02-18
实现背景渐变的方法
经过几天的摸索,终于找到不使用图片实现背景渐变的方法
首先建立文件drawable/shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient android:startColor="#FFFFFFFF" android:endColor="#FFFF0000"
android:angle="270"/>
</shape>
在该文件中设置渐变的开始颜色(startColor)、结束颜色(endColor)和角度(angle)
接着创建一个主题values/style.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="NewTheme" parent="android:Theme">
<item name="android:background">@drawable/shape</item>
</style>
</resources>
然后在AndroidManifest.xml文件中的application或activity中引入该主题,如:
<activity android:name=".ShapeDemo" android:theme="@style/NewTheme">
该方法同样适用于控件
经过几天的摸索,终于找到不使用图片实现背景渐变的方法
首先建立文件drawable/shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient android:startColor="#FFFFFFFF" android:endColor="#FFFF0000"
android:angle="270"/>
</shape>
在该文件中设置渐变的开始颜色(startColor)、结束颜色(endColor)和角度(angle)
接着创建一个主题values/style.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="NewTheme" parent="android:Theme">
<item name="android:background">@drawable/shape</item>
</style>
</resources>
然后在AndroidManifest.xml文件中的application或activity中引入该主题,如:
<activity android:name=".ShapeDemo" android:theme="@style/NewTheme">
该方法同样适用于控件
最新技术文章: