最進開始做一些android的項目,除了一個新聞客戶端的搭建,還需要一個實現一個即時通訊的功能,參考了很多大神成型的實例,了解到operfire+asmack是搭建簡易即時通訊比較方便,所以就寫了這篇博客。
一、基礎知識(這是復制別人的)
XMPP協議簡介
XMPP協議(Extensible Messaging and PresenceProtocol,可擴展消息處理現場協議)是一種基於XML的協議,目的是為了解決及時通信標准而提出來的,最早是在Jabber上實現的。它繼承了在XML環境中靈活的發展性。因此,基於XMPP的應用具有超強的可擴展性。並且XML很易穿過防火牆,所以用XMPP構建的應用不易受到防火牆的阻礙。利用XMPP作為通用的傳輸機制,不同組織內的不同應用都可以進行有效的通信。
這篇文章有基本的介紹,http://blog.csdn.net/xutaozero21/article/details/4873439
IM
Instant Messenger,及時通信軟件,就是大家使用的QQ、MSN Messenger和Gtalk等等。其中Gtalk 就是基於XMPP 協議的一個實現,其他的則不是。當前IM 幾乎作為每個上網者必然使用的工具,在國外的大型企業中有一些企業級的IM應用,但是其商業價值還沒完全發揮出來。設想既然XMPP 協議是一個公開的協議,那么每個企業都可以利用它來開發適合本身企業工作,提高自身生產效率的IM;甚至,你還可以在網絡游戲中集成這種通信軟件,不但讓你可以邊游戲邊聊天,也可以開發出適合游戲本身的IM 應用,比如說一些游戲關鍵場景提醒功能,團隊語音交流等等都可以基於IM來實現。
本文主要講解在android使用xmpp協議進行即時通信,所涉及3個主要的東西,它們是openfire、smack和spark,這個三個東東結合起來就是完整的xmpp IM實現,這里簡單介紹一下這3個東東在下文的作用:
openfire主要是作為服務器,負責管理客戶端的通信連接,以及提供客戶端一些通信信息和連接信息。
Smack主要是xmpp協議的實現,提供了一套很好的api,所以下面操作xmpp都是通過使用smack的api來實現,當然因為是在android里,所以使用的是asmack這個包,里面方法跟smack包差不多。
Spark 是IM客戶端的實現,其實就是使用了smack 的api實現的。
Openfire的安裝和配置:
可參考http://www.cnblogs.com/hoojo/archive/2012/05/17/2506769.html
二、實現第一步登錄
做好了一系列的前期准備之后我們就能看到這樣的用戶后台管理了,其中注冊了兩個用戶用來測試。
1.首先可以搭建簡易的樣式:
夠丑吧=-=
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <TextView android:id="@+id/textview" android:text="@string/hello_world" android:textSize="48dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TableLayout android:layout_below="@id/textview" android:id="@+id/tablelayout" android:layout_width="match_parent" android:layout_height="wrap_content"> <TableRow> <TextView android:layout_height="wrap_content" android:text="Name:" /> <EditText android:id="@+id/login_name" android:hint="Input your Name " android:layout_height="wrap_content" /> </TableRow> <TableRow> <TextView android:layout_width="wrap_content" android:text="Password:" /> <EditText android:id="@+id/login_password" android:hint="Input your Password " android:layout_height="wrap_content" /> </TableRow> </TableLayout> <Button android:id="@+id/buttonlogin" android:layout_below="@id/tablelayout" android:layout_width="wrap_content" android:layout_height="48dp" android:text="login in"/> </RelativeLayout>
一個標題,兩個輸入,一個Login in的按鈕夠簡單吧!!
2.代碼實現:
首先將一些要用的方法封裝到工具類里。
1 public class connect { 2 private static ConnectionConfiguration connConfig; 3 private static XMPPConnection con; 4 5 public static XMPPConnection getConnection() {//獲取連接 6 if (con == null || !con.isConnected()) { 7 openConnection(); 8 } 9 return con; 10 } 11 public static boolean openConnection() {//連接方法 12 try { 13 connConfig = new ConnectionConfiguration("192.168.252.1", 5222); //5222是客戶端和服務端的連接端口,其中的ip是我的內網ip 15 // 設置登錄狀態為離線 16 connConfig.setSendPresence(false); 17 // 斷網重連 18 connConfig.setReconnectionAllowed(true); 19 con = new XMPPConnection(connConfig); 20 con.connect(); 21 return true; 22 } catch (Exception e) { 23 // TODO: handle exception 24 } 25 return false; 26 } 27 public static void closeConnection() {//斷開連接 28 con.disconnect(); 29 }
1 public static boolean login(String account, String password) { 2 try { 3 if (connect.getConnection() == null) 4 return false; 5 /** 登錄 */ 6 SASLAuthentication.supportSASLMechanism("PLAIN", 0); 7 connect.getConnection().login(account, password); 8 // 設置登錄狀態:在線 9 // Presence presence = new Presence(Presence.Type.available); 10 // connect.getConnection().sendPacket(presence); 11 return true; 12 } catch (Exception e) { 13 e.printStackTrace(); 14 } 15 return false; 16 }
1 public class MainActivity extends ActionBarActivity implements View.OnClickListener {//主函數 2 public static final int FAIL_CON=0; 3 public static final int SUCC_CON=0; 4 private String Tag = "MainAcy"; 5 private String account; 6 private String pwd; 7 @Override 8 protected void onCreate(Bundle savedInstanceState) { 9 super.onCreate(savedInstanceState); 10 setContentView(R.layout.activity_main); 11 12 //綁定按鈕 13 findViewById(R.id.buttonlogin).setOnClickListener(this); 14 15 } 16 17 private android.os.Handler insHandler = new android.os.Handler() { 18 public void handleMessage(android.os.Message msg) { 19 switch (msg.what) { 20 // 登錄成功 21 case 1: 22 Toast.makeText(MainActivity.this,"SUCCESS",Toast.LENGTH_SHORT).show(); 23 Log.d(Tag, "login suc");
//跳轉頁面 24 Intent intent=new Intent(); 25 intent.putExtra("usename", account);
//傳值 26 intent.setClass(MainActivity.this, useractivity.class); 27 startActivity(intent); 28 break; 29 case 0: 30 Toast.makeText(MainActivity.this,"FAIL",Toast.LENGTH_SHORT).show(); 31 Log.d(Tag, "login fail"); 32 accountLogin(); 33 default: 34 break; 35 } 36 } 37 }; 38 39 private void accountLogin() { 40 new Thread() { 41 public void run() { 42 account = ((EditText) findViewById(R.id.login_name)) 43 .getText().toString(); 44 pwd = ((EditText) findViewById(R.id.login_password)).getText() 45 .toString(); 46 boolean is = ConnecMethod.login(account, pwd); 47 if (is) { 48 insHandler.sendEmptyMessage(1); 49 // 保存用戶名 50 user.UserName = account; 51 } else { 52 insHandler.sendEmptyMessage(0); 53 } 54 }; 55 }.start(); 56 } 57 58 @Override 59 public void onClick(View v) { 60 // TODO Auto-generated method stub 61 switch (v.getId()) { 62 case R.id.buttonlogin: 63 accountLogin(); 64 default: 65 break; 66 } 67 } 68 }
我們為下一個頁面傳遞了一個值就是我們登陸的用戶名,所以在用戶頁面要:
1 @Override 2 protected void onCreate(Bundle savedInstanceState) { 3 super.onCreate(savedInstanceState); 4 setContentView(R.layout.useractivity); 5 Intent intent =getIntent(); 6 String username=intent.getStringExtra("usename");//接收用戶名 7 TextView textView= (TextView) findViewById(R.id.username);再體現在用戶頁的一個textiew里 8 textView.setText(username); 9 connect.closeConnection();
//使用的連接服務要在登錄成功后,即時銷毀,否則下一次就會登陸錯誤。 10 }
這就是第一步的完成,近期不忙就會做下一步的完成。