IT虾米网

Android智能机器人

mate10pro 2018年06月09日 手机开发 1254 0

今天做了一个智能聊天机器人,其实相对比较简单,用到的知识点如下:

1.listView的熟练使用

2.第三方API的调用,发送数据请求和返回数据解析

3.网络请求时使用的异步任务和Handler

不过学会了之前没有接触的东西,在IDE里测试工具类,写完工具类测试是一个好习惯

public class HttpUtil { 
	 
	private static final String URL = "http://www.tuling123.com/openapi/api"; 
	private static final String API_KEY = ""; 
	private static final String CHARSET = "UTF-8"; 
	 
	 
	/* 
	 * 发送一个消息,得到ChatMessage类型返回值 
	 */ 
	public static ChatMessage sendChatmessage(String msg){ 
		 
		ChatMessage chatMessage = new ChatMessage(); 
		 
		String JsonResult = getMsg(msg); 
		 
		Gson gson = new Gson(); 
		Result result = null; 
		try { 
			result = gson.fromJson(JsonResult, Result.class); 
			 
			chatMessage.setMsg(result.getText()); 
		} catch (JsonSyntaxException e) { 
			chatMessage.setMsg("服务器异常"); 
			e.printStackTrace(); 
		} 
		 
		chatMessage.setDate(new Date()); 
		chatMessage.setType(Type.INCOMING); 
		 
		 
		return chatMessage; 
		 
	} 
	 
	/* 
	 * 发送请求,得到返回这为json数组 
	 */ 
	public static String getMsg(String msg){ 
		 
		StringBuffer result = new StringBuffer(); 
		StringBuffer outBuf = new StringBuffer(); 
		try { 
			outBuf.append("key=").append(API_KEY).append("&info=").append(URLEncoder.encode(msg, CHARSET)); 
		} catch (UnsupportedEncodingException e1) { 
			e1.printStackTrace(); 
		} 
		HttpURLConnection conn; 
		 
		try { 
			//POST方式向服务器端发送信息 
			conn = (HttpURLConnection) new URL(URL).openConnection(); 
			conn.setRequestMethod("POST"); 
			conn.setConnectTimeout(5000); 
			conn.setReadTimeout(5000); 
			 
			conn.setDoOutput(true); 
			//一行行读取和字节读取哪个更好? 
			BufferedWriter out = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), CHARSET)); 
			out.write(outBuf.toString()); 
			out.flush(); 
			 
			 
			BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), CHARSET)); 
			String line = ""; 
			while((line = in.readLine()) != null){ 
				result.append(line); 
			} 
			 
			 
		} catch (ProtocolException e) { 
			// TODO Auto-generated catch block 
			e.printStackTrace(); 
		} catch (MalformedURLException e) { 
			// TODO Auto-generated catch block 
			e.printStackTrace(); 
		} catch (IOException e) { 
			// TODO Auto-generated catch block 
			e.printStackTrace(); 
		} 
		 
		 
		 
		return result.toString(); 
	} 
 
	 
 
}


在这里首先使用POST方式发送消息给服务器(也可以采用GET方式),解析返回值时,返回值是JSON数组,用BufferReader的readline()一行行读取(也可以用字节流读取,相对来说应该更加可靠,但是效率比较慢,因此我使用字符流)。返回的JSON字符串在sendChatMessage()中使用GSON来把JSON字符串解析为对应了Bean,这里我把JSON字符串转化为了Result。工具类写好了,接下来开始测试:

<application 
        android:allowBackup="true" 
        android:icon="@drawable/xiaomeng" 
        android:label="@string/app_name" 
        android:theme="@style/AppTheme" > 
        <uses-library android:name="android.test.runner"></uses-library> 
       
        <activity 
            android:name=".MainActivity" 
            android:label="@string/app_name" > 
            <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
    </application> 
     
    <instrumentation 
        android:targetPackage="com.liu.androidxiaofeng"//指定测试程序的包名 
        android:label="This is a test"//可以随便写 
        android:name="android.test.InstrumentationTestRunner"> 
    </instrumentation>

在apalication里写了uses-library,接着编写instrucmentaction,这就是配置测试的必要步骤

接着编写测试类

public class TestHttpUtil extends AndroidTestCase { 
	 
	private static final String TAG = "TestHttpUtil"; 
	 
	public void testUtil(){ 
		 
		String res = HttpUtil.getMsg("你好"); 
		Log.d(TAG, res); 
		 
		res = HttpUtil.getMsg("给我讲个笑话"); 
		Log.d(TAG, res); 
		 
		res = HttpUtil.getMsg("我帅不帅"); 
		Log.d(TAG, res); 
		 
	} 
 
}


创建一个类继承AndroidTestCase,在里面编写测试逻辑,然后对逻辑测试方法右键 run-as-Android-JUtil-Test


说明测试成功!!

还有一点需要注意,由于listView是对话模式,因此要有两个子项布局,在编写Adapter时,要实现另外两个方法getItemViewType(int position) 和 getViewTypeCount()

public class MsgAdapter extends BaseAdapter { 
	 
	private List<ChatMessage> data; 
	private LayoutInflater inflater; 
	 
	public MsgAdapter(Context context, List<ChatMessage> data){ 
		this.data = data; 
		inflater = LayoutInflater.from(context); 
	} 
 
	 
	@Override 
	public int getCount() { 
		return data.size(); 
	} 
 
	@Override 
	public Object getItem(int position) { 
		return data.get(position); 
	} 
 
	@Override 
	public long getItemId(int position) { 
		return position; 
	} 
	 
	 
 
	@Override 
	public int getItemViewType(int position) { 
		 
		ChatMessage chatMessage = data.get(position); 
		if(chatMessage.getType() == Type.INCOMING){//如果是接受消息,返回0 
			return 0; 
		}else{ 
			return 1;//如果是发送消息,返回1 
		} 
		 
	} 
 
	@Override 
	public int getViewTypeCount() { 
		return 2;//有发送消息和接受消息两种view 
	} 
 
	@Override 
	public View getView(int position, View convertView, ViewGroup parent) { 
		 
		ChatMessage chatMessage = data.get(position); 
		ViewHolder viewHolder = null; 
		if(convertView == null){ 
			 
			if(getItemViewType(position) == 0){//说明是接受布局 
				convertView = inflater.inflate(R.layout.item_from_msg, parent, false); 
				viewHolder = new ViewHolder(); 
				viewHolder.date = (TextView) convertView.findViewById(R.id.tv_from_msg_date); 
				viewHolder.msg = (TextView) convertView.findViewById(R.id.tv_from_msg); 
			}else{//说明是发送布局 
				convertView = inflater.inflate(R.layout.item_to_msg, parent, false); 
				viewHolder = new ViewHolder(); 
				viewHolder.date = (TextView) convertView.findViewById(R.id.tv_to_msg_date); 
				viewHolder.msg = (TextView) convertView.findViewById(R.id.tv_to_msg); 
			} 
			 
			convertView.setTag(viewHolder); 
			 
		}else{ 
			viewHolder = (ViewHolder) convertView.getTag(); 
			 
		} 
		 
		//设置数据 
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
		viewHolder.date.setText(dateFormat.format(new Date())); 
		viewHolder.msg.setText(chatMessage.getMsg()); 
		 
		return convertView; 
	} 
	 
	private final class ViewHolder{ 
		TextView date; 
		TextView msg; 
	} 
 
}


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!