Sending and Receiving messages using Smack Api for Android
Asked Answered
C

1

8

I'm trying since last four days to send and receive chat message using own XMPP and with Smack+OpenFire. According to Smack's "readme.txt' i set up the connection and got logged user in. The code of connection and login is this

public static String TAG = "Test connection";
private static XMPPTCPConnection connection;
private static String userName = "demo";
private static String Password = "demo";

static {
    // Create the configuration for this new connection
    XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
    configBuilder.setSecurityMode(XMPPTCPConnectionConfiguration.SecurityMode.disabled);
    configBuilder.setResource("");
    configBuilder.setUsernameAndPassword(userName, Password);
    configBuilder.setServiceName("192.168.2.10");
    configBuilder.setHost("192.168.2.10");
    configBuilder.setPort(5222);
    configBuilder.setCompressionEnabled(false);
    connection = new XMPPTCPConnection(configBuilder.build());
}

This way i configured the connectionbuilder. here i am connecting and signing in the user.

public class ConnectAndLogin extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... params) {
        try {
            connection.connect();
            Log.i(TAG, "Connected to " + connection.getHost());
        } catch (SmackException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (XMPPException e) {
            Log.e(TAG, "Failed to connect to " + connection.getHost());
            Log.e(TAG, e.toString());
            e.printStackTrace();
        }

        try {
            connection.login(userName, Password);
            Log.i(TAG, "Login as a : " + connection.getUser());
            setConnection(connection);
            setListner();
        } catch (XMPPException e) {
            e.printStackTrace();
            Log.i(TAG, "Login error " + e.toString());
        } catch (SmackException e) {
            e.printStackTrace();
            Log.i(TAG, "Login error " + e.toString());
        } catch (IOException e) {
            e.printStackTrace();
            Log.i(TAG, "Login error " + e.toString());
        }


        return null;
    }
}

In some tutorials that the addPacketListner must be set after login. i done that in setConnection() and some posts went through addAsyncStanzaListner. for send message

send.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Message msg = new Message("demo2", Message.Type.chat);
            msg.setBody("Hi how are you");
            if (connection != null) {
                try {
                    connection.sendPacket(msg);
                    Log.d("Send to room  : Name : ", "demo2");
                    Log.d("store", "store data to db");
                    //DBAdapter.addUserData(new UserData(text, "", "1" ,beam_id));
                } catch (Exception e) {
                    Log.d("ooo", "msg exception" + e.getMessage());
                }
            }
        }
    });

and for receiving messages this code

 public void setListner() {
    connection.addAsyncStanzaListener(new StanzaListener() {
        @Override
        public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
            Message message = (Message) packet;
            Log.i(TAG, "REC : " + message.getBody());
            Log.i(TAG, "REC: " + message.getFrom());


        }

    }, new StanzaFilter() {
        @Override
        public boolean accept(Stanza stanza) {
            return false;
        }
    });
}

here is my dependencies

 compile 'org.igniterealtime.smack:smack-android:4.1.0'
compile 'org.igniterealtime.smack:smack-tcp:4.1.0'
compile 'org.igniterealtime.smack:smack-core:4.1.0'
compile 'org.igniterealtime.smack:smack-im:4.1.0'
compile 'org.igniterealtime.smack:smack-resolver-minidns:4.1.0'
compile 'org.igniterealtime.smack:smack-sasl-provided:4.1.0'

But still i'm not able to send messages to demo2 user. Where im doing wrong.Please guide and help me. Thanks

Cabinetwork answered 5/11, 2015 at 17:38 Comment(3)
Are you getting any errorHorselaugh
if you get 100 messages at a time in smack . are you able to get them all in order as they are sent from the server ?Frontolysis
didn't try this way.Cabinetwork
C
12

After long time now i can send text message and even images. this is my complete code to that handle the XmppConnection.

