文章目录

  • 1.极光推送
    • 1.1 基本使用
    • 1.2 极光推送的高级使用
    • 1.3 推送原理介绍
  • 2.科大讯飞
    • 2.1 语音听写
    • 2.2 语音合成
    • 2.3 聊天机器人:布局搭建
    • 2.4 聊天机器人:数据填充
    • 2.5 聊天机器人:语音数据解析 & 展示提问对象
    • 2.6 聊天机器人:展示回答对象 & 朗读回答
  • 3.友盟统计
    • 3.1 介绍 & SDK使用
    • 3.2 友盟指数
  • 4.ZXing
  • 5.DynamicGrid

1.极光推送

1.1 基本使用

消息推送,类似于社交工具中QQ、微信中的聊天功能,即消息之间的传输,其原理图如下所示:

消息推送的主要特点,是指客户端被动接收服务端的消息,即使客户端服务端没有相连。而消息推送的应用也不局限于聊天功能,还应用在广告推送、私信推送等

要实现消息推送的技术,就需要引入一个第三方的框架:JPush(极光推送),而JPush的使用,可以参考此篇集成文档:http://docs.jiguang.cn/jpush/client/Android/android_guide/,这里不再详述。

而想用快速创建demo,则可参考http://docs.jiguang.cn/jpush/client/Android/android_3m/来实现,这里不再详述

1.2 极光推送的高级使用

想要进行极光推送的高级使用,可参考http://docs.jiguang.cn/jpush/client/Android/android_api/,这里不再详述

1.3 推送原理介绍

在客户端和服务端之间,一般进行一次数据的发送和接收后就会断开相互的连接。然而,在消息推送中,这样的连接在数据传输的过程中不会断开,则称为长连接

  • Http1.1之后,支持长连接

  • xmpp协议,专门适用于消息推送,此种协议更加精简,没有过多冗余的数据

  • socket,套接字,网络底层实现

  • TCPUDP,传输协议

  • 心跳包:客户端每隔一段时间(比如说30秒)向服务器发送一段极短的数据,来证明自己还“活着”

2.科大讯飞

2.1 语音听写

要实现这个功能,同样需要借助一个第三方框架——科大讯飞语音云,官方网站为:https://www.xfyun.cn/

在这里要实现语音听写的功能,网站为:https://www.xfyun.cn/services/voicedictation

这里不再详述

2.2 语音合成

在这里要实现语音合成的功能,网站为:https://www.xfyun.cn/services/online_tts

这里不再详述

2.3 聊天机器人:布局搭建

通过科大讯飞的这些api,可以实现一个简单的聊天机器人的应用

聊天菜单可用ListView来实现,而每一条聊天记录可用item来实现

  1. 新建一个项目,导入科大讯飞的jar包,然后修改activity_main.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="match_parent"android:orientation="vertical"><ListViewandroid:id="@+id/lv_list"android:layout_width="match_parent"android:layout_height="0dp"android:divider="@null"android:layout_weight="1"/><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/bottom_bar"><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/btn_selector"android:layout_centerHorizontal="true"android:layout_centerVertical="true"android:onClick="startVoice"android:text="点击开始语音识别"/></RelativeLayout>
</LinearLayout>
  1. 在drawable目录下建立按钮的状态选择器文件btn_selector.xml,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_pressed="true" android:drawable="@drawable/btn_voice_search_pressed"/><item android:drawable="@drawable/btn_voice_search_normal"/></selector>

2.4 聊天机器人:数据填充

前面将布局搭建好了,接下来就是为ListView填充数据

  1. 修改MainActivity,获取ListView的实例,并且注册适配器,代码如下:
