android实现xmppconnection服务

时间:2013-03-23 14:28:10

标签: android service xmpp asmack

我正在尝试使用asmack和Openfire创建一个基本的聊天应用。 我已经为XMPPConnection创建了一个绑定服务,每个Activity都绑定到它。

每当我尝试绑定到服务时,都会有很长的延迟。我知道bindService是异步的,但我想确定在我开始寻找其他问题之前我的服务实现是正确的。

我在onCreate方法中绑定了我的服务,并尝试访问onStart中的连接。

我还是新手,但我怀疑我做错了一些错误。我的app现在运行的方式,只有当我尝试从OnClickListener访问它时,mBound变量才返回true。听众中发生了什么事情会产生如此大的影响?我试图找到OnClick方法的代码,但我找不到它。

我的XMPPConnectionService是这样的:

package com.example.smack_text;

import java.io.File;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class XMPPService extends Service{

XMPPConnection connection;
//  private final IBinder mBinder = new LocalBinder();


@Override
public void onCreate(){
super.onCreate();
Log.d("service","created");
}

/**
 * Class used for the client Binder.  Because we know this service always
 * runs in the same process as its clients, we don't need to deal with IPC.
 */
@Override
public IBinder onBind(Intent intent) {
Log.d("sevice","bound");
LocalBinder mBinder = new LocalBinder (this);
return mBinder;
}

public class LocalBinder extends Binder {
XMPPService service;

public LocalBinder (XMPPService service)
{
this.service = service;
}

public XMPPService getService (){
return service;
}

//          XMPPService getService() {
//              return XMPPService.this;
//          }
}

public void connect(final String user, final String pass) {
Log.d("Xmpp Alex","in service");

ConnectionConfiguration config = new ConnectionConfiguration("10.0.2.2",5222);

//          KEYSTORE SETTINGS
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
config.setTruststoreType("AndroidCAStore");
config.setTruststorePassword(null);
config.setTruststorePath(null);
} 
else {
config.setTruststoreType("BKS");
String path = System.getProperty("javax.net.ssl.trustStore");
if (path == null)
path = System.getProperty("java.home") + File.separator + "etc"
       + File.separator + "security" + File.separator
       + "cacerts.bks";
    config.setTruststorePath(path);
} 

//          Create XMPP Connection

connection = new XMPPConnection(config);

new Thread(new Runnable() {
@Override
public void run() {

try {
connection.connect();
connection.login(user, pass);
if(connection.isConnected()){
Log.d("Alex", "connected biatch!");
}
else{
Log.d("Alex","not connected");
}


} catch (XMPPException e) {
e.printStackTrace();
}
}
}).start();
}
public void disconnect(){
if(connection.isConnected()){
connection.disconnect();
}  
else{
Toast.makeText(getApplicationContext(), "not connected", Toast.LENGTH_LONG).show();
}
}
}

2 个答案:

答案 0 :(得分:2)

我与Asmack实施Android聊天。

我创建了一个服务。 该服务具有XmppConnection的全局变量。 在开始时我使用线程进行连接和登录。 然后我为登录用户设置VCard,设置rosterListener 最后设置connection.addPacketListener 我使用BroadcastReceiver活动端和

更新活动
@Override
    public IBinder onBind(Intent arg0) {

        return mBinderXmpp;
    }

    public class BinderServiceXmpp extends Binder {
        ServiceXmpp getService() {
            return ServiceXmpp.this;
        }
    }


    private Runnable sendUpdatesToUI = new Runnable() {
        public void run() {
            DisplayInfo();
            handler.postDelayed(this, 2000); // 2 segundos
        }
    };
    private void DisplayInfo() {
        isRunning = true; // flag to know if service is running
        Intent tempIntent;
        tempIntent = new Intent(BROADCAST_ACTION);
        tempIntent.putExtra("UPDATE_OPTION", UPDATE_ACTION);
        sendBroadcast(tempIntent);


    }

答案 1 :(得分:0)

您的实现有效,您仍然需要为客户端绑定的CONNECT和DISCONNECT等操作实现处理程序(例如LoginActivity)。

示例:

class IncomingHandler extends Handler { // Handler of incoming messages from clients bound.
    @Override
    public void handleMessage(android.os.Message msg) {
        switch (msg.what) {
            case MSG_CONNECT_XMPP:
                new AsyncTask<Void, Void, Boolean>(){
                    @Override
                    protected Boolean doInBackground(Void... params) {
                        // Do connection
                    }

                    @Override
                    protected void onPostExecute(Boolean aBoolean) {
                        // Notify the connection status
                    }
                }.execute();
                break;
            case MSG_DICCONNECT_XMPP:
                new AsyncTask<Void, Void, Boolean>(){
                    @Override
                    protected Boolean doInBackground(Void... params) {
                        // Do disconnection
                    }

                    @Override
                    protected void onPostExecute(Boolean aBoolean) {
                        // Notify the connection status
                    }
                }.execute();

                break;
            default:
                super.handleMessage(msg);
        }
    }
}

但是,这种在服务需要运行网络动作时创建AsyncTask的方法将达到BroadcastReceiver中sendBroadcast的限制。

如果您有需要通过向XMPPService发送消息来启动或停止连接的BroadcastReceiver,您可以这样:

public class NetworkConnectivityReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        NetworkInfo network = cm.getActiveNetworkInfo();

        network = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);

        if (XmppService.isRunning() && network.isConnected()) {
            context.sendBroadcast(new Intent(XmppService.ACTION_CONNECT));
        } else if (XmppService.isRunning() && !network.isConnected()) {
            context.sendBroadcast(new Intent(XmppService.ACTION_DISCONNECT));
        }
    }
}

然后,您需要在XmppService类中实现Broadcast侦听器。 但是,您不能在Broadcast侦听器中运行AsyncTask!

剩余选项在我的帖子中描述:

Android - Best option to implement Networking Class