版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、.基于Android的智能聊天機(jī)器人的設(shè)計(jì)與實(shí)現(xiàn)學(xué)院名稱:專業(yè):班級:學(xué)號:姓名:任課教師:安卓智能聊天機(jī)器人開發(fā)(一)這個(gè)聊天機(jī)器人有點(diǎn)像前段時(shí)間很火的一個(gè)安卓應(yīng)用小黃雞應(yīng)用的實(shí)現(xiàn)其實(shí)很簡單,網(wǎng)上有許多關(guān)于智能機(jī)器人聊天的接口,我們只需要去調(diào)用對應(yīng)的接口,遵守它的API開發(fā)規(guī),就可以獲取到我們想要的信息這里我使用的接口是圖靈機(jī)器人(.tuling123./openapi/)這個(gè)接口給我們返回的是Json字符串,我們只需要對它進(jìn)行Json字符串解析,就可以實(shí)現(xiàn)這個(gè)應(yīng)用。開發(fā)步驟:首先我們需要到這個(gè)圖靈機(jī)器人的官網(wǎng)去注冊一個(gè)賬號,他會(huì)給我們一個(gè)唯一Key,通過這個(gè)Key和對應(yīng)的API開發(fā)規(guī),我們
2、就可以進(jìn)行開發(fā)了。然后在這個(gè)(.tuling123./openapi/cloud/access_api.jsp)網(wǎng)址里可以找到相關(guān)的開發(fā)介紹比如:請求方式,參數(shù),返回參數(shù),包括開發(fā)例,一些返回的編碼等信息這里是官方提供的一個(gè)調(diào)用小案例(JAVA),這里我也順帶貼一下/* 調(diào)用圖靈機(jī)器人平臺(tái)接口* 需要導(dǎo)入的包:commons-logging-1.0.4.jar、 httpclient-4.3.1.jar、httpcore-4.3.jar */ public static void main(String args) throws IOException String INFO = URLEnc
3、oder.encode("今日天氣", "utf-8"); String requesturl = ".tuling123./openapi/api"key= 注冊激活返回的Apikey&info="+INFO; HttpGet request = new HttpGet(requesturl); HttpResponse response = HttpClients.createDefault().execute(request); /200即正確的返回碼 if(response.getStatusLine().g
4、etStatusCode()=200) String result = EntityUtils.toString(response.getEntity(); System.out.println("返回結(jié)果:"+result); 好了,接下來開始實(shí)戰(zhàn)吧,這個(gè)應(yīng)用我打算寫成兩篇文章第一篇講下關(guān)于如何調(diào)用接口,從網(wǎng)上獲取數(shù)據(jù),包括解析Json字符串第二篇會(huì)把這些獲取的數(shù)據(jù)嵌入到安卓應(yīng)用首先,先寫一個(gè)工具類,這個(gè)工具類是用來獲取用戶輸入的信息并返回服務(wù)器提供的數(shù)據(jù)的這里面用到了一個(gè)第三方提供的JAR包,Gson它是谷歌提供給我們用來使Json數(shù)據(jù)序列化和反序列化的關(guān)于
5、Gson的使用我之前寫過一篇筆記,不熟悉的朋友可以看看:Gson簡要使用筆記(.cnblogs./lichenwei/p/3987429.html)代碼如下:具體看注釋package .example.utils;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.UnsupportedEncodingException;import .HttpURLConnection;import .MalformedURLException;im
6、port .URLEncoder;import java.util.Date;import android.util.Log;import .example.pojo.Message;import .example.pojo.Message.Type;import .example.pojo.Result;import .google.gson.Gson;/* * * 獲取信息幫助類傳入用戶輸入的字符,給出相對應(yīng)的信息 * */public class GetDataUtils private static final String API_KEY = "這里填寫官方提供的KEY&q
7、uot;/ 申請的API_KEY值 private static final String URL = ".tuling123./openapi/api"/ 接口請求地址 public String getChat(String msg) /這個(gè)方法是獲取服務(wù)端返回回來的Json數(shù)據(jù),msg為用戶輸入的信息 String result = "/ 存放服務(wù)器返回信息的變量 InputStream inputStream = null; ByteArrayOutputStream outputStream = null; try / 進(jìn)行資源請求 .URL url =
8、 new .URL(getMsgUrl(msg); HttpURLConnection httpURLConnection = (HttpURLConnection) url .openConnection();/ 打開資源連接 / HttpURLConnection參數(shù)設(shè)定 httpURLConnection.setReadTimeout(5 * 1000); httpURLConnection.setConnectTimeout(5 * 1000); httpURLConnection.setRequestMethod("GET"); inputStream = htt
9、pURLConnection.getInputStream();/ 獲取一個(gè)輸入流接收服務(wù)端返回的信息 int len = -1; byte bs = new byte124;/ 用來接收輸入流的字節(jié)數(shù)組 outputStream = new ByteArrayOutputStream();/ 用一個(gè)輸出流來輸出剛獲取的輸入流所得到的信息 while (len = inputStream.read(bs) != -1) / 從輸入流中讀取一定數(shù)量的字節(jié),并將其存儲(chǔ)在緩沖區(qū)數(shù)組 / bs 中 outputStream.write(bs, 0, len);/ 往輸入流寫入 outputStream
10、.flush();/ 清除緩沖區(qū) result = new String(outputStream.toByteArray();/ 轉(zhuǎn)換成字符串 catch (MalformedURLException e) e.printStackTrace(); catch (IOException e) e.printStackTrace(); finally / 關(guān)閉相關(guān)資源 if (inputStream != null) try inputStream.close(); catch (IOException e) e.printStackTrace(); if (outputStream != n
11、ull) try outputStream.close(); catch (IOException e) e.printStackTrace(); Log.i("tuzi", "result:" + result);/打印測試日志 return result; private String getMsgUrl(String msg) throws UnsupportedEncodingException String path = " String info = URLEncoder.encode(msg, "UTF-8")
12、;/ 轉(zhuǎn)換url編碼 path = URL + "key=" + API_KEY + "&info=" + msg; return path; public Message getInfo(String msg) Message message=new Message(); Gson gson=new Gson(); try Result result=gson.fromJson(getChat(msg), Result.class);/獲取到服務(wù)器返回的json并轉(zhuǎn)換為Result對象,Result對象可能不存在,會(huì)出現(xiàn)異常 message.s
13、etMsg(result.getText();/message可能為空,需要捕獲異常 catch (Exception e) /可能服務(wù)器沒有返回正常數(shù)據(jù),也就存在著空白容,需要捕獲異常 message.setMsg("服務(wù)器繁忙,請稍后再試"); message.setTime(new Date(); message.setType(Type.INCOME); return message; 下面這2個(gè)是實(shí)體類,根據(jù)官網(wǎng)提供的示例,返回的Json字符串里包含:code狀態(tài)碼,text文本容package .example.pojo;/* * * 用來映射返回Json字符串
14、 * */public class Result private String code; private String text; public String getCode() return code; public void setCode(String code) this.code = code; public String getText() return text; public void setText(String text) this.text = text; package .example.pojo;import java.util.Date;public class
15、Message private String name; private String msg; private Date time; private Type type; public enum Type/類型枚舉,發(fā)送,接收 INCOME,OUTCOME public String getName() return name; public void setName(String name) = name; public String getMsg() return msg; public void setMsg(String msg) this.msg = msg;
16、public Date getTime() return time; public void setTime(Date time) this.time = time; public Type getType() return type; public void setType(Type type) this.type = type; 編寫個(gè)測試類package .example.test;import android.test.AndroidTestCase;import android.util.Log;import .example.pojo.Message;import .example
17、.utils.GetDataUtils;public class GetDataUtilsTest extends AndroidTestCase public void test() GetDataUtils dataUtils=new GetDataUtils(); Message message=dataUtils.getInfo("你好"); Message message1=dataUtils.getInfo("你是誰"); Message message2=dataUtils.getInfo("你知道JAVA是什么嗎");
18、 Message message3=dataUtils.getInfo("下雨了,天好冷"); Log.i("兔子",message.getMsg(); Log.i("兔子",message1.getMsg(); Log.i("兔子",message2.getMsg(); Log.i("兔子",message3.getMsg(); 在JAVA WEB里編寫測試單元用到的是Junit,需要導(dǎo)入jar包,在安卓開發(fā)里也有類似這樣的步驟首先我們要在AndroidManifest.xml里的applic
19、ation標(biāo)簽里添加<uses-library android:name="android.test.runner"/>然后在application外添加<instrumentation android:name="android.test.InstrumentationTestRunner" android:label="ceshi" android:targetPackage=".example.androidchat"></instrumentation>由于需要聯(lián)網(wǎng)別忘了
20、給應(yīng)用賦予網(wǎng)絡(luò)權(quán)限<uses-permission android:name="android.permission.INTERNET"/>這里是完整文件代碼:<"xml version="1.0" encoding="utf-8"><manifest xmlns:android="schemas.android./apk/res/android" package=".example.androidchat" android:versionCode=&qu
21、ot;1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="dr
22、awable/ic_launcher" android:label="string/app_name" android:theme="style/AppTheme" > <uses-library android:name="android.test.runner" /> <activity android:name=".MainActivity" android:label="string/app_name" > <intent-filter>
23、; <action android:name="ent.action.MAIN" /> <category android:name="ent.category.LAUNCHER" /> </intent-filter> </activity> </application> <instrumentation android:name="android.test.InstrumentationTestRunner" androi
24、d:label="ceshi" android:targetPackage=".example.androidchat" > </instrumentation></manifest>看下我們的測試代碼效果圖:好了,此時(shí)我們已經(jīng)可以獲取到服務(wù)端的數(shù)據(jù),并且接收到客戶端并做處理在上一篇文章中,已經(jīng)實(shí)現(xiàn)了對網(wǎng)絡(luò)數(shù)據(jù)的獲取和處理封裝,這篇文章來講下如何嵌入到安卓應(yīng)用中。先看下效果圖:從上面兩圖我們可以發(fā)現(xiàn),這個(gè)聊天布局其實(shí)就是一個(gè)ListView,只不過它和傳統(tǒng)的ListView有些區(qū)別,因?yàn)樗褂昧硕郔tem樣式布局首先,先來分
25、析下基礎(chǔ)布局:這個(gè)界面是由3個(gè)布局文件組成,分別是主布局,發(fā)送消息樣式布局,接收消息樣式布局先來看下主布局:這里是對應(yīng)的主布局代碼:android:divider="null"-去除ListView的Item分割線<RelativeLayout xmlns:android="schemas.android./apk/res/android" xmlns:tools="schemas.android./tools" android:layout_width="match_parent" android:layo
26、ut_height="match_parent" android:background="drawable/chat_bg_default" > <LinearLayout android:id="+id/title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:backgro
27、und="drawable/title_bar" android:gravity="center" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_gravity="center" android:text="機(jī)器兔" android:
28、textColor="android:color/white" android:textSize="20sp" /> </LinearLayout> <RelativeLayout android:id="+id/bottom" android:layout_width="fill_parent" android:layout_height="55dp" android:layout_alignParentBottom="true" android:b
29、ackground="drawable/bottom_bar" android:padding="5dp" > <EditText android:id="+id/send_message" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertica
30、l="true" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:background="drawable/login_edit_normal" /> <Button android:id="+id/send_bt" android:layout_width="wrap_content" android:layout_height="fill_parent&
31、quot; android:layout_alignParentRight="true" android:layout_alignRight="id/send_message" android:background="drawable/send_button_selector" android:gravity="center_vertical" android:text="發(fā)送" /> </RelativeLayout> <ListView android:id=&quo
32、t;+id/chatlistview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="id/bottom" android:layout_below="id/title" android:divider="null" > </ListView></RelativeLayout>再來看下消息布局:(由于消息布局只是左右兩
33、邊方向的不同,這里只給出其中一個(gè))這是2個(gè)消息布局的代碼:<"xml version="1.0" encoding="utf-8"><LinearLayout xmlns:android="schemas.android./apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical
34、" > <TextView android:id="+id/sendtime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="*999999" android:text="2014-11-07 18:00" android:textColor="
35、;android:color/white" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"
36、 android:orientation="vertical" > <!- 頭像昵稱部分 -> <ImageView android:layout_width="50dp" android:layout_height="50dp" android:src="drawable/icon1" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_conte
37、nt" android:layout_gravity="center" android:text="機(jī)器兔" /> </LinearLayout> <TextView android:id="+id/sendmsg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="drawable/chatfrom_bg_norma
38、l" android:text="你好,我是機(jī)器兔。" /> </LinearLayout></LinearLayout><"xml version="1.0" encoding="utf-8"><LinearLayout xmlns:android="schemas.android./apk/res/android" android:layout_width="match_parent" android:layout_heig
39、ht="match_parent" android:orientation="vertical" > <TextView android:id="+id/receivetime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="*999999"
40、android:text="2014-11-07 18:00" android:textColor="android:color/white" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="right" android:orientation="horizontal" > <TextVie
41、w android:id="+id/receivemsg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="drawable/chatto_bg_normal" android:text="你好,我是機(jī)器兔。" android:textColor="android:color/black" /> <LinearLayout an
42、droid:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <!- 頭像昵稱部分 -> <ImageView android:layout_width="50dp" android:layout_height="50dp" android:src="drawable/icon" /> <Text
43、View android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:text="我" /> </LinearLayout> </LinearLayout></LinearLayout>接下來看下關(guān)于ListView的自定義適配器,和往常一樣自定義適配器需要繼承BaseAdapter,并實(shí)現(xiàn)一些必須的方法這里有個(gè)
44、需要注意的是,因?yàn)閭鹘y(tǒng)的ListView是統(tǒng)一一個(gè)樣式的,而這里的聊天布局是左右兩邊收發(fā)信息多Item樣式所以需要額外的多覆寫2個(gè)方法:1、getViewTypeCount-返回樣式的種類數(shù)目2、getItemViewType -給定類型標(biāo)示符,便于在回調(diào)函數(shù)getView時(shí)讓系統(tǒng)知道我們需要顯示的哪個(gè)樣式代碼里還提到了ViewHolder,這個(gè)是優(yōu)化ListView加載速度的一種方法,關(guān)于這個(gè)知識(shí)點(diǎn)我整理一篇筆記安卓開發(fā)筆記ListView加載性能優(yōu)化ViewHolder出來,不熟悉的朋友可以看看。package .example.androidchat;import java.
45、text.SimpleDateFormat;import java.util.List;import .example.pojo.Msg;import .example.pojo.Msg.Type;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;/* * * ListView
46、適配器 * */public class ChatAdapter extends BaseAdapter private List<Msg> data; private LayoutInflater inflater;/ 布局工廠,可以把res/layout的xml布局文件轉(zhuǎn)換成view對象 public ChatAdapter(Context context, List<Msg> data) inflater = LayoutInflater.from(context); this.data = data; Override public int getCount()
47、 return data.size(); Override public Object getItem(int position) return data.get(position); Override public long getItemId(int position) return position; Override public View getView(int position, View convertView, ViewGroup parent) Msg message = data.get(position); ViewHolder viewHolder = null; if
48、 (convertView = null) / 未加載布局文件對象 / 可以通過getItemViewType所定義的標(biāo)識(shí)來設(shè)定對應(yīng)的item樣式 if (getItemViewType(position) = 0) / 接收信息 viewHolder = new ViewHolder(); convertView = inflater.inflate(R.layout.send_msg, null); viewHolder.time = (TextView) convertView .findViewById(R.id.receivetime); viewHolder.msg = (Text
49、View) convertView .findViewById(R.id.receivemsg); else viewHolder = new ViewHolder(); convertView = inflater.inflate(R.layout.receive_msg, null); viewHolder.time = (TextView) convertView .findViewById(R.id.sendtime); viewHolder.msg = (TextView) convertView .findViewById(R.id.sendmsg); convertView.se
50、tTag(viewHolder); else / 已經(jīng)存在布局文件對象 viewHolder = (ViewHolder) convertView.getTag(); / 設(shè)置數(shù)據(jù) SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); viewHolder.time.setText(dateFormat.format(message.getTime(); viewHolder.msg.setText(message.getMsg(); return convertView; /
51、* * 由于此處我們要返回2種ListView的Item樣式,需要再額外多覆寫2個(gè)方法 * (1)、getItemViewType(int position)給定類型標(biāo)示符 * (2)、getViewTypeCount() 類型數(shù)量 */ Override public int getItemViewType(int position) Msg message = data.get(position); if (message.getType() = Type.INCOME) return 0;/ 如果消息類型為接收,則值為0 return 1;/ 如果消息類型為發(fā)送,則值為1 Override public int getViewTypeCount() return 2; private final class ViewHolder TextView time;/ 消息時(shí)間 TextView msg;/ 消息容 然后就是主程序代碼了:這里就沒什么好說的了,網(wǎng)絡(luò)數(shù)據(jù)獲取工具類包括ListView的適配器類在之前已經(jīng)提過,這里就只剩下調(diào)用了。注意點(diǎn)有3:1、那就是在UI主線程里不能直接取獲取網(wǎng)絡(luò)數(shù)據(jù),這里我們需要另開一個(gè)子線程去獲取,然后在通過Handler去更新UI界面。2、當(dāng)數(shù)據(jù)源發(fā)生更新的時(shí)候,需要在UI主線程去操
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- H國有企業(yè)員工績效管理優(yōu)化研究
- 二零二五版門衛(wèi)室安全防范應(yīng)急預(yù)案合同4篇
- 二零二五年度腳手架租賃與安全培訓(xùn)協(xié)議3篇
- 綠色包裝線索對消費(fèi)者食品購買意愿的影響
- 2025年度常州消防設(shè)施改造項(xiàng)目施工合同范本4篇
- 基于分子動(dòng)力學(xué)的水化硅酸鈣的徐變特性研究
- 2025新版公司裝修合同范本
- 2025民間借款合同范本集錦
- Unit 2 Travelling integrated skills說課稿 - 2024-2025學(xué)年牛津譯林版八年級英語下冊
- 2025年度個(gè)人集資房買賣合同規(guī)范文本4篇
- 藥學(xué)技能競賽標(biāo)準(zhǔn)答案與評分細(xì)則處方
- 2025屆高考英語 716個(gè)閱讀理解高頻詞清單
- 報(bào)建協(xié)議書模板
- 汽車配件購銷合同范文
- 貴州省2024年中考英語真題(含答案)
- 施工項(xiàng)目平移合同范本
- (高清版)JTGT 3360-01-2018 公路橋梁抗風(fēng)設(shè)計(jì)規(guī)范
- 胰島素注射的護(hù)理
- 云南省普通高中學(xué)生綜合素質(zhì)評價(jià)-基本素質(zhì)評價(jià)表
- 2024年消防產(chǎn)品項(xiàng)目營銷策劃方案
- 聞道課件播放器
評論
0/150
提交評論