使用 Smack Api 为 Android 发送和接收消息

Sending and Receiving messages using Smack Api for Android

自从过去四天以来,我一直在尝试使用自己的 XMPP 和 Smack+OpenFire 发送和接收聊天消息。根据 Smack 的“readme.txt”,我建立了连接并让用户登录。连接和登录代码是这个

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());
}

这样我配置了connectionbuilder。 我在这里连接并登录用户。

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;
    }
}

在某些教程中,addPacketListner必须在登录后设置。我在 setConnection() 完成了这项工作,一些帖子通过了 addAsyncStanzaListner发送消息

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());
                }
            }
        }
    });

对于接收消息此代码

 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;
        }
    });
}

这是我的依赖项

 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'

但我仍然无法向 demo2 用户发送消息。 我在做什么 wrong.Please 指导和帮助我。 谢谢

很久以后我可以发送短信甚至图片了。这是我处理 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) {

    }
});*/
}

其中一些行是数据库的,因为我将文本消息存储在 sqlite 中。 此方法用于发送消息。

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");
    }
}