Chat works only one-way with Smack 4.1.7 Android

2019-07-17 18:19发布

问题:

I am working on Android Chat app based on Smack 4.1.7. I have created my XMPP related operations on Saperate class said MyXMPP.java. and in my app's Application class i am initializing MyXMPP class objects.

my problem is, suppose we have user 1 and user 2. if user 1 sends message to user 2 then user 2 can get message but cant reply back. means if user 2 trying to reply then user 1 can not get user 2's reply.

in short if user 1 initiates chatting then, only user 1 can send message. user 2 can not send message to user 1 same Vice versa.

my codes are as below,

MyXMPP.java

    public class MyXMPP {

    static Context context;
    static XMPPTCPConnectionConfiguration.Builder xmppConfig;
    static XMPPTCPConnection connection;
    static MyXMPP myXMPP = null;
    static Chat chat;
    Roster roster;
    ArrayList<Rosters> rosters;
    static ChatManager chatManager;

    static Application app;

    public static synchronized MyXMPP getInstance(Context c) {

        app = (Application) c.getApplicationContext();
        context = c;
        if (myXMPP == null) {
            myXMPP = new MyXMPP();
            xmppConfig = XMPPTCPConnectionConfiguration.builder();
            xmppConfig.setResource(Constants.RESOURCE);
            xmppConfig.setServiceName(Constants.SERVICE_NAME);
            xmppConfig.setPort(Constants.PORT);
            xmppConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
        }

        return myXMPP;
    }

    public static synchronized AbstractXMPPConnection getConnectXMPP() {

        try {
            xmppConfig.setUsernameAndPassword(Constants.USERNAME, Constants.PASSWORD);
            XMPPTCPConnection.setUseStreamManagementDefault(true);
            connection = new XMPPTCPConnection(xmppConfig.build());
            connection.setUseStreamManagement(true);
            connection.connect().login();
            connection.requestSmAcknowledgement();
        } catch (SmackException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (XMPPException e) {
            e.printStackTrace();
        }

        return connection;
    }

    public static ChatManager getChatManager() {

        if (chatManager == null) {
            chatManager = ChatManager.getInstanceFor(app.connection);
        }
        return chatManager;
    }


    public ArrayList<Rosters> getRosters() {

        rosters = new ArrayList<>();

        roster = Roster.getInstanceFor(app.connection);

        if (!roster.isLoaded())
            try {
                roster.reloadAndWait();

            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (SmackException.NotLoggedInException e) {
                e.printStackTrace();
            } catch (SmackException.NotConnectedException e) {
                e.printStackTrace();
            }

        //Get Roster Entry list
        Set<RosterEntry> rosterEntries = roster.getEntries();
        Debug.e("entry size", "" + rosterEntries.size());
        for (final RosterEntry entry : rosterEntries) {
            /*
             build List<> for roster entry with roster
                            ---or---
             if it is in activity or in fragment then add both items (entry,roster) to adapter
             */
            Rosters rosterItem = new Rosters();
            rosterItem.entry.add(entry);
            rosterItem.roster.add(roster);
            rosters.add(rosterItem);
        }

        return rosters;

    }

    public void initChatManager() {

        if (chatManager == null) {
            chatManager = getChatManager();
        }

        chatManager.addChatListener(new ChatManagerListener() {

            @Override
            public void chatCreated(Chat chat, boolean createdLocally) {

                MyXMPP.chat = chat;

                if (!createdLocally) {

                    chat.addMessageListener(new ChatMessageListener() {
                        @Override
                        public void processMessage(Chat chat, Message message) {
                            Debug.e("Chat obj", chat.toString());
                            if (message != null || !message.getBody().equalsIgnoreCase(null) || !message.getBody().equalsIgnoreCase("")) {
                                if (message.getBody() == null || message.getBody().equals(null)) {
                                } else {
                                    Debug.e("Message aala", "" + message.getBody());
                                }

                            } else {
                                Debug.e("message null", "Message Null");
                            }
                        }
                    });
                } else {
                    Debug.e("MY MSG", chat.getParticipant());
                }
            }
        });
    }

    public void sendMessage(String to, String msg) {

        Chat newChat = app.myXMPP.getChatManager().createChat(to, new ChatMessageListener() {
            @Override
            public void processMessage(Chat chat, Message message) {
                System.out.println("Received message: " + message);
            }
        });

        try {
            Message message = new Message();
            message.setFrom(connection.getUser());
            message.setTo("xyz@myhostaddress.com");
            message.setBody("My Message");
            newChat.addMessageListener(new ChatMessageListener() {
                @Override
                public void processMessage(Chat chat, Message message) {
                    Debug.e("send msg listener", message.getBody());
                }
            });
            newChat.sendMessage(message);
        } catch (SmackException.NotConnectedException e) {
            e.printStackTrace();
        }
    }
  }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    Application app;
    Button btn;
    String threadId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn = (Button) findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                app.myXMPP.sendMessage("xyz@myhost.com", "hello");
            }
        });

        //Get Application data access
        app = (Application) getApplicationContext();

        //Establish Connection and Login
        new XMPPOperations().execute();
    }

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

        @Override
        protected Void doInBackground(Void... params) {

            if (app.connection == null || !app.connection.isConnected()) {
                app.connection = app.myXMPP.getConnectXMPP();
                Debug.e("Connection in activity", "" + app.connection.isConnected());
            }
            app.myXMPP.getRosters();

            app.myXMPP.initChatManager();

            return null;
        }
    }
}

Application.java

public class Application extends android.app.Application {

    public MyXMPP myXMPP;
    public AbstractXMPPConnection connection;

    @Override
    public void onCreate() {
        super.onCreate();

        myXMPP = MyXMPP.getInstance(this);
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        Presence p = new Presence(Presence.Type.unavailable);
        try {
            connection.sendStanza(p);
        } catch (SmackException.NotConnectedException e) {
            e.printStackTrace();
        }
    }
}