public class SmackConnection implements ConnectionListener, ChatManagerListener, RosterListener, ChatMessageListener, PingFailedListener {

private Gson gson;
private AsyncTask<Void, Void, Void> mRegisterTask;
private FileTransferManager manager;
private static final String TAG = "SMACK";
public static Context mApplicationContext;
public static SmackConnection instance = null;
private final String mServiceName = "192.168.2.3";
private static XMPPTCPConnection mConnection;
private static final byte[] dataToSend = StringUtils.randomString(1024 * 4 * 3).getBytes();
private static byte[] dataReceived;
private XMPPTCPConnectionConfiguration.Builder config;

public void init(String mUsername, String mPassword) {
    Log.i(TAG, "connect()");
    config = XMPPTCPConnectionConfiguration.builder();
    config.setServiceName(mServiceName);
    config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
    config.setHost(mServiceName);
    config.setPort(5222);
    config.setDebuggerEnabled(true);
    config.setResource("sender");
    config.setCompressionEnabled(true);
    config.setUsernameAndPassword(mUsername, mPassword);
    XMPPTCPConnection.setUseStreamManagementResumptiodDefault(true);
    XMPPTCPConnection.setUseStreamManagementDefault(true);
    config.setCompressionEnabled(true);
    try {
        TLSUtils.acceptAllCertificates(config);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    }
    mConnection = new XMPPTCPConnection(config.build());
    mConnection.addConnectionListener(this);
    PingManager pingManager = PingManager.getInstanceFor(mConnection);
    pingManager.registerPingFailedListener(this);
    ChatManager.getInstanceFor(mConnection).addChatListener(this);
    manager = FileTransferManager.getInstanceFor(mConnection);
    manager.addFileTransferListener(new FileTransferIMPL());
    FileTransferNegotiator.getInstanceFor(mConnection);

    gson = new Gson();
    connectAndLoginAnonymously();
}

public void connectAndLoginAnonymously() {
    mRegisterTask = new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                mConnection.connect();
                mConnection.login();
            } catch (SmackException | XMPPException | IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void res) {
        }
    };

    // execute AsyncTask
    mRegisterTask.execute(null, null, null);
}


public void login(final String username, final String password) {
    mRegisterTask = new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try {

                disconnect();
                config.setUsernameAndPassword(username, password);

                mConnection.connect();

                mConnection.login();

            } catch (SmackException | XMPPException | IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void res) {
        }
    };
    // execute AsyncTask
    mRegisterTask.execute(null, null, null);
}


public void disconnect() {
    Log.i(TAG, "disconnect()");
    if (mConnection != null) {
        mConnection.disconnect();
    }
}


public void sendMessage(ChatMessage chatMessage) {
    gson = new Gson();
    Log.i(TAG, "sendMessage()");
    Chat chat = ChatManager.getInstanceFor(mConnection).createChat(chatMessage.receiver + "@santosh-pc", this);
    Gson gson = new Gson();
    String body = gson.toJson(chatMessage);
    final Message message = new Message();
    message.setBody(body);
    message.setStanzaId(chatMessage.msgid);
    message.setType(Message.Type.chat);
    try {
        chat.sendMessage(message);
    } catch (SmackException.NotConnectedException e) {
        e.printStackTrace();
    }

}

@Override
public void chatCreated(Chat chat, boolean createdLocally) {
    Log.i(TAG, "chatCreated()");
    chat.addMessageListener(this);
}

//MessageListener
@Override
public void processMessage(Chat chat, Message message) {
    gson = new Gson();
    Log.i(TAG, "processMessage()");
    if (message.getType().equals(Message.Type.chat) || message.getType().equals(Message.Type.normal)) {
        Log.i("MyXMPP_MESSAGE_LISTENER", "Xmpp message received: '"
                + message);
        if (message.getType() == Message.Type.chat
                && message.getBody() != null) {
            String sender1 = message.getFrom();
            final Random random = new Random();
            final String delimiter = "\\@";
            String[] temp = sender1.split(delimiter);
            final String sender = temp[0];
            final ChatMessage chatMessage = gson.fromJson(message.getBody(), ChatMessage.class);
            chatMessage.msgid = " " + random.nextInt(1000);
            processMessage(sender, chatMessage);
        }
    }
}

public void processMessage(final String sender, ChatMessage chatMessage) {
    chatMessage.sender = sender;
    chatMessage.receiver = LoginSignupPage.self;
    chatMessage.type = "TEXT";
    chatMessage.isMine = false;
    Log.i("MSG RECE", chatMessage.getBody());
    ChatActivity.chatlist.add(chatMessage);
    CommonMethods commonMethods = new CommonMethods(mApplicationContext);
    commonMethods.createTable(sender);
    commonMethods.insertIntoTable(sender, sender, LoginSignupPage.self, "fdfd", "r", "TEXT");
    Log.i("MSG RECE", "Added");
    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            Log.i("MSG RECE", "LOOPER");
            ChatActivity.chatAdapter.notifyDataSetChanged();

        }
    });

}

private void processMessage(final FileTransferRequest request) {
    new Handler(Looper.getMainLooper()).post(new Runnable() {

        @Override
        public void run() {
            Log.i("MSG RECE", "LOOPER");
            Random random = new Random();
            CommonMethods commonMethods = new CommonMethods(mApplicationContext);
            int iend = request.getRequestor().lastIndexOf("@");
            String requester = request.getRequestor().substring(0, 10);
            commonMethods.createTable(requester);
            Log.i("MSG RECE", requester);
            commonMethods.insertIntoTable(requester, requester, LoginSignupPage.self, request.getFileName(), "r", "IMG");
            final ChatMessage chatMessage = new ChatMessage(LoginSignupPage.self, requester,
                    request.getFileName(), "" + random.nextInt(1000), false, "IMG");
            chatMessage.setMsgID();
            chatMessage.body = request.getFileName();
            chatMessage.Date = CommonMethods.getCurrentDate();
            chatMessage.Time = CommonMethods.getCurrentTime();
            chatMessage.type = "IMG";
            ChatActivity.chatlist.add(chatMessage);
            ChatActivity.chatAdapter.notifyDataSetChanged();
            Log.i("MSG RECE", request.getRequestor());

        }
    });


}


//ConnectionListener

@Override
public void connected(XMPPConnection connection) {

    Log.i(TAG, "connected()");
}

@Override
public void authenticated(XMPPConnection connection, boolean arg0) {
    Log.i(TAG, "authenticated()");
}

@Override
public void connectionClosed() {
    Log.i(TAG, "connectionClosed()");

}

@Override
public void connectionClosedOnError(Exception e) {
    Log.i(TAG, "connectionClosedOnError()");

}

@Override
public void reconnectingIn(int seconds) {
    Log.i(TAG, "reconnectingIn()");

}

@Override
public void reconnectionSuccessful() {
    Log.i(TAG, "reconnectionSuccessful()");
}

@Override
public void reconnectionFailed(Exception e) {
    Log.i(TAG, "reconnectionFailed()");
}

//RosterListener

@Override
public void entriesAdded(Collection<String> addresses) {
}

@Override
public void entriesUpdated(Collection<String> addresses) {
    Log.i(TAG, "entriesUpdated()");
}

@Override
public void entriesDeleted(Collection<String> addresses) {
    Log.i(TAG, "entriesDeleted()");
}

@Override
public void presenceChanged(Presence presence) {
    Log.i(TAG, "presenceChanged()");
}


@Override
public void pingFailed() {
    Log.i(TAG, "pingFailed()");
}


