简体   繁体   中英

Android Smack chat with openfire server

Hey every one i have some problems with my code for chat using openfire servr and android Smack and i have some errors in my log cat. i just wanaa simple code for connection becuse i dont know what's get worng in my code .. here is my code :

package com.exm.dor;

import java.util.ArrayList;
import java.util.List;

import org.jivesoftware.smack.*;
import org.jivesoftware.smack.filter.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.ConnectionConfiguration;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.*;

public class MainActivity extends Activity {
private final static String SERVER_HOST = "10.0.2.2";
private final static int SERVER_PORT = 5222;
private final static String SERVICE_NAME = "search.drcode"; 
private final static String LOGIN = "dorperezz";
private final static String PASSWORD = "123123";


private List<String> m_discussionThread;
private ArrayAdapter<String> m_discussionThreadAdapter;
private XMPPConnection m_connection;
private Handler m_handler;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    m_handler = new Handler();
    try {
        initConnection();
    } catch (XMPPException e) {
        e.printStackTrace();
    }

    final EditText recipient = (EditText) this.findViewById(R.id.recipient);
    final EditText message = (EditText) this.findViewById(R.id.message);        
    ListView list = (ListView) this.findViewById(R.id.thread);

    m_discussionThread = new ArrayList<String>();
    m_discussionThreadAdapter = new ArrayAdapter<String>(this,
            R.layout.multi_line_list_item, m_discussionThread);
    list.setAdapter(m_discussionThreadAdapter);

    Button send = (Button) this.findViewById(R.id.send);
    send.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            String to = recipient.getText().toString();
            String text = message.getText().toString();

            Message msg = new Message(to, Message.Type.chat);
            msg.setBody(text);
            m_connection.sendPacket(msg);
            m_discussionThread.add("moi :");
            m_discussionThread.add(text);
            m_discussionThreadAdapter.notifyDataSetChanged();
        }
    });
}


private void initConnection() throws XMPPException {
    //Initialisation de la connexion
    ConnectionConfiguration config =
            new ConnectionConfiguration(SERVER_HOST, SERVER_PORT, SERVICE_NAME);
    m_connection = new XMPPConnection(config);
    m_connection.connect();
    m_connection.login(LOGIN, PASSWORD);
    Presence presence = new Presence(Presence.Type.available);
    m_connection.sendPacket(presence);

    //enregistrement de l'יcouteur de messages
    PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
    m_connection.addPacketListener(new PacketListener() {
            public void processPacket(Packet packet) {
                Message message = (Message) packet;
                if (message.getBody() != null) {
                    String fromName = StringUtils.parseBareAddress(message
                            .getFrom());
                    m_discussionThread.add(fromName + ":");
                    m_discussionThread.add(message.getBody());

                    m_handler.post(new Runnable() {
                        public void run() {
                            m_discussionThreadAdapter.notifyDataSetChanged();
                        }
                    });
                }
            }
        }, filter);
}

}

here is the logcat:

10-15 11:23:16.665: E/AndroidRuntime(1986): FATAL EXCEPTION: main
10-15 11:23:16.665: E/AndroidRuntime(1986): Process: com.drcode.youplay, PID: 1986
10-15 11:23:16.665: E/AndroidRuntime(1986): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.drcode.youplay/com.drcode.youplay.MainActivity}: android.os.NetworkOnMainThreadException
10-15 11:23:16.665: E/AndroidRuntime(1986):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at android.app.ActivityThread.access$800(ActivityThread.java:135)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at android.os.Handler.dispatchMessage(Handler.java:102)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at android.os.Looper.loop(Looper.java:136)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at android.app.ActivityThread.main(ActivityThread.java:5017)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at java.lang.reflect.Method.invokeNative(Native Method)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at java.lang.reflect.Method.invoke(Method.java:515)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at dalvik.system.NativeStart.main(Native Method)
10-15 11:23:16.665: E/AndroidRuntime(1986): Caused by: android.os.NetworkOnMainThreadException
10-15 11:23:16.665: E/AndroidRuntime(1986):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at libcore.io.IoBridge.connect(IoBridge.java:112)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at java.net.Socket.connect(Socket.java:843)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at java.net.Socket.connect(Socket.java:786)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at org.jivesoftware.smack.proxy.DirectSocketFactory.createSocket(DirectSocketFactory.java:28)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at org.jivesoftware.smack.XMPPConnection.connectUsingConfiguration(XMPPConnection.java:550)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:991)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at com.drcode.youplay.MainActivity.initConnection(MainActivity.java:74)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at com.drcode.youplay.MainActivity.onCreate(MainActivity.java:38)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at android.app.Activity.performCreate(Activity.java:5231)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
10-15 11:23:16.665: E/AndroidRuntime(1986):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)

Try this way,hope this will help you to solve your problem.

Use AsyncTask which makes your network call on different thread(in background) rather than on app's main thread.

public class MainActivity extends Activity {
    private final static String SERVER_HOST = "10.0.2.2";
    private final static int SERVER_PORT = 5222;
    private final static String SERVICE_NAME = "search.drcode";
    private final static String LOGIN = "dorperezz";
    private final static String PASSWORD = "123123";


    private List<String> m_discussionThread;
    private ArrayAdapter<String> m_discussionThreadAdapter;
    private XMPPConnection m_connection;
    private EditText recipient;
    private EditText message;
    private ListView list;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        recipient = (EditText) this.findViewById(R.id.recipient);
        message = (EditText) this.findViewById(R.id.message);
        list = (ListView) this.findViewById(R.id.thread);


        new ConnectToXmpp().execute();
        Button send = (Button) this.findViewById(R.id.send);
        send.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                String to = recipient.getText().toString();
                String text = message.getText().toString();

                Message msg = new Message(to, Message.Type.chat);
                msg.setBody(text);
                m_connection.sendPacket(msg);
                m_discussionThread.add("moi :");
                m_discussionThread.add(text);
                m_discussionThreadAdapter.notifyDataSetChanged();
            }
        });
    }

    class ConnectToXmpp extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {
            try {
                ConnectionConfiguration config = new ConnectionConfiguration(SERVER_HOST, SERVER_PORT, SERVICE_NAME);
                m_connection = new XMPPConnection(config);
                m_connection.connect();
                m_connection.login(LOGIN, PASSWORD);
                Presence presence = new Presence(Presence.Type.available);
                m_connection.sendPacket(presence);

                PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
                m_connection.addPacketListener(new PacketListener() {
                    public void processPacket(Packet packet) {
                        Message message = (Message) packet;
                        if (message.getBody() != null) {
                            String fromName = StringUtils.parseBareAddress(message
                                    .getFrom());
                            m_discussionThread.add(fromName + ":");
                            m_discussionThread.add(message.getBody());
                            m_discussionThreadAdapter.notifyDataSetChanged();
                        }
                    }
                }, filter);
            } catch (XMPPException e) {
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            m_discussionThread = new ArrayList<String>();
            m_discussionThreadAdapter = new ArrayAdapter<String>(this,R.layout.multi_line_list_item, m_discussionThread);
            list.setAdapter(m_discussionThreadAdapter);
        }

    }
}
Caused by: android.os.NetworkOnMainThreadException

This is your problem. You are connecting socket on main thread. Try creating a global service an connect socket in that.

Also you can provide a retry policy for that thing. You can also search for open source project from github which do the whole task. You can add the required code for the projects for more reliable way coz your code will not stand production challenges.

Adding a reference https://github.com/siacs/Conversations

Jsut add this line onCreate() after setContentView() :

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

StrictMode.setThreadPolicy(policy); 

I think so it will solve your problem

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM