聊天其實就是要實作消息推送,而推送消息就需要保持連接配接(長連接配接)。在之前項目裡雖然實作了即時聊天,但是一種很本的方法。
去掉了其中的網絡通路。地圖試用的百度api
還是先放上圖,在說下做法。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5ya18mcsFna0EXZwB3awBXM4QzNxQTMvwlMw8CX4AjMxAjMvwVb1J3bm9CX05WZth2YhRHdh9CXhRXYk9CXt92YuQWavJHZuFWZvVmL3d3dvw1LcpDc0RHaiojIsJye.png)
具體做法就是,開啟一個服務,在背景每隔10秒鐘通路一起(socket)伺服器,如果有資料,則傳回資料,用戶端進行解析,然後發送廣播,即可接收到消息。
發送消息,則是由伺服器提供接口來發送。然後,伺服器與用戶端建立一個簡單的通信協定。
如:msg|發送人id|2012-2-12 07:25:12|發送類型 msg是個辨別,類型包括文本(包含表情),圖檔,語音,位置等。
圖檔和語音的發送,都是通過ftp先上傳檔案到伺服器,然後把本地存儲的路徑發送給對方。
在聊天的頁面中,使用者的頭像都是在本地存的。包括聊天的資訊,也是本地資料庫存的。這樣就能記錄資訊。也可以擴充把聊天記錄導出。
在本地建立的 消息資料庫中。要定義好聊天信心的字段,包括自己id,好友id,消息類型,文本内容,時間,是否已讀等(可擴充)
01
02
03
04
05
06
07
08
09
<code> </code><code>private</code>
<code>string table =</code><code>"create table if not exists message("</code>
<code>+</code>
<code> </code><code>"_id integer primary key,"</code>
<code> </code><code>"ttmtype integer ,"</code>
<code> </code><code>"ttmtuid integer ,"</code>
<code> </code><code>"ttmtouserid integer ,"</code>
<code> </code><code>"ttmcontent text ,"</code>
<code> </code><code>"ttmtime varchar(200) ,"</code>
<code> </code><code>"isread integer ,"</code>
<code> </code><code>"isreplylocation integer )"</code><code>;</code>
這樣再次進入聊天頁面就可以把資料庫的内容讀出來,比對到擴充卡
10
11
12
13
14
15
16
17
18
19
20
<code>public</code> <code>list<detailentity> getdatas(</code><code>int</code> <code>ttmtuid,</code><code>int</code> <code>ttmtouserid) {</code>
<code> </code>
<code>list<detailentity> de =</code><code>new</code>
<code>arraylist<detailentity>();</code>
<code>sqlitedatabase database = dbmanger.getwritabledatabase();</code>
<code>cursor cursor = database</code>
<code> </code><code>.rawquery(</code>
<code> </code><code>"select * from message where (ttmtuid = ? and ttmtouserid = ?) or (ttmtouserid = ? and ttmtuid = ?) order by _id"</code><code>,</code>
<code> </code><code>new</code>
<code>string[] { string.valueof(ttmtuid),</code>
<code> </code><code>string.valueof(ttmtouserid),</code>
<code> </code><code>string.valueof(ttmtuid),</code>
<code> </code><code>string.valueof(ttmtouserid)});</code>
<code> </code><code>while</code> <code>(cursor.movetonext()) {</code>
<code> </code><code>de.add(</code><code>new</code>
<code>detailentity(cursor.getint(</code><code>1</code><code>), cursor.getint(</code><code>2</code><code>), cursor</code>
<code> </code><code>.getint(</code><code>3</code><code>), cursor.getstring(</code><code>4</code><code>), cursor.getstring(</code><code>5</code><code>),cursor.getint(</code><code>6</code><code>),cursor.getint(</code><code>7</code><code>)));</code>
<code> </code><code>}</code>
<code> </code><code>cursor.close();</code>
<code> </code><code>database.close();</code>
<code> </code><code>return</code> <code>de;</code>
<code> </code><code>}</code>
圖檔的檢視和語音的播放,都需要從資料庫裡取出檔案儲存的路徑,不然的會顯示和播放都不正确。
仔細看源碼的話發現,在進入頁面适配資料的時候已經從資料庫讀取内容了,而在擴充卡中檢視圖檔,又重新讀取了一次,
主要是因為,不這樣做還是不能正确顯示和播放。 對這個問題很費解。
進入到聊天頁面,換取到資料,很據資料類型來加載對應的layout,當然還要判斷使用者id,資訊的讀取是根據使用者id來擷取的
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<code>messagelist = messagesqlservice.getinstance(</code><code>this</code><code>).getdatas(</code>
<code> </code><code>integer.valueof(userinfomation.getuserid(talkmessageact.</code><code>this</code><code>)),</code>
<code> </code><code>integer.valueof(tfuid));</code>
<code>for</code> <code>(</code><code>int</code> <code>i =</code>
<code>0</code><code>; i < messagelist.size(); i++) {</code>
<code> </code>
<code> </code><code>switch</code>
<code>(messagelist.get(i).getttmtype()) {</code>
<code> </code><code>case</code>
<code>1</code><code>:</code>
<code>int</code> <code>id = integer.valueof(messagelist.get(i).getttmtuid());</code>
<code>if</code> <code>(id == integer.valueof(tfuid)) {</code>
<code> </code><code>}</code><code>else</code> <code>if</code> <code>(id == integer.valueof(userinfomation</code>
<code> </code><code>.getuserid(talkmessageact.</code><code>this</code><code>))) {</code>
<code> </code>
<code> </code><code>break</code><code>;</code>
<code>2</code><code>:</code>
<code> </code><code>int</code> <code>ids = integer.valueof(messagelist.get(i).getttmtuid());</code>
<code> </code><code>if</code> <code>(ids == integer.valueof(tfuid)) {</code>
<code> </code><code>}</code><code>else</code> <code>if</code> <code>(ids == integer.valueof(userinfomation</code>
<code>3</code><code>:</code>
<code> </code><code>int</code> <code>idsx = integer.valueof(messagelist.get(i).getttmtuid());</code>
<code> </code><code>if</code> <code>(idsx == integer.valueof(tfuid)) {</code>
<code> </code><code>}</code><code>else</code> <code>if</code> <code>(idsx == integer.valueof(userinfomation</code>
<code>5</code><code>:</code>
<code>6</code><code>:</code>
<code> </code><code>int</code> <code>idsxx = integer.valueof(messagelist.get(i).getttmtuid());</code>
<code> </code><code>if</code> <code>(idsxx == integer.valueof(tfuid)) {</code>
<code> </code><code>}</code><code>else</code> <code>if</code> <code>(idsxx == integer.valueof(userinfomation</code>
<code>}</code>
之前在測試中,用socket實作不了長連接配接。主要是因為不加上 socket.shutdownoutput();就收不到消息,而加上了即接收完消息斷了連接配接。是以每隔10秒就要通路次socket伺服器
<code> </code><code>socket =</code><code>new</code> <code>socket(constants.socket_ip, constants.socket_port);</code>
<code> </code><code>if</code>
<code>(socket.isconnected()) {</code>
<code>out =</code><code>new</code> <code>printwriter(</code><code>new</code> <code>bufferedwriter(</code>
<code> </code><code>new</code>
<code>outputstreamwriter(socket.getoutputstream())),</code><code>true</code><code>);</code>
<code>out.write(</code><code>"lgn|"</code><code>+</code>
<code> </code><code>userinfomation.getuserid(talkmessageserver.</code><code>this</code><code>)+</code><code>"|"</code><code>+</code>
<code> </code><code>userinfomation.getuserpw(talkmessageserver.</code><code>this</code><code>));</code>
<code>out.flush();</code>
<code> </code><code>socket.shutdownoutput();</code>
<code> </code><code>reader =</code><code>new</code> <code>bufferedreader(</code><code>new</code>
<code>inputstreamreader(</code>
<code> </code><code>socket.getinputstream()));</code>
<code> </code><code>while</code>
<code>((line = reader.readline()) !=</code><code>null</code><code>) {</code>
<code> </code><code>if</code> <code>(line !=</code>
<code>null</code><code>) {</code>
<code> </code><code>//截取字元,讀取資訊的操作</code>
雖然實作了,但在實際的應用中,效果不好。費電,丢包。
當然了,現在正在往長連接配接方向該,也修改了通信協定(很規範),(socketchannel,selector)
最後放上源碼
mb, 下載下傳次數: 5691)