public boolean createNewAccount(String username, String newpassword) {
    boolean status = false;
    if (mConnection == null) {
        try {
            mConnection.connect();
        } catch (SmackException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (XMPPException e) {
            e.printStackTrace();
        }
    }

    try {
        String newusername = username + mConnection.getServiceName();
        Log.i("service", mConnection.getServiceName());
        AccountManager accountManager = AccountManager.getInstance(mConnection);
        accountManager.createAccount(username, newpassword);
        status = true;
    } catch (SmackException.NoResponseException e) {
        status = false;
        e.printStackTrace();
    } catch (XMPPException.XMPPErrorException e) {
        e.printStackTrace();
        status = false;
    } catch (SmackException.NotConnectedException e) {
        e.printStackTrace();
        status = false;
    }
    mConnection.disconnect();
    return status;

}

public XMPPTCPConnection getConnection() {
    return mConnection;
}

public SmackConnection(Context context) {
    mApplicationContext = context;
}

public SmackConnection() {
}

public XMPPTCPConnection SmackConnection() {
    return mConnection;

}

public static SmackConnection getInstance(Context context) {
    if (instance == null) {
        instance = new SmackConnection(context);
        mApplicationContext = context;
    }
    return instance;
}

public class FileTransferIMPL implements FileTransferListener {

    @Override
    public void fileTransferRequest(final FileTransferRequest request) {
        final IncomingFileTransfer transfer = request.accept();
        try {
            InputStream is = transfer.recieveFile();
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            int nRead;
            byte[] buf = new byte[1024];
            try {
                while ((nRead = is.read(buf, 0, buf.length)) != -1) {
                    os.write(buf, 0, nRead);
                }
                os.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            dataReceived = os.toByteArray();
            createDirectoryAndSaveFile(dataReceived, request.getFileName());
            Log.i("File Received", transfer.getFileName());
            processMessage(request);
        } catch (XMPPException ex) {
            Logger.getLogger(SmackConnection.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SmackException e) {
            e.printStackTrace();
        }
    }

}

public void fileTransfer(String user, Bitmap bitmap, String filename) throws XMPPException {
    Roster roster = Roster.getInstanceFor(mConnection);
    String destination = roster.getPresence(user).getFrom();
    // Create the file transfer manager
    FileTransferManager manager = FileTransferManager.getInstanceFor(mConnection);
    // Create the outgoing file transfer
    final OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(destination);
    // Send the file
    //transfer.sendFile(new File("abc.txt"), "You won't believe this!");
    transfer.sendStream(new ByteArrayInputStream(convertFileToByte(bitmap)), filename, convertFileToByte(bitmap).length, "A greeting");

    System.out.println("Status :: " + transfer.getStatus() + " Error :: " + transfer.getError() + " Exception :: " + transfer.getException());
    System.out.println("Is it done? " + transfer.isDone());
    if (transfer.getStatus().equals(FileTransfer.Status.refused))
        System.out.println("refused  " + transfer.getError());
    else if (transfer.getStatus().equals(FileTransfer.Status.error))
        System.out.println(" error " + transfer.getError());
    else if (transfer.getStatus().equals(FileTransfer.Status.cancelled))
        System.out.println(" cancelled  " + transfer.getError());
    else
        System.out.println("Success");
}

public byte[] convertFileToByte(Bitmap bmp) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
    return stream.toByteArray();
}

private void createDirectoryAndSaveFile(byte[] imageToSave, String fileName) {
    File direct = new File(Environment.getExternalStorageDirectory() + "/LocShopie/Received/");
    if (!direct.exists()) {
        File wallpaperDirectory = new File("/sdcard/LocShopie/Received/");
        wallpaperDirectory.mkdirs();
    }
    File file = new File(new File("/sdcard/LocShopie/Received/"), fileName);
    if (file.exists()) {
        file.delete();
    }
    try {
        FileOutputStream out = new FileOutputStream(file);
        out.write(imageToSave);
        out.flush();
        out.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

/*DeliveryReceiptManager dm = DeliveryReceiptManager
        .getInstanceFor(mConnection);
dm.setAutoReceiptMode(DeliveryReceiptManager.AutoReceiptMode.always);
dm.addReceiptReceivedListener(new ReceiptReceivedListener() {

    @Override
    public void onReceiptReceived(final String fromid,
    final String toid, final String msgid,
    final Stanza packet) {

    }
});*/
}

In this some lines are of database as i am storing the text msg in sqlite. this method is for send msg.

public void sendTextMessage(View v) {
    String message = msg_edittext.getEditableText().toString();
    if (!message.equalsIgnoreCase("")) {
        final ChatMessage chatMessage = new ChatMessage(LoginSignupPage.self, user2, message, "" + random.nextInt(1000), true, "TEXT");
        chatMessage.setMsgID();
        chatMessage.body = message;
        chatMessage.Date = CommonMethods.getCurrentDate();
        chatMessage.Time = CommonMethods.getCurrentTime();
        chatMessage.type = "TEXT";
        chatMessage.isMine = true;
        msg_edittext.setText("");
        try {
            chatAdapter.add(chatMessage);
            chatAdapter.notifyDataSetChanged();
            chatXmpp.sendMessage(chatMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }
        CommonMethods commonMethods = new CommonMethods(ChatActivity.this);
        commonMethods.createTable(user2);
        commonMethods.insertIntoTable(user2, chatMessage.sender, chatMessage.receiver, chatMessage.body, "m", "TEXT");
    }
}
Cabinetwork answered 30/12, 2015 at 19:40 Comment(14)
Can you share the chatMessage classVtehsta
If you have any separate error, please post another question. else comment.Cabinetwork
Hi, did you get slow chat message issue?Geriatrician
Hi, did you get slow chat message issue? means after sending any message receiver getting message too late..Geriatrician
@Geriatrician No, it was instant. like blink and Tin Tin! New MessageCabinetwork
I am getting issue of delayed message.. even i used same configuration as yours. Server has updated their smack to 4.0.2. do you know about this issue?Geriatrician
How much time it takes to get msg delivered?Cabinetwork
sometimes max 30 mins.. sometimes instant.. Our server team is saying that issue on client side so i updated my Smack to 4.2.0 but still getting this issueGeriatrician
I tried with PSI tool, when sending message from PSI messages are instant, issue is when i am sending from android/iosGeriatrician
It was pretty fast when i was working on. Not aware of the new updates of library. May be you are doing lengthy operations on your database.Try by passing the db operations.Cabinetwork
When i send message I get log of D/SMACK: SENT (0): <message to='id' id='7pj9B-201' type='chat'><active xmlns='jabber.org/protocol/chatstates'/></message><r xmlns='urn:xmpp:sm:3'/>Geriatrician
what version was on server side you used?Geriatrician
Not sure. what it was.Cabinetwork
You can check on their community page. community.igniterealtime.org/thread/57267Cabinetwork

© 2022 - 2024 — McMap. All rights reserved.