项目地址: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 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();    }}








更多相关文章

  1. Android(安卓): Spinner初始化时填充默认值数据
  2. Android(安卓): Spinner初始化时填充默认值数据
  3. android log日志
  4. 关于android studio启动时加载项目gradle build出现错误的解决方
  5. android studio升级后的各种错误解决
  6. Android(安卓)错误信息集锦(持续更新)
  7. android使用keystore打包错误解决方法
  8. Android文件下载
  9. Android:ADB各类错误

随机推荐

  1. sqlserver、mysql获取连接字符串步骤
  2. SqlServer修改数据库文件及日志文件存放
  3. SQL Server降权运行 SQL Server 2000以GU
  4. SQL Server 分页查询通用存储过程(只做分
  5. sqlserver清除完全重复的数据只保留重复
  6. sqlserver登陆后报不能为空不能为null的
  7. 使用sql语句创建和删除约束示例代码
  8. SQL Server的链接服务器技术小结
  9. SQL Server 2012无法连接到WMI提供程序(Ca
  10. SQL中DATEADD和DATEDIFF的用法示例介绍