版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1333587
本文主要介绍一下之前学习的安卓平台下 “图灵机器人的设计”,希望能给爱学习的你到来更多的启发和兴趣。当然,随着时间的推延,技术的优化和进步,难免出现新技术的更迭,所以要经常充电学习...
安卓开发:android4.2-5.0
【注:2017-12-12】
今天在同事手机上安装了一下试试,发现红米手机可支持,并且没有使用讯飞输入法也可以完成。
毕竟代码编辑久远,当初的代码是在 android4.2 - 5.0 版本下开发的,如今的安卓版本更新换代快,终究会出现兼容问题,此外两年多没有碰安卓代码了,可能很难给以参考的伙伴以有价值的建议,希望多多进步咯 ...
一.前期准备:
1.代码编写之前,在此提供 前辈大牛的视频讲解 ,其中涉及到了图灵账号的注册和效果实现
2.其中注册网址为 图灵机器人官网 ,具体操作可看官方文档和之前的视频链接
3.在此补充一个感觉很好的 参考博文 ,编写之前也参考了他的很多,主要还是学习众家所长嘛
4.代码使用了讯飞语音,个人认为如果使用的讯飞输入法,同时下载了其语音,在编辑的同时即可使用,而此代码表示需要在联网状态进行语音的输入转化。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- 讯飞语音权限开始 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 讯飞语音权限结束 -->
注意对应的jar包使用,之后会附上源码下载地址作为参考
(1). /HoMotou/res/layout/motou_view.xml 源码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="@drawable/bg4"
android:layout_height="match_parent" >
<include
android:id="@+id/include_top_motou"
layout="@layout/top_motou" />
<RelativeLayout
android:id="@+id/id_ly_bottom"
android:layout_width="fill_parent"
android:layout_height="55dp"
android:layout_alignParentBottom="true"
android:background="@drawable/bottom_bar" >
<Button
android:id="@+id/id_send_msg"
android:layout_width="60dp"
android:layout_height="40dp"
android:layout_marginRight="3dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/send_btn_bg"
android:text="发送" />
<Button
android:layout_marginLeft="3dp"
android:id="@+id/iv_voice"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@drawable/voice"
android:text="" />
<EditText
android:id="@+id/id_input_msg"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_toRightOf="@id/iv_voice"
android:layout_toLeftOf="@id/id_send_msg"
android:background="@drawable/login_edit_normal"
android:textSize="18sp" />
</RelativeLayout>
<ListView
android:id="@+id/id_listview_msgs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="7dp"
android:layout_marginRight="7dp"
android:layout_above="@id/id_ly_bottom"
android:layout_below="@id/include_top_motou"
android:divider="@null"
android:dividerHeight="5dp" >
</ListView>
</RelativeLayout>
(2). /HoMotou/res/layout/item_from_msg.xml 源码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_weight="1"
android:id="@+id/id_form_msg_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/timeDemo"
android:textColor="@color/darkGreen"
android:textSize="12sp" />
<LinearLayout
android:layout_weight="2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:layout_width="49dp"
android:layout_height="49dp"
android:src="@drawable/sgc" />
<TextView
android:id="@+id/id_from_msg_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/chatfrom_bg_normal"
android:gravity="center_vertical"
android:textSize="17sp"
android:textColor="@color/dark_hese"
android:text="@string/hello" />
</LinearLayout>
</LinearLayout>
(3). /HoMotou/res/layout/item_to_msg.xml 源码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:orientation="vertical" >
<TextView
android:id="@+id/id_to_msg_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/timeDemo"
android:textColor="@color/darkGreen"
android:textSize="12sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<LinearLayout
android:layout_weight="5"
android:gravity="right"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/id_to_msg_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:background="@drawable/chatto_bg_normal"
android:text="dfgs发过"
android:textColor="@color/dark_hese"
android:textSize="17sp" />
</LinearLayout>
<ImageView
android:layout_weight="1"
android:layout_width="49dp"
android:layout_height="49dp"
android:src="@drawable/yoo" />
</LinearLayout>
</LinearLayout>
(4)./HoMotou/res/layout/top_motou.xml 源码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#eee"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="46dp"
android:gravity="center"
android:background="#ebebeb"
android:orientation="horizontal" >
<TextView
android:layout_weight="3"
android:paddingLeft="3dp"
android:id="@+id/tv_back"
android:textColor="#C0C0C0"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" />
<TextView
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/top_motou"
android:gravity="center"
android:textSize="18sp"
android:textColor="#008000" />
<TextView
android:layout_weight="3"
android:paddingLeft="3dp"
android:id="@+id/tv_2"
android:textColor="#C0C0C0"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" />
</LinearLayout>
<ImageView
android:id="@+id/id_iv_tabline"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@drawable/tabline" />
</LinearLayout>
(/HoMotou/src/com/mo/adapter/ChatMessageAdapter.java)
package com.mo.adapter;
import java.text.SimpleDateFormat;
import java.util.List;
import com.mo.bean.ChatMessage;
import com.mo.bean.ChatMessage.Type;
import com.mo.hoo.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class ChatMessageAdapter extends BaseAdapter
{
private LayoutInflater mInflater;
private List<ChatMessage> mDatas;
public ChatMessageAdapter(Context context, List<ChatMessage> mDatas)
{
mInflater = LayoutInflater.from(context);
this.mDatas = mDatas;
}
@Override
public int getCount()
{
return mDatas.size();
}
@Override
public Object getItem(int position)
{
return mDatas.get(position);
}
@Override
public long getItemId(int position)
{
return position;
}
@Override
public int getItemViewType(int position)
{
ChatMessage chatMessage = mDatas.get(position);
if (chatMessage.getType() == Type.INCOMING)
{
return 0;
}
return 1;
}
@Override
public int getViewTypeCount()
{
return 2;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ChatMessage chatMessage = mDatas.get(position);
ViewHolder viewHolder = null;
if (convertView == null)
{
// 通过ItemType设置不同的布局
if (getItemViewType(position) == 0)
{
convertView = mInflater.inflate(R.layout.item_from_msg, parent,
false);
viewHolder = new ViewHolder();
viewHolder.mDate = (TextView) convertView
.findViewById(R.id.id_form_msg_date);
viewHolder.mMsg = (TextView) convertView
.findViewById(R.id.id_from_msg_info);
} else
{
convertView = mInflater.inflate(R.layout.item_to_msg, parent,
false);
viewHolder = new ViewHolder();
viewHolder.mDate = (TextView) convertView
.findViewById(R.id.id_to_msg_date);
viewHolder.mMsg = (TextView) convertView
.findViewById(R.id.id_to_msg_info);
}
convertView.setTag(viewHolder);
} else
{
viewHolder = (ViewHolder) convertView.getTag();
}
// 设置数据
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
viewHolder.mDate.setText(df.format(chatMessage.getDate()));
viewHolder.mMsg.setText(chatMessage.getMsg());
return convertView;
}
private final class ViewHolder
{
TextView mDate;
TextView mMsg;
}
}
(/HoMotou/src/com/mo/util/HttpUtils.java)
package com.mo.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.util.Date;
import com.google.gson.Gson;
import com.mo.bean.ChatMessage;
import com.mo.bean.ChatMessage.Type;
import com.mo.bean.Result;
public class HttpUtils
{
private static final String URL = "http://www.tuling123.com/openapi/api";
//"请自行申请apikey"
private static final String API_KEY = "0905b3be27b638a58362d682529e2a3b";
/**
* 发送一个消息,得到返回的消息
* @param msg
* @return
*/
public static ChatMessage sendMessage(String msg)
{
ChatMessage chatMessage = new ChatMessage();
String jsonRes = doGet(msg);
Gson gson = new Gson();
Result result = null;
try
{
result = gson.fromJson(jsonRes, Result.class);
chatMessage.setMsg(result.getText());
} catch (Exception e)
{
chatMessage.setMsg("服务器繁忙,请稍候再试");
}
chatMessage.setDate(new Date());
chatMessage.setType(Type.INCOMING);
return chatMessage;
}
public static String doGet(String msg)
{
String result = "";
String url = setParams(msg);
ByteArrayOutputStream baos = null;
InputStream is = null;
try
{
java.net.URL urlNet = new java.net.URL(url);
HttpURLConnection conn = (HttpURLConnection) urlNet
.openConnection();
conn.setReadTimeout(5 * 1000);
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
is = conn.getInputStream();
int len = -1;
byte[] buf = new byte[128];
baos = new ByteArrayOutputStream();
while ((len = is.read(buf)) != -1)
{
baos.write(buf, 0, len);
}
baos.flush();
result = new String(baos.toByteArray());
} catch (MalformedURLException e)
{
e.printStackTrace();
} catch (Exception e)
{
e.printStackTrace();
} finally
{
try
{
if (baos != null)
baos.close();
} catch (IOException e)
{
e.printStackTrace();
}
try
{
if (is != null)
{
is.close();
}
} catch (IOException e)
{
e.printStackTrace();
}
}
return result;
}
private static String setParams(String msg)
{
String url = "";
try
{
url = URL + "?key=" + API_KEY + "&info="
+ URLEncoder.encode(msg, "UTF-8");
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
return url;
}
}
(/HoMotou/src/com/mo/hoo/MuTouActivity.java)
package com.mo.hoo;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.mo.adapter.ChatMessageAdapter;
import com.mo.bean.ChatMessage;
import com.mo.bean.ChatMessage.Type;
import com.mo.util.HttpUtils;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MuTouActivity extends Activity {
public static String toMsg="";
private ListView mMsgs;
private ChatMessageAdapter mAdapter;
private List<ChatMessage> mDatas;
private TextView tv_back;
public static EditText mInputMsg;
private Button mSendMsg;
private Button iv_voice;
private Handler mHandler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
// 等待接收,子线程完成数据的返回
ChatMessage fromMessge = (ChatMessage) msg.obj;
mDatas.add(fromMessge);
mAdapter.notifyDataSetChanged();
mMsgs.setSelection(mDatas.size()-1);
};
};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
overridePendingTransition(R.anim.push_right_in,R.anim.hold);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.motou_view);
initView();
initDatas();
// 初始化事件
initListener();
}
private void initListener()
{
mSendMsg.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
toMsg = mInputMsg.getText().toString();
if (TextUtils.isEmpty(toMsg))
{
Toast.makeText(MuTouActivity.this, "发送消息不能为空!",
Toast.LENGTH_SHORT).show();
return;
}
ChatMessage toMessage = new ChatMessage();
toMessage.setDate(new Date());
toMessage.setMsg(toMsg);
toMessage.setType(Type.OUTCOMING);
mDatas.add(toMessage);
mAdapter.notifyDataSetChanged();
mMsgs.setSelection(mDatas.size()-1);
mInputMsg.setText("");
new Thread()
{
public void run()
{
ChatMessage fromMessage = HttpUtils.sendMessage(toMsg);
Message m = Message.obtain();
m.obj = fromMessage;
mHandler.sendMessage(m);
};
}.start();
}
});
tv_back.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
finish();
overridePendingTransition(R.anim.hold,R.anim.push_right_out);
}
});
}
private void initDatas()
{
mDatas = new ArrayList<ChatMessage>();
mDatas.add(new ChatMessage("笨蛋,找我干嘛啊?", Type.INCOMING, new Date()));
mAdapter = new ChatMessageAdapter(this, mDatas);
mMsgs.setAdapter(mAdapter);
iv_voice.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 初始化,再加载
//MyRecognizerDialogLister.text="";
VoiceToWord voice = new VoiceToWord(MuTouActivity.this,"534e3fe2");
voice.GetWordFromVoice();
}
});
}
private void initView()
{
mMsgs = (ListView) findViewById(R.id.id_listview_msgs);
mInputMsg = (EditText) findViewById(R.id.id_input_msg);
mSendMsg = (Button) findViewById(R.id.id_send_msg);
tv_back=(TextView) findViewById(R.id.tv_back);
iv_voice=(Button) findViewById(R.id.iv_voice);
}
}
package com.mo.hoo;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
import android.text.TextUtils;
//import com.iflytek.speech.ErrorCode;
//import com.iflytek.speech.SpeechError;
/**
* 对云端返回的Json结果进行解析
* @author iFlytek
* @since 20131211
*/
public class JsonParser {
/**
* 听写结果的Json格式解析
* @param json
* @return
*/
private static boolean isTag;
public static String parseIatResult(String json) {
if(TextUtils.isEmpty(json))
return "";
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
// 听写结果词,默认使用第一个结果
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
JSONObject obj = items.getJSONObject(0);
ret.append(obj.getString("w"));
// 如果需要多候选结果,解析数组其他字段
// for(int j = 0; j < items.length(); j++)
// {
// JSONObject obj = items.getJSONObject(j);
// ret.append(obj.getString("w"));
// }
}
} catch (Exception e) {
e.printStackTrace();
}
return ret.toString();
}
/**
* 识别结果的Json格式解析
* @param json
* @return
*/
public static String parseGrammarResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
for(int j = 0; j < items.length(); j++)
{
JSONObject obj = items.getJSONObject(j);
if(obj.getString("w").contains("nomatch"))
{
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append("【结果】" + obj.getString("w"));
ret.append("【置信度】" + obj.getInt("sc"));
ret.append("\n");
}
}
} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}
/**
* 语义结果的Json格式解析
* @param json
* @return
*/
public static String parseUnderstandResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
ret.append("【应答码】" + joResult.getString("rc") + "\n");
ret.append("【转写结果】" + joResult.getString("text") + "\n");
ret.append("【服务名称】" + joResult.getString("service") + "\n");
ret.append("【操作名称】" + joResult.getString("operation") + "\n");
ret.append("【完整结果】" + json);
} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}
}
package com.mo.hoo;
import com.iflytek.cloud.speech.SpeechConstant;
import com.iflytek.cloud.speech.SpeechError;
import com.iflytek.cloud.speech.SpeechListener;
import com.iflytek.cloud.speech.SpeechRecognizer;
import com.iflytek.cloud.speech.SpeechUser;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.widget.Toast;
public class VoiceToWord extends Activity{
private Context context;
private Toast mToast;
//识别窗口
private RecognizerDialog iatDialog;
//识别对象
private SpeechRecognizer iatRecognizer;
//缓存,保存当前的引擎参数到下一次启动应用程序使用.
private SharedPreferences mSharedPreferences;
private RecognizerDialogListener recognizerDialogListener = null;
public VoiceToWord(Context context,String APP_ID) {
// TODO Auto-generated constructor stub
//用户登录
this.context = context;
SpeechUser.getUser().login(context, null, null
, "appid=" + APP_ID, listener);
//初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer
iatDialog =new RecognizerDialog(context);
mToast = Toast.makeText(context, "", Toast.LENGTH_LONG);
//初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer
iatDialog =new RecognizerDialog(context);
//初始化缓存对象.
mSharedPreferences = context.getSharedPreferences(context.getPackageName(),MODE_PRIVATE);
}
public VoiceToWord(Context context,String APP_ID,RecognizerDialogListener recognizerDialogListener)
{
this.context = context;
SpeechUser.getUser().login(context, null, null
, "appid=" + APP_ID, listener);
//初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer
iatDialog =new RecognizerDialog(context);
mToast = Toast.makeText(context, "", Toast.LENGTH_LONG);
//初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer
iatDialog =new RecognizerDialog(context);
//初始化缓存对象.
mSharedPreferences = context.getSharedPreferences(context.getPackageName(),MODE_PRIVATE);
this.recognizerDialogListener = recognizerDialogListener;
}
public void GetWordFromVoice()
{
boolean isShowDialog = mSharedPreferences.getBoolean("iat_show",true);
if (isShowDialog) {
//显示语音听写Dialog.
showIatDialog();
} else {
if(null == iatRecognizer) {
iatRecognizer=SpeechRecognizer.createRecognizer(this);
}
if(iatRecognizer.isListening()) {
iatRecognizer.stopListening();
// ((Button) findViewById(android.R.id.button1)).setEnabled(false);
} else {
}
}
}
private void showTip1(String str)
{
if(!TextUtils.isEmpty(str))
{
mToast.setText(str);
mToast.show();
}
}
/**
* 显示听写对话框.
* @param
*/
public void showIatDialog()
{
if(null == iatDialog) {
//初始化听写Dialog
iatDialog =new RecognizerDialog(this);
}
//获取引擎参数
String engine = mSharedPreferences.getString(
"iat_engine",
"iat");
//清空Grammar_ID,防止识别后进行听写时Grammar_ID的干扰
iatDialog.setParameter(SpeechConstant.CLOUD_GRAMMAR, null);
//设置听写Dialog的引擎
iatDialog.setParameter(SpeechConstant.DOMAIN, engine);
//设置采样率参数,支持8K和16K
String rate = mSharedPreferences.getString(
"sf",
"sf");
if(rate.equals("rate8k"))
{
iatDialog.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
}
else
{
iatDialog.setParameter(SpeechConstant.SAMPLE_RATE, "16000");
}
if(recognizerDialogListener == null)
{
getRecognizerDialogListener();
}
//显示听写对话框
iatDialog.setListener(recognizerDialogListener);
iatDialog.show();
}
private void getRecognizerDialogListener()
{
/**
* 识别回调监听器
*/
recognizerDialogListener=new MyRecognizerDialogLister(context);
}
/**
* 用户登录回调监听器.
*/
private SpeechListener listener = new SpeechListener()
{
@Override
public void onData(byte[] arg0) {
}
@Override
public void onCompleted(SpeechError error) {
if(error != null) {
System.out.println("user login success");
}
}
@Override
public void onEvent(int arg0, Bundle arg1) {
}
};
}
【声明】如有转载,请注明信息来源,欢迎学习,指点 ...