2012年6月16日 星期六

方法,XMPP的Demo

這是最近念念不忘了的XMPP,想要試著利用這來多點應用。

關於XMPP的介紹,不多說,參考這裡

這裡有比較詳細的介紹,還滿詳細的。

然後實做了一個App,是綁定Google Talk進行聊天用的:
這是載點

發現了幾點:

  1. 不能夠和自己聊天。也就是兩台機器登入同樣的帳號沒辦法互相傳遞訊息。
    這真的很殘念呀!
    通常用戶都會安裝google相關App,如果要透過XMPP頻繁的傳送data的話,
    登入自己的帳號,這樣傳送會一直有默認的通知產生,很麻煩的。
    而且,如果登入自己的帳號,互傳時必須要與傳送方加入google talk的通訊錄。
  2. 如果我想要頻繁傳送data又必須解決通訊錄名單的問題的話,也許我可以自己創造一個server,似乎可以用Openfire?相關設定參考這裡。載點在這裡


參考的API,在這裡
而其中lib和相關server的載點,參考這裡

這次我比較用心,裡面有較為詳細的註解,請笑納:

package demoXMPP.demo.idea;

import java.util.ArrayList;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.util.StringUtils;

import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

public class XMPPClient extends Activity implements MessageListener {

    private ArrayList<String> messages;// 文字暫存的列表
    private Handler mHandler = new Handler();
    private EditText mRecipient;// 傳送文字對象的帳號
    private EditText mSendText;// 傳送文字的內容
    private ListView mList;// 顯示文字的列表
    private XMPPConnection connection;// XMPP的連接物件
    private ArrayAdapter<String> adapter;// ListView的adapter

    /**
     * Called with the activity is first created.
     * 簡單操作介紹:http://www.cnblogs.com/zhangdongzi/archive/2012/01/11/2320021.html
     */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);
        // --初始化---
        messages = new ArrayList<String>();
        mRecipient = (EditText) this.findViewById(R.id.recipient);
        mSendText = (EditText) this.findViewById(R.id.sendText);
        mList = (ListView) this.findViewById(R.id.listMessages);
        setOrRefreshListAdapter();
        Button send = (Button) this.findViewById(R.id.send);
        // --初始化---
        send.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                // 按下傳送,讀取文字,讀取傳送對象,送出文字
                StringBuffer temp = new StringBuffer();
                temp.append(mRecipient.getText().toString());
                if (temp.indexOf("@") == -1) {
                    temp.append("@gmail.com");
                }// 因為讀取對象需要完整mail帳號,如果只輸入帳號則添加後面的@...
                String to = temp.toString();
                String text = mSendText.getText().toString();
                Message msg = new Message(to, Message.Type.chat);// 產生送出文件
                msg.setBody(text);// 設定文字內容
                connection.sendPacket(msg);// 送出文件
                
                messages.add(StringUtils.parseBareAddress(connection.getUser()) + " say: ");
                messages.add(text);// 準備本機在ListView的顯示內容。
                setOrRefreshListAdapter();// 更新列表
            }
        });
        setting();// 初始化設定登入帳號密碼
    }

    private void setOrRefreshListAdapter() {
        //如果是第一次則進行設定,之後則使用更新列表的指令。
        if (adapter == null) {
            adapter = new ArrayAdapter<String>(this,
                    R.layout.multi_line_list_item, messages);
            mList.setAdapter(adapter);
        } else
            adapter.notifyDataSetChanged();//更新列表

    }

    @Override
    public void processMessage(Chat chat, Message message) {
        // 處理接收到的值,將收到訊息更新在ListView上面
        Log.d("Test", "processMessage");
        if (message.getBody() != null) {
            String fromName = StringUtils.parseBareAddress(message.getFrom());//獲得傳送者的完整mail帳號
            messages.add(fromName + " said: ");
            messages.add(message.getBody());//添加訊息
            mHandler.post(new Runnable() {
                public void run() {
                    setOrRefreshListAdapter();//更新列表
                }
            });
        }
    }

    private void setting() {
        //產生對話視窗,需要輸入登入的各項資訊。
        Builder builder = new Builder(this);
        final View view = ((LayoutInflater) this
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
                R.layout.settings, null);
        builder.setView(view);
        builder.setPositiveButton(R.string.ok, new OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                String host = ((EditText) view.findViewById(R.id.host))
                        .getText().toString();// 獲取google talk host
                String port = ((EditText) view.findViewById(R.id.port))
                        .getText().toString();// 獲取google talk port
                String service = ((EditText) view.findViewById(R.id.service))
                        .getText().toString();// 獲取google talk service
                String username = ((EditText) view.findViewById(R.id.userid))
                        .getText().toString();// 獲取使用者的帳號
                String password = ((EditText) view.findViewById(R.id.password))
                        .getText().toString();// 獲取使用者的密碼
                if (username.indexOf("@") == -1) {
                    username = username + "@gmail.com";
                }// 在這邊只需要輸入帳號,會自動添加後面的@...

                ConnectionConfiguration connConfig = new ConnectionConfiguration(
                        host, Integer.parseInt(port), service);// 創立連結設定檔
                connection = new XMPPConnection(connConfig);// 創立連結

                try {
                    connection.connect();// 進行連結
                } catch (XMPPException ex) {
                    Log.e("Test", "XMPPException 錯誤:" + ex);
                }
                if (connection.isConnected()) {
                    //雖然說服務相關內容已經寫上去了,但是做個確保。如果出錯了會要求重新輸入
                    try {
                        connection.login(username, password);// 登入
                        // 將狀態設定為登入狀態
                        Presence presence = new Presence(
                                Presence.Type.available);
                        connection.sendPacket(presence);
                    } catch (XMPPException ex) {
                        Log.e("Test", "XMPPException 錯誤:" + ex);
                    }
                    if (connection.isAuthenticated()) {
                        connection.getChatManager().addChatListener(//設定監聽訊息
                                new ChatManagerListener() {
                                    @Override
                                    public void chatCreated(Chat chat,
                                            boolean createdLocally) {
                                        if (!createdLocally) {
                                            chat.addMessageListener(XMPPClient.this);//設置監聽實做
                                        }
                                    }
                                });
                    } else
                        failMsg();
                } else
                    failMsg();
            }
        });
        builder.show();
    }

    //錯誤訊息實做
    private void failMsg() {
        Toast.makeText(getApplicationContext(), R.string.not_connection,
                Toast.LENGTH_LONG).show();
        setting();
    }
}







沒有留言:

張貼留言

你好,我是小書,如果文章內容有錯誤,或是看到有建議以及任何感想時,歡迎提出分享,我們一起學習一起努力。

追蹤者