package com.example.chatrobot;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;public class MainActivity extends AppCompatActivity {private ListView lvList;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);lvList = findViewById(R.id.lv_list);}public void startVoice(View view){}class ChatAdapter extends BaseAdapter{@Overridepublic int getCount() {return 0;}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {return null;}}
}
  1. 建立ListView的子布局文件list_item.xml,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"><TextViewandroid:id="@+id/tv_ask"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_alignParentTop="true"android:background="@drawable/asker_bubble"android:gravity="center"android:paddingLeft="10dp"android:paddingRight="15dp"android:textColor="#000"android:textSize="16sp"android:text="提问"/><LinearLayoutandroid:id="@+id/ll_answer"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:paddingLeft="15dp"android:paddingRight="10dp"android:layout_below="@id/tv_ask"android:background="@drawable/answer_bubble"android:orientation="vertical"><TextViewandroid:id="@+id/tv_answer"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:textColor="#000"android:textSize="16sp"android:text="回答"/><ImageViewandroid:id="@+id/iv_answer"android:layout_width="wrap_content"android:layout_height="wrap_content"android:visibility="gone"android:src="@drawable/p1"/></LinearLayout>
</RelativeLayout>
  1. 修改MainActivity,引用刚刚创建好的布局,并创建内部类ViewHolder,代码如下:
package com.example.chatrobot;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;public class MainActivity extends AppCompatActivity {private ListView lvList;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);lvList = findViewById(R.id.lv_list);}public void startVoice(View view){}class ChatAdapter extends BaseAdapter{@Overridepublic int getCount() {return 0;}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView == null){convertView = View.inflate(getApplicationContext(),R.layout.list_item,null);holder = new ViewHolder();holder.tvAsk = convertView.findViewById(R.id.tv_ask);holder.tvAnswer = convertView.findViewById(R.id.tv_answer);holder.llAnswer = convertView.findViewById(R.id.ll_answer);holder.ivAnswer = convertView.findViewById(R.id.iv_answer);convertView.setTag(holder);}else {holder = (ViewHolder) convertView.getTag();}return convertView;}}static class ViewHolder{public TextView tvAsk;public TextView tvAnswer;public LinearLayout llAnswer;public ImageView ivAnswer;}
}
  1. 建立TalkBean类,作为每句对话的实体类对象,代码如下:
package com.example.chatrobot;public class TalkBean {public String content;public boolean isAsk;public int imageId = -1;public TalkBean(String content, boolean isAsk, int imageId) {this.content = content;this.isAsk = isAsk;this.imageId = imageId;}
}
  1. 修改MainActivity,用ArrayList来存储刚刚创建好的对象,并且进行相应调用,将ListView和Adapter进行匹配,代码如下:
package com.example.chatrobot;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;import java.util.ArrayList;public class MainActivity extends AppCompatActivity {private ListView lvList;private ArrayList<TalkBean> mTalkList = new ArrayList<>();private ChatAdapter mAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);lvList = findViewById(R.id.lv_list);mAdapter = new ChatAdapter();lvList.setAdapter(mAdapter);}public void startVoice(View view){}class ChatAdapter extends BaseAdapter{@Overridepublic int getCount() {return mTalkList.size();}@Overridepublic TalkBean getItem(int position) {return mTalkList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView == null){convertView = View.inflate(getApplicationContext(),R.layout.list_item,null);holder = new ViewHolder();holder.tvAsk = convertView.findViewById(R.id.tv_ask);holder.tvAnswer = convertView.findViewById(R.id.tv_answer);holder.llAnswer = convertView.findViewById(R.id.ll_answer);holder.ivAnswer = convertView.findViewById(R.id.iv_answer);convertView.setTag(holder);}else {holder = (ViewHolder) convertView.getTag();}TalkBean item = getItem(position);if (item.isAsk){// 提问holder.tvAsk.setVisibility(View.VISIBLE);holder.llAnswer.setVisibility(View.GONE);holder.tvAsk.setText(item.content);}else {holder.tvAsk.setVisibility(View.GONE);holder.llAnswer.setVisibility(View.VISIBLE);holder.tvAnswer.setText(item.content);if (item.imageId > 0){// 有图片holder.ivAnswer.setVisibility(View.VISIBLE);holder.ivAnswer.setImageResource(item.imageId);}else {// 无图片holder.ivAnswer.setVisibility(View.GONE);}}return convertView;}}static class ViewHolder{public TextView tvAsk;public TextView tvAnswer;public LinearLayout llAnswer;public ImageView ivAnswer;}
}

2.5 聊天机器人:语音数据解析 & 展示提问对象

现在我们完成了数据的填充,接下来就要开始运用到科大讯飞的语音听写api了

  1. 修改MainActivity,完善startVoice()方法,代码如下:
public void startVoice(View view){RecognizerDialog mDialog = new RecognizerDialog(this, null);mDialog.setParameter(SpeechConstant.LANGUAGE,"zh_cn");mDialog.setParameter(SpeechConstant.ACCENT,"mandarin");mDialog.setListener(new RecognizerDialogListener() {@Overridepublic void onResult(RecognizerResult recognizerResult, boolean b) {String result = recognizerResult.getResultString();}@Overridepublic void onError(SpeechError speechError) {}});mDialog.show();}
  1. 由于要使用GSON来解析语音识别后的JSON数据,这里需要创建一个实体类VoiceBean,代码如下:
package com.example.chatrobot;import java.util.ArrayList;public class VoiceBean {public ArrayList<WsBean> ws;public class WsBean{public ArrayList<CwBean> cw;}public class CwBean{public String w;}
}
  1. 修改MainActivity,添加processData()方法,引入GSON来解析json数据,代码如下:
package com.example.chatrobot;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;import com.google.gson.Gson;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;import java.util.ArrayList;public class MainActivity extends AppCompatActivity {private ListView lvList;private ArrayList<TalkBean> mTalkList = new ArrayList<>();private ChatAdapter mAdapter;private StringBuffer mBuffer;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);SpeechUtility.createUtility(this, SpeechConstant.APPID +"=5bfca40b");lvList = findViewById(R.id.lv_list);mAdapter = new ChatAdapter();lvList.setAdapter(mAdapter);}public void startVoice(View view){RecognizerDialog mDialog = new RecognizerDialog(this, null);mDialog.setParameter(SpeechConstant.LANGUAGE,"zh_cn");mDialog.setParameter(SpeechConstant.ACCENT,"mandarin");mBuffer = new StringBuffer();mDialog.setListener(new RecognizerDialogListener() {@Overridepublic void onResult(RecognizerResult recognizerResult, boolean b) {String result = recognizerResult.getResultString();String resultStriing = processData(result);mBuffer.append(resultStriing);if (b){// 话已经说完了String finalResult = mBuffer.toString();}}@Overridepublic void onError(SpeechError speechError) {}});mDialog.show();}private String processData(String result) {Gson gson = new Gson();VoiceBean voiceBean = gson.fromJson(result, VoiceBean.class);StringBuffer sb = new StringBuffer();for (VoiceBean.WsBean ws : voiceBean.ws) {String word = ws.cw.get(0).w;sb.append(word);}return sb.toString();}class ChatAdapter extends BaseAdapter{@Overridepublic int getCount() {return mTalkList.size();}@Overridepublic TalkBean getItem(int position) {return mTalkList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView == null){convertView = View.inflate(getApplicationContext(),R.layout.list_item,null);holder = new ViewHolder();holder.tvAsk = convertView.findViewById(R.id.tv_ask);holder.tvAnswer = convertView.findViewById(R.id.tv_answer);holder.llAnswer = convertView.findViewById(R.id.ll_answer);holder.ivAnswer = convertView.findViewById(R.id.iv_answer);convertView.setTag(holder);}else {holder = (ViewHolder) convertView.getTag();}TalkBean item = getItem(position);if (item.isAsk){// 提问holder.tvAsk.setVisibility(View.VISIBLE);holder.llAnswer.setVisibility(View.GONE);holder.tvAsk.setText(item.content);}else {holder.tvAsk.setVisibility(View.GONE);holder.llAnswer.setVisibility(View.VISIBLE);holder.tvAnswer.setText(item.content);if (item.imageId > 0){// 有图片holder.ivAnswer.setVisibility(View.VISIBLE);holder.ivAnswer.setImageResource(item.imageId);}else {// 无图片holder.ivAnswer.setVisibility(View.GONE);}}return convertView;}}static class ViewHolder{public TextView tvAsk;public TextView tvAnswer;public LinearLayout llAnswer;public ImageView ivAnswer;}
}
  1. 修改MainActivity,修改startVoice()方法,将解析后的字符串初始化为提问语句,并添加到集合中,代码如下:
public void startVoice(View view){RecognizerDialog mDialog = new RecognizerDialog(this, null);mDialog.setParameter(SpeechConstant.LANGUAGE,"zh_cn");mDialog.setParameter(SpeechConstant.ACCENT,"mandarin");mBuffer = new StringBuffer();mDialog.setListener(new RecognizerDialogListener() {@Overridepublic void onResult(RecognizerResult recognizerResult, boolean b) {String result = recognizerResult.getResultString();String resultStriing = processData(result);mBuffer.append(resultStriing);if (b){// 话已经说完了String finalResult = mBuffer.toString();// 初始化提问对象TalkBean askBean = new TalkBean(finalResult,true,-1);mTalkList.add(askBean);mAdapter.notifyDataSetChanged(); // 刷新ListView}}@Overridepublic void onError(SpeechError speechError) {}});mDialog.show();}

2.6 聊天机器人:展示回答对象 & 朗读回答

之前创建好了提问的对象,现在就来创建回答的对象

  1. 修改MainActivity,修改startVoice()方法,初始化提问对象,编写回话逻辑,代码如下:
package com.example.chatrobot;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;import com.google.gson.Gson;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;import java.util.ArrayList;public class MainActivity extends AppCompatActivity {private ListView lvList;private ArrayList<TalkBean> mTalkList = new ArrayList<>();private ChatAdapter mAdapter;private StringBuffer mBuffer;private String[] mAnswers = new String[]{"约吗?","这张怎么样?","100块啦","不要再要啦","最后一张啦"};private int[] mImageIds = new int[]{R.drawable.p1,R.drawable.p2,R.drawable.p3,R.drawable.p4};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);SpeechUtility.createUtility(this, SpeechConstant.APPID +"=5bfca40b");lvList = findViewById(R.id.lv_list);mAdapter = new ChatAdapter();lvList.setAdapter(mAdapter);}public void startVoice(View view){RecognizerDialog mDialog = new RecognizerDialog(this, null);mDialog.setParameter(SpeechConstant.LANGUAGE,"zh_cn");mDialog.setParameter(SpeechConstant.ACCENT,"mandarin");mBuffer = new StringBuffer();mDialog.setListener(new RecognizerDialogListener() {@Overridepublic void onResult(RecognizerResult recognizerResult, boolean b) {String result = recognizerResult.getResultString();String resultStriing = processData(result);mBuffer.append(resultStriing);if (b){// 话已经说完了String finalResult = mBuffer.toString();// 初始化提问对象TalkBean askBean = new TalkBean(finalResult,true,-1);mTalkList.add(askBean);// 初始化回答对象String answerContent = "没听清";int imageId = -1;if (finalResult.contains("你好")){answerContent = "你好呀!";}else if (finalResult.contains("你是谁")){answerContent = "我是你的小助手!";}else if (finalResult.contains("美女")){// 随机回答int i = (int) (Math.random() * mAnswers.length);answerContent = mAnswers[i];// 随机图片int j = (int) (Math.random() * mImageIds.length);imageId = mImageIds[j];}else if (finalResult.contains("天王盖地虎")){answerContent = "小鸡炖蘑菇";imageId = R.drawable.m;}TalkBean answerBean = new TalkBean(answerContent,false,imageId);mTalkList.add(answerBean);mAdapter.notifyDataSetChanged(); // 刷新ListViewlvList.setSelection(mTalkList.size() - 1);// 显示在最后一个Item上}}@Overridepublic void onError(SpeechError speechError) {}});mDialog.show();}private String processData(String result) {Gson gson = new Gson();VoiceBean voiceBean = gson.fromJson(result, VoiceBean.class);StringBuffer sb = new StringBuffer();for (VoiceBean.WsBean ws : voiceBean.ws) {String word = ws.cw.get(0).w;sb.append(word);}return sb.toString();}class ChatAdapter extends BaseAdapter{@Overridepublic int getCount() {return mTalkList.size();}@Overridepublic TalkBean getItem(int position) {return mTalkList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView == null){convertView = View.inflate(getApplicationContext(),R.layout.list_item,null);holder = new ViewHolder();holder.tvAsk = convertView.findViewById(R.id.tv_ask);holder.tvAnswer = convertView.findViewById(R.id.tv_answer);holder.llAnswer = convertView.findViewById(R.id.ll_answer);holder.ivAnswer = convertView.findViewById(R.id.iv_answer);convertView.setTag(holder);}else {holder = (ViewHolder) convertView.getTag();}TalkBean item = getItem(position);if (item.isAsk){// 提问holder.tvAsk.setVisibility(View.VISIBLE);holder.llAnswer.setVisibility(View.GONE);holder.tvAsk.setText(item.content);}else {holder.tvAsk.setVisibility(View.GONE);holder.llAnswer.setVisibility(View.VISIBLE);holder.tvAnswer.setText(item.content);if (item.imageId > 0){// 有图片holder.ivAnswer.setVisibility(View.VISIBLE);holder.ivAnswer.setImageResource(item.imageId);}else {// 无图片holder.ivAnswer.setVisibility(View.GONE);}}return convertView;}}static class ViewHolder{public TextView tvAsk;public TextView tvAnswer;public LinearLayout llAnswer;public ImageView ivAnswer;}
}
  1. 修改MainActivity,添加startSpeak()方法,用于将回答内容朗诵出来,代码如下:
package com.example.chatrobot;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;import com.google.gson.Gson;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;import java.util.ArrayList;public class MainActivity extends AppCompatActivity {private ListView lvList;private ArrayList<TalkBean> mTalkList = new ArrayList<>();private ChatAdapter mAdapter;private StringBuffer mBuffer;private String[] mAnswers = new String[]{"约吗?","这张怎么样?","100块啦","不要再要啦","最后一张啦"};private int[] mImageIds = new int[]{R.drawable.p1,R.drawable.p2,R.drawable.p3,R.drawable.p4};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);SpeechUtility.createUtility(this, SpeechConstant.APPID +"=5bfca40b");lvList = findViewById(R.id.lv_list);mAdapter = new ChatAdapter();lvList.setAdapter(mAdapter);}public void startVoice(View view){RecognizerDialog mDialog = new RecognizerDialog(this, null);mDialog.setParameter(SpeechConstant.LANGUAGE,"zh_cn");mDialog.setParameter(SpeechConstant.ACCENT,"mandarin");mBuffer = new StringBuffer();mDialog.setListener(new RecognizerDialogListener() {@Overridepublic void onResult(RecognizerResult recognizerResult, boolean b) {String result = recognizerResult.getResultString();String resultStriing = processData(result);mBuffer.append(resultStriing);if (b){// 话已经说完了String finalResult = mBuffer.toString();// 初始化提问对象TalkBean askBean = new TalkBean(finalResult,true,-1);mTalkList.add(askBean);// 初始化回答对象String answerContent = "没听清";int imageId = -1;if (finalResult.contains("你好")){answerContent = "你好呀!";}else if (finalResult.contains("你是谁")){answerContent = "我是你的小助手!";}else if (finalResult.contains("美女")){// 随机回答int i = (int) (Math.random() * mAnswers.length);answerContent = mAnswers[i];// 随机图片int j = (int) (Math.random() * mImageIds.length);imageId = mImageIds[j];}else if (finalResult.contains("天王盖地虎")){answerContent = "小鸡炖蘑菇";imageId = R.drawable.m;}TalkBean answerBean = new TalkBean(answerContent,false,imageId);mTalkList.add(answerBean);mAdapter.notifyDataSetChanged(); // 刷新ListViewlvList.setSelection(mTalkList.size() - 1);// 显示在最后一个Item上startSpeak(answerContent);}}@Overridepublic void onError(SpeechError speechError) {}});mDialog.show();}private void startSpeak(String answerContent) {SpeechSynthesizer synthesizer = SpeechSynthesizer.createSynthesizer(this, null);synthesizer.setParameter(SpeechConstant.VOICE_NAME,"xiaoyan");synthesizer.setParameter(SpeechConstant.SPEED,"50");synthesizer.setParameter(SpeechConstant.VOLUME,"80");synthesizer.setParameter(SpeechConstant.ENGINE_TYPE,SpeechConstant.TYPE_CLOUD);synthesizer.setParameter(SpeechConstant.TTS_AUDIO_PATH,"./sdcard/iflytek.pcm");synthesizer.startSpeaking(answerContent,null);}private String processData(String result) {Gson gson = new Gson();VoiceBean voiceBean = gson.fromJson(result, VoiceBean.class);StringBuffer sb = new StringBuffer();for (VoiceBean.WsBean ws : voiceBean.ws) {String word = ws.cw.get(0).w;sb.append(word);}return sb.toString();}class ChatAdapter extends BaseAdapter{@Overridepublic int getCount() {return mTalkList.size();}@Overridepublic TalkBean getItem(int position) {return mTalkList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView == null){convertView = View.inflate(getApplicationContext(),R.layout.list_item,null);holder = new ViewHolder();holder.tvAsk = convertView.findViewById(R.id.tv_ask);holder.tvAnswer = convertView.findViewById(R.id.tv_answer);holder.llAnswer = convertView.findViewById(R.id.ll_answer);holder.ivAnswer = convertView.findViewById(R.id.iv_answer);convertView.setTag(holder);}else {holder = (ViewHolder) convertView.getTag();}TalkBean item = getItem(position);if (item.isAsk){// 提问holder.tvAsk.setVisibility(View.VISIBLE);holder.llAnswer.setVisibility(View.GONE);holder.tvAsk.setText(item.content);}else {holder.tvAsk.setVisibility(View.GONE);holder.llAnswer.setVisibility(View.VISIBLE);holder.tvAnswer.setText(item.content);if (item.imageId > 0){// 有图片holder.ivAnswer.setVisibility(View.VISIBLE);holder.ivAnswer.setImageResource(item.imageId);}else {// 无图片holder.ivAnswer.setVisibility(View.GONE);}}return convertView;}}static class ViewHolder{public TextView tvAsk;public TextView tvAnswer;public LinearLayout llAnswer;public ImageView ivAnswer;}
}

3.友盟统计

3.1 介绍 & SDK使用

统计,顾名思义,作用是统计应用的各种访问流量数据,这里要使用一个第三方的SDK——友盟统计,官网为:https://www.umeng.com/,官网上有相关使用教程

这里不再详述

3.2 友盟指数

友盟指数(现在更名为全域罗盘),是友盟自己对于应用这个SDK所进行的各种统计数据,可以在友盟的官网上查看:https://compass.umeng.com/

4.ZXing

二维码,在日常生活中很常见,一般扫描后会显示详情信息,如图所示:

其中,位于左上、左下、右上角都有一个独特的黑点,是作为二维码的特有标识点,而黑白相继出现的方块,则代表着计算机中的0和1

同样的,由于二维码底层实现复杂,因此这里同样引入一个第三方框架——ZXing来实现二维码的逻辑

5.DynamicGrid

DynamicGrid,是一种可拖拽的GridVew,可以用于实现频道的管理,如图所示:

Android开发实战《智慧北京》——7.项目拓展相关推荐

  1. Xamarin Android开发实战(上册)

    Xamarin Android开发实战(上册)大学霸内部资料 试读文档下载地址:http://pan.baidu.com/s/1jGEHhhO 密码:vcfm 介绍: 本教程是国内唯一的Xamarin ...

  2. 《Java和Android开发实战详解》——2.2节构建Java应用程序

    本节书摘来自异步社区<Java和Android开发实战详解>一书中的第2章,第2.2节构建Java应用程序,作者 陈会安,更多章节内容可以访问云栖社区"异步社区"公众号 ...

  3. Android开发实战---一个汽车销售APP,有汽车列表页、汽车详情页、贷款计算页3个界面。

    Android开发实战设计并实现一个汽车销售APP,要求至少有汽车列表页.汽车详情页.贷款计算页3个界面. 已开源:https://github.com/yan123666/wlf 实现结果: 1.计 ...

  4. 《Java和Android开发实战详解》——2.5节良好的Java程序代码编写风格

    本节书摘来自异步社区<Java和Android开发实战详解>一书中的第2章,第2.5节良好的Java程序代码编写风格,作者 陈会安,更多章节内容可以访问云栖社区"异步社区&quo ...

  5. 《Java和Android开发实战详解》——1.2节Java基础知识

    本节书摘来自异步社区<Java和Android开发实战详解>一书中的第1章,第1.2节Java基础知识,作者 陈会安,更多章节内容可以访问云栖社区"异步社区"公众号查看 ...

  6. android垃圾清理动画,[Android开发实战]金山清理大师(猎豹清理大师)一键加速快捷方式动画实现...

    转载请注明出处:http://blog.csdn.net/ruils/article/details/16922557 最近有人问我金山清理大师桌面上的一键加速的动画是如何实现的,我下了个金山清理大师 ...

  7. 【系】微信小程序云开发实战坚果商城-商城项目搭建

    第 2-1 课:商城项目搭建 目录 开篇 [系]微信小程序云开发实战坚果商城-开篇 基础篇 [系]微信小程序云开发实战坚果商城-弹性盒子 [系]微信小程序云开发实战坚果商城-ES6 简单入门 [系]微 ...

  8. [魔乐科技]Android开发实战经典视频教程

    http://down.51cto.com/zt/2757/6/ Android开发实战经典视频教程 http://down.51cto.com/data/407121 03_传智播客Android视 ...

  9. 阅读《名师讲坛--Android开发实战经典》

    一,专心,快速阅读一本书,直到深入理解,把书读厚,再读薄,你定会有收获. 二,20171214开始阅读<名师讲坛--Android开发实战经典>,但愿自己有所收获.从今天开始养成刻录学习写 ...

  10. 安卓开发陀螺仪!首发10万字Android开发实战文档,进阶学习资料!

    Gradle是什么? Gradle是一种构建语言,目前是Android的默认构建工具,我们编写的编译脚本,其实就是玩Gradle的API,所以从它更底层的意义上看,是一个编程框架. 因为涉及的内容很多 ...

最新文章

  1. 解决延迟有 Wi-Fi 6 就够了!
  2. sql语句分析是否走索引_MySql 的SQL执行计划查看,判断是否走索引
  3. android edittext最多输入,android 中如何限制 EditText 最大输入字符数
  4. idea中启动tomcat,控制台中文乱码问题解决方案
  5. 同一进程不同线程之间的资源共享与独享
  6. day11_界面闪烁处理
  7. CentOS 7 搭建 L2TP/Ipsec
  8. 《算法第四版》环境搭建
  9. JAVA之所得税计算器
  10. idle最好记的常用快捷键大全
  11. 会汇编语言学c语言好学吗,只有C语言功底的我学习汇编语言可以吗?
  12. kubernetes Pod 污点与容忍
  13. 计算机科学与昆虫,基于视觉的昆虫物种识别算法研究
  14. 作为一位资深Java程序员应该注意的几点
  15. JAVA获取自定义配置文件的kv值
  16. IG-REPORT企业智能报表 测试记录
  17. 计算机专业优秀毕业生,计算机专业优秀毕业生求职信
  18. 真Unity3d_人物摇杆操作(2022年重写)
  19. 二叉树思想实现的计算器
  20. 从0 到1开发一款App(三):设计

热门文章

  1. Oracle知识点(一)--创建表
  2. 盛大渗透全纪实之SVN猎手
  3. 巨龙信息大数据建模与分析技术浅析
  4. 输入10个数,将最大的数字输出;
  5. Jquery-判断form表单数据是否变化
  6. 计算机二级证书评职称有用,计算机二级证书有用吗
  7. python关键词爬取bing【必应images】高清大图
  8. Zookeeper之开源客户端ZkClient
  9. css零到一基础教程044:CSS 图标
  10. java中double身高_用JAVA编一个程序 输入10名同学的身高,找出最高升高,要求使用对象数组类型的带参方法来实现...