当前位置:  编程技术>移动开发
本页文章导读:
    ▪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;

        }

将原始数据点转化为显示屏对应的数据,一般触摸屏校正就在这里对数据点进行较正的。

    
[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
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">
该方法同样适用于控件

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
sqlserver iis7站长之家
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3