视力测试Demo

来源:互联网 发布:手机应用商店网络异常 编辑:程序博客网 时间:2024/04/27 18:42

项目地址:https://github.com/zabio/TestEyes


package com.hy.testasr;import android.content.DialogInterface;import android.content.Intent;import android.content.SharedPreferences;import android.os.Bundle;import android.support.v7.app.AlertDialog;import android.support.v7.app.AppCompatActivity;import android.text.TextUtils;import android.util.Log;import android.view.View;import android.view.animation.Animation;import android.view.animation.AnimationSet;import android.view.animation.RotateAnimation;import android.view.animation.ScaleAnimation;import android.widget.ImageView;import android.widget.Toast;import com.iflytek.cloud.ErrorCode;import com.iflytek.cloud.GrammarListener;import com.iflytek.cloud.InitListener;import com.iflytek.cloud.RecognizerListener;import com.iflytek.cloud.RecognizerResult;import com.iflytek.cloud.SpeechConstant;import com.iflytek.cloud.SpeechError;import com.iflytek.cloud.SpeechRecognizer;import java.util.ArrayList;import java.util.Random;public class TestEyeActivity extends AppCompatActivity implements View.OnClickListener {    static final String TAG = TestEyeActivity.class.getSimpleName();    static final int DIRECT_UNCLEAR = -1;    static final int DIRECT_UP = 0;    static final int DIRECT_RIGHT = 1;    static final int DIRECT_DOWN = 2;    static final int DIRECT_LEFT = 3;    static final String TEXT_UP = "上";    static final String TEXT_RIGHT = "右";    static final String TEXT_DOWN = "下";    static final String TEXT_LEFT = "左";    static final String TEXT_UNCLEAR = "看不清";    static final String TEXT_NOT_SEE = "看不见";    static final String TEXT_NOT_VISIBLE = "不清楚";    private static final String GRAMMAR_TYPE_ABNF = "abnf";    private ImageView mImgEye;    private int mIndex = 0;    private float mLastToDegrees = 0;    private int mDirect = 1;    private int mRet = 0;    private ArrayList<Item> mUserList = new ArrayList<>();    private Toast mToast;    private String mEngineType = SpeechConstant.TYPE_CLOUD;    // 语音识别对象    private SpeechRecognizer mAsr;    // 缓存    private SharedPreferences mSharedPreferences;    private static final String KEY_GRAMMAR_ABNF_ID = "grammar_abnf_id";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_test_eye);        init();        initAsr();    }    /**     * 初始化view     */    private void init() {        mImgEye = (ImageView) findViewById(R.id.img_e);        findViewById(R.id.rl_top).setOnClickListener(this);        findViewById(R.id.rl_bottom).setOnClickListener(this);        findViewById(R.id.rl_left).setOnClickListener(this);        findViewById(R.id.rl_right).setOnClickListener(this);    }    /**     * 初始化讯飞在线语音识别     */    private void initAsr() {        mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);        mSharedPreferences = getSharedPreferences(getPackageName(), MODE_PRIVATE);        // 初始化识别对象        mAsr = SpeechRecognizer.createRecognizer(this, mInitListener);        buildAsr();    }    /**     * 构建语法文件     */    private void buildAsr() {        showTip("上传预设关键词/语法文件");        // 本地-构建语法文件,生成语法id        String mCloudGrammar =                "#ABNF 1.0 UTF-8;"                        + "languagezh-CN;"                        + "mode voice;"                        + "root $main;"                        + "$main = $place1$place2| 看不见 | 看不清 | 不清楚"                        + "$place1 = 上 | 下 | 左 | 右 ;"                        + "$place2 = 面 | 边 | 方;";        //指定引擎类型        mAsr.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);        mAsr.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");        mRet = mAsr.buildGrammar(GRAMMAR_TYPE_ABNF, mCloudGrammar, mCloudGrammarListener);        if (mRet != ErrorCode.SUCCESS) {            showTip("语法构建失败,错误码:" + mRet);        } else {            startListening();        }    }    //开始监听    private void startListening() {        mRet = mAsr.startListening(mRecognizerListener);        if (mRet != ErrorCode.SUCCESS) {            if (mRet == ErrorCode.ERROR_COMPONENT_NOT_INSTALLED) {                //未安装则跳转到提示安装页面            } else {                showTip("识别失败,错误码: " + mRet);            }        }    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.rl_top:                up();                break;            case R.id.rl_bottom:                down();                break;            case R.id.rl_left:                left();                break;            case R.id.rl_right:                right();                break;        }    }    private void up() {        final boolean flag = mDirect == DIRECT_UP;        //已经错误一次 且本次也错误        if (!checkErrorTimes() && !flag) {            showResult();            return;        }        mUserList.add(new Item(mIndex, mDirect, mDirect == DIRECT_UP ? DIRECT_UP : DIRECT_UNCLEAR));        next(flag);    }    private void down() {        final boolean flag = mDirect == DIRECT_DOWN;        //已经错误一次 且本次也错误        if (!checkErrorTimes() && !flag) {            showResult();            return;        }        mUserList.add(new Item(mIndex, mDirect, flag? DIRECT_DOWN : DIRECT_UNCLEAR));        next(flag);    }    private void left() {        final boolean flag = mDirect == DIRECT_LEFT;        //已经错误一次 且本次也错误        if (!checkErrorTimes() && !flag) {            showResult();            return;        }        mUserList.add(new Item(mIndex, mDirect, flag ? DIRECT_LEFT : DIRECT_UNCLEAR));        next(flag);    }    private void right() {        final boolean flag = mDirect == DIRECT_RIGHT;        //已经错误一次 且本次也错误        if (!checkErrorTimes() && !flag) {            showResult();            return;        }        mUserList.add(new Item(mIndex, mDirect, flag ? DIRECT_RIGHT : DIRECT_UNCLEAR));        next(flag);    }    /**     * 看不清楚 两次后终止     */    private void unClear() {        //已经错误一次 再次错误        if (!checkErrorTimes()) {            showResult();            return;        }        mUserList.add(new Item(mIndex, mDirect, DIRECT_UNCLEAR));        next(false);    }    /**     * 检查是否已经错误过一次     *     * @return flag     */    private boolean checkErrorTimes() {        boolean flag = true;        for (Item item : mUserList) {            int index = item.getIndex();            if (index == mIndex && item.getUser_direct() == DIRECT_UNCLEAR) {                flag = false;                break;            }        }        return flag;    }    private void next(boolean clear) {        if (clear) {            mIndex++;        }        if (mIndex > 8) {            showResult();        } else {            playAnim();        }    }    private void showResult() {        AlertDialog.Builder dialog = new AlertDialog.Builder(this);        dialog.setTitle("测试结果");        String msg = "";        for (Item item : mUserList) {            msg += item.getResult();        }        dialog.setMessage(msg);        dialog.create();        dialog.setNegativeButton("重新测试", new DialogInterface.OnClickListener() {            @Override            public void onClick(DialogInterface dialog, int which) {                finish();                startActivity(new Intent(TestEyeActivity.this, TestEyeActivity.class));            }        });        dialog.setPositiveButton("退出测试", new DialogInterface.OnClickListener() {            @Override            public void onClick(DialogInterface dialog, int which) {                finish();            }        });        dialog.show();    }    /**     * 播放动画 缩放 + 旋转     * 随着mIndex++ 图片每次缩小10%     * mDirect方向随机生成 如果错误一次不缩小 只换旋转     */    private void playAnim() {        float from = 1 - (float) (0.1 * mIndex);        float to = 1 - (float) (0.1 * (mIndex + 1));        AnimationSet set = new AnimationSet(true);        ScaleAnimation scaleAnimation = new ScaleAnimation(from, to, from, to, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);        set.addAnimation(scaleAnimation);        Random random = new Random();        int rd = random.nextInt(4);        //保存本次旋转角度 以便下次使用        float fromDegrees = mLastToDegrees;        mLastToDegrees = fromDegrees + 90 * rd;        float toDegrees = mLastToDegrees;        RotateAnimation rotate = new RotateAnimation(fromDegrees, toDegrees, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);        set.addAnimation(rotate);        set.setDuration(500);        set.setFillAfter(true);        mImgEye.startAnimation(set);        //记录旋转后的方向        mDirect += rd;        if (mDirect < 4) {            mDirect += 4;        }        mDirect %= 4;        mAsr.startListening(mRecognizerListener);    }    /**     * 云端构建语法监听器。     */    private GrammarListener mCloudGrammarListener = new GrammarListener() {        @Override        public void onBuildFinish(String grammarId, SpeechError error) {            if (error == null) {                String grammarID = new String(grammarId);                SharedPreferences.Editor editor = mSharedPreferences.edit();                if (!TextUtils.isEmpty(grammarId))                    editor.putString(KEY_GRAMMAR_ABNF_ID, grammarID);                editor.apply();                showTip("语法构建成功:" + grammarId);            } else {                showTip("语法构建失败,错误码:" + error.getErrorCode());            }        }    };    /**     * 初始化监听器。     */    private InitListener mInitListener = new InitListener() {        @Override        public void onInit(int code) {            Log.d(TAG, "SpeechRecognizer init() code = " + code);            if (code != ErrorCode.SUCCESS) {                showTip("初始化失败,错误码:" + code);            }        }    };    /**     * 识别监听器。     */    private RecognizerListener mRecognizerListener = new RecognizerListener() {        @Override        public void onVolumeChanged(int volume, byte[] data) {            showTip("当前正在说话,音量大小:" + volume);            Log.d(TAG, "返回音频数据:" + data.length);        }        @Override        public void onResult(final RecognizerResult result, boolean isLast) {            if (null != result) {                Log.d(TAG, "recognizer result:" + result.getResultString());                if ("cloud".equalsIgnoreCase(mEngineType)) {                    String text = JsonParser.parseGrammarResult(result.getResultString());                    if (TextUtils.isEmpty(text)) {                        showTip("语音识别失败");                    } else {                        if (text.contains(TEXT_UP)) {                            up();                        } else if (text.contains(TEXT_RIGHT)) {                            right();                        } else if (text.contains(TEXT_DOWN)) {                            down();                        } else if (text.contains(TEXT_LEFT)) {                            left();                        } else if (text.contains(TEXT_UNCLEAR) || text.contains(TEXT_NOT_VISIBLE) || text.contains(TEXT_NOT_SEE)) {                            unClear();                        } else {                            showTip("语音识别失败");                        }                    }                }            } else {                Log.d(TAG, "recognizer result : null");            }        }        @Override        public void onEndOfSpeech() {            // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入            showTip("结束说话");        }        @Override        public void onBeginOfSpeech() {            // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入            showTip("开始说话");        }        @Override        public void onError(SpeechError error) {            showTip("onError Code:" + error.getErrorCode());        }        @Override        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {            // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因            // 若使用本地能力,会话id为null            //if (SpeechEvent.EVENT_SESSION_ID == eventType) {            //String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);            //Log.d(TAG, "session id =" + sid);            //}        }    };    private void showTip(final String str) {        runOnUiThread(new Runnable() {            @Override            public void run() {                mToast.setText(str);                mToast.show();            }        });    }    /**     * 内部类 记录每次选择     */    class Item {        //次数        private int index;        //系统的方向        private int direct;        //用户选择的方向        private int user_direct;        public Item(int index, int direct, int user_direct) {            this.index = index;            this.direct = direct;            this.user_direct = user_direct;        }        public int getIndex() {            return index;        }        public int getUser_direct() {            return user_direct;        }        public String getResult() {            StringBuilder sb = new StringBuilder();            sb.append("第");            sb.append(index + 1);            sb.append("次");            sb.append("  ");            sb.append(appendText(direct));            sb.append("  ");            sb.append("选择");            sb.append("  :  ");            sb.append(appendText(user_direct));            sb.append("  ---->  ");            sb.append(direct == user_direct ? "正确" : "错误");            sb.append("\n");            return sb.toString();        }        private String appendText(int direct) {            String text = "";            switch (direct) {                case DIRECT_UP:                    text = "上";                    break;                case DIRECT_RIGHT:                    text = "右";                    break;                case DIRECT_DOWN:                    text = "下";                    break;                case DIRECT_LEFT:                    text = "左";                    break;                case DIRECT_UNCLEAR:                    text = "看不清";                    break;            }            return text;        }    }    @Override    protected void onDestroy() {        super.onDestroy();        // 退出时释放连接        mAsr.cancel();        mAsr.destroy();    }}








0 0
原创粉丝点击