疯狂Android讲义--- 一些有手写识别意思的小玩意儿
2018-06-27 本文已影响74人
亚欧沙龙
疯狂Android讲义--- 一些有意思的小玩意儿
- [x] 增强手势
- [x] 手势的识别
- [x] 自动朗读(TTS)
今天来一波新鲜小程序~~
gesture.gif增强手势
来来来....先上新布局控件--GestureOverlayView(一个记录手势的平台)
activity_main_xml
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/gestureTip"
android:textStyle="bold"
android:textSize="22sp"/>
<android.gesture.GestureOverlayView
android:id="@+id/gesture"
android:layout_width="match_parent"
android:layout_height="410dp"
android:gestureStrokeType="multiple"/>
<!--将gestureStrokeType的参数设置为multiple目的是该手势可由多笔组成-->
MainActivity
Android 使用GestureLibrary来代表手势库,并提供了GestureLibraries工具类来创建手势库,并且 GestureLibraries 还提供了以下四个静态方法:
static GrstureLibrary fromFile(String path):从path代表的文件中加载手势库
staic Gesturelirary froPrivateFile context.Stingname): 从指定应用程序的数据文件夹的mame 文件中加载手势库
static GesturelLibrary fromRawResource(Context context,int resourceld)从所代表的资源中加载手势库
void addGesture(Sting entyName,Gesturegesture): 添加一个名为entyName 的手势
ArrayList<Gesture> getGestures(String entryName): 获取entry Name 名称对应的全部手势
ArrayList<Prediction>recognize(Gesture gesture): 从当前手势库中识别与gesture匹配的全部手势
void removeEntry(String entryName): 制除手势库中entryName 对应的手势
void removeGesture(String entryName,Gesture gesture): 删除手势库中entyYame、gesture 对应的手势。
bolean save():当向手势库中添加手势或从中删除手势后调用该方法保存手势库
//获取文本编辑框
mEditText = (EditText)findViewById(R.id.gesture_name);
//获取手势编辑框
mGestureView = (GestureOverlayView) findViewById(R.id.gesture);
//设置手势绘制的颜色
mGestureView.setGestureColor(Color.RED);
//设置手势绘制的宽度
mGestureView.setGestureStrokeWidth(8);
//为gesture设置监听器
mGestureView.addOnGesturePerformedListener(
new OnGesturePerformedListener() {
@Override
public void onGesturePerformed(GestureOverlayView overlay, final Gesture gesture) {
//加载save.xml界面布局所代表的视图
View saveDialog = getLayoutInflater().inflate(R.layout.save,null);
//获取saveDialog的show组件
ImageView imageView = (ImageView) saveDialog.findViewById(R.id.show);
//获取saveDialog里的gesture_name组件
final EditText gestureName = (EditText) saveDialog.findViewById(R.id.gesture_name);
//根据Gesture包含的手势创建一个位图
Bitmap bitmap = gesture.toBitmap(128,128,10,0xffff0000);
//将那个将位图用图片显示出来
imageView.setImageBitmap(bitmap);
//使用对话框显示saveDialog的组件
new AlertDialog.Builder(MainActivity.this)
.setView(saveDialog)
.setPositiveButton("保存", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//获取指定文件对应的收拾库
gestureLib = GestureLibraries
.fromFile("/wanghao");
//添加手势
gestureLib.addGesture(gestureName.getText().toString(),gesture);
//保存手势库
gestureLib.save();
}
}).setNegativeButton("取消",null).show();
}
}
);
手势的识别
布局呢。。。。就很简单了,如果看过上面的代码的话,相信可以自己写一个GestureOverlayView了吧
重要的就是gestureAcitvity.java
gestureLibrary_1 = GestureLibraries
.fromFile("/wanghao");
if (gestureLibrary_1.load()){
Toast.makeText(getsureActivity.this, "手势装载成功", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(getsureActivity.this, "手势装载失败", Toast.LENGTH_SHORT).show();
}
gestureView = (GestureOverlayView) findViewById(R.id.gesture_1);
gestureView.addOnGesturePerformedListener(
new GestureOverlayView.OnGesturePerformedListener() {
@Override
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = gestureLibrary_1
.recognize(gesture);
ArrayList<String> result = new ArrayList<>();
for (Prediction pred : predictions) {
if (pred.score > 2.0){
result.add("与手势【" + pred.name + "】相似度为" + pred.score);
}
}
if (result.size() > 0){
ArrayAdapter<Object> adapter = new ArrayAdapter<Object>(getsureActivity.this,
android.R.layout.simple_dropdown_item_1line,result.toArray());
new AlertDialog.Builder(getsureActivity.this)
.setAdapter(adapter,null)
.setPositiveButton("确定",null).show();
}else {
Toast.makeText(getsureActivity.this, "无法找到匹配的手势", Toast.LENGTH_SHORT).show();
}
}
}
);
}
自动朗读
这个布局么。。。EditText + 两个Button,相信大家也应该学会了吧
直接走逻辑
GestureLibrary提供了recognize(Festure ges)方法来识别手势,
该方法会返回手势库中所有与ges相匹配的手势
recognize(Festure ges)方法的返回值为ArrayList<Prediction其中
prediction封装了手势的匹配信息
Prediction对象的name属性代表了匹配的手势名,score代表了手势的相似度
TextToSpeech tts;
EditText mEditText;
Button speech;
Button record;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tts);
//初始化TextToSpeech对象
tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
//如果TTS引擎成功
if (status == TextToSpeech.SUCCESS){
//设置使用美式英语朗读
int result = tts.setLanguage(Locale.US);
//如果不支持所设置的语言
if (result != TextToSpeech.LANG_COUNTRY_AVAILABLE
&& result != TextToSpeech.LANG_AVAILABLE){
Toast.makeText(TtsActivity.this, "TTS暂时还不支持这种语言的朗读",
Toast.LENGTH_SHORT).show();
}
}
}
});
mEditText = (EditText) findViewById(R.id.txt);
speech = (Button ) findViewById(R.id.speech);
record = (Button) findViewById(R.id.record);
speech.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onClick(View v) {
//执行朗读
tts.speak(mEditText.getText().toString(),
TextToSpeech.QUEUE_ADD,null,"speed");
}
});
record.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onClick(View v) {
//将朗读文本音频尽录到指定文件
tts.synthesizeToFile(mEditText.getText().toString(),null,
new File("/wanghao"),"record");
Toast.makeText(TtsActivity.this, "声音记录成功", Toast.LENGTH_SHORT).show();
}
});
}
//
//一定要在Activity回调之前关闭TextSpeech对象
@Override
protected void onDestroy() {
super.onDestroy();
//关闭TextSpeech对象
if (tts != null){
tts.shutdown();
}
}
最最最重要的,可别忘了饿哦们这可是访问SD卡的
从Android4.0开始读取SD卡就成为危险了,所以尽快加上一行代码
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />