android中的XMPP连接使用smack
Posted
技术标签:
【中文标题】android中的XMPP连接使用smack【英文标题】:XMPP connection in android using smack 【发布时间】:2015-09-01 10:00:38 【问题描述】:我在运行代码时收到此错误。我正在使用 smack 3.1.0 和 smackx3.1.0 以及 smack 的 android 扩展(smack-android-4.1.0-alpha6)
09-01 15:28:37.430: E/NativeCrypto(9558): ssl=0x670ec948 cert_verify_callback x509_store_ctx=0x6790a938 arg=0x0
09-01 15:28:37.431: E/NativeCrypto(9558): ssl=0x670ec948 cert_verify_callback calling verifyCertificateChain authMethod=DHE_RSA
09-01 15:28:38.267: E/AndroidRuntime(9558): FATAL EXCEPTION: AsyncTask #6
09-01 15:28:38.267: E/AndroidRuntime(9558): Process: com.example.xmppkoderootapp, PID: 9558
09-01 15:28:38.267: E/AndroidRuntime(9558): java.lang.RuntimeException: An error occured while executing doInBackground()
09-01 15:28:38.267: E/AndroidRuntime(9558): at android.os.AsyncTask$3.done(AsyncTask.java:300)
09-01 15:28:38.267: E/AndroidRuntime(9558): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
09-01 15:28:38.267: E/AndroidRuntime(9558): at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
09-01 15:28:38.267: E/AndroidRuntime(9558): at java.util.concurrent.FutureTask.run(FutureTask.java:242)
09-01 15:28:38.267: E/AndroidRuntime(9558): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
09-01 15:28:38.267: E/AndroidRuntime(9558): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
09-01 15:28:38.267: E/AndroidRuntime(9558): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
09-01 15:28:38.267: E/AndroidRuntime(9558): at java.lang.Thread.run(Thread.java:841)
09-01 15:28:38.267: E/AndroidRuntime(9558): Caused by: java.lang.VerifyError: org/jivesoftware/smack/sasl/SASLMechanism
09-01 15:28:38.267: E/AndroidRuntime(9558): at java.lang.reflect.Constructor.constructNative(Native Method)
09-01 15:28:38.267: E/AndroidRuntime(9558): at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
09-01 15:28:38.267: E/AndroidRuntime(9558): at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:304)
09-01 15:28:38.267: E/AndroidRuntime(9558): at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:395)
09-01 15:28:38.267: E/AndroidRuntime(9558): at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:349)
09-01 15:28:38.267: E/AndroidRuntime(9558): at com.example.xmppkoderootapp.SettingsDialog$LongOperation.doInBackground(SettingsDialog.java:69)
09-01 15:28:38.267: E/AndroidRuntime(9558): at com.example.xmppkoderootapp.SettingsDialog$LongOperation.doInBackground(SettingsDialog.java:1)
09-01 15:28:38.267: E/AndroidRuntime(9558): at android.os.AsyncTask$2.call(AsyncTask.java:288)
09-01 15:28:38.267: E/AndroidRuntime(9558): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
09-01 15:28:38.267: E/AndroidRuntime(9558): ... 4 more
这是我的代码
SettingsDialog.java
package com.example.xmppkoderootapp;
import android.app.Dialog;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
/**
* Gather the xmpp settings and create an XMPPConnection
*/
public class SettingsDialog extends Dialog implements android.view.View.OnClickListener
private XMPPClient xmppClient;
public SettingsDialog(XMPPClient xmppClient)
super(xmppClient);
this.xmppClient = xmppClient;
protected void onStart()
super.onStart();
setContentView(R.layout.settings);
getWindow().setFlags(4, 4);
setTitle("XMPP Settings");
Button ok = (Button) findViewById(R.id.ok);
ok.setOnClickListener(this);
public void onClick(View v)
String host = getText(R.id.host);
String port = getText(R.id.port);
String service = getText(R.id.service);
String username = getText(R.id.userid);
String password = getText(R.id.password);
new LongOperation().execute("im.koderoot.net","5222","im.koderoot.net","xxxx@im.koderoot.net","xxxx");
dismiss();
private String getText(int id)
EditText widget = (EditText) this.findViewById(id);
return widget.getText().toString();
private class LongOperation extends AsyncTask<String, Void, String>
@Override
protected String doInBackground(String... params)
// Create a connection
// Create a connection
ConnectionConfiguration connConfig =
new ConnectionConfiguration(params[0], Integer.parseInt(params[1]), params[2]);
XMPPConnection connection = new XMPPConnection(connConfig);
try
connection.connect();
Log.i("XMPPClient", "[SettingsDialog] Connected to " + connection.getHost());
catch (XMPPException ex)
Log.e("XMPPClient", "[SettingsDialog] Failed to connect to " + connection.getHost());
Log.e("XMPPClient", ex.toString());
xmppClient.setConnection(null);
try
connection.login(params[3], params[4]);
Log.i("XMPPClient", "Logged in as " + connection.getUser());
// Set the status to available
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
xmppClient.setConnection(connection);
catch (XMPPException ex)
Log.e("XMPPClient", "[SettingsDialog] Failed to log in as " + params[3]);
Log.e("XMPPClient", ex.toString());
xmppClient.setConnection(null);
return "Executed";
@Override
protected void onPostExecute(String result)
Log.e("In onpost execute ", "Success");
// TextView txt = (TextView) findViewById(R.id.output);
//txt.setText("Executed"); // txt.setText(result);
// might want to change "executed" for the returned string passed
// into onPostExecute() but that is upto you
@Override
protected void onPreExecute()
@Override
protected void onProgressUpdate(Void... values)
XMPPClient.java
package com.example.xmppkoderootapp;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.filter.MessageTypeFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.StringUtils;
import java.util.ArrayList;
public class XMPPClient extends Activity
private ArrayList<String> messages = new ArrayList();
private Handler mHandler = new Handler();
private SettingsDialog mDialog;
private EditText mRecipient;
private EditText mSendText;
private ListView mList;
private XMPPConnection connection;
/**
* Called with the activity is first created.
*/
@Override
public void onCreate(Bundle icicle)
super.onCreate(icicle);
Log.i("XMPPClient", "onCreate called");
setContentView(R.layout.main);
mRecipient = (EditText) this.findViewById(R.id.recipient);
Log.i("XMPPClient", "mRecipient = " + mRecipient);
mSendText = (EditText) this.findViewById(R.id.sendText);
Log.i("XMPPClient", "mSendText = " + mSendText);
mList = (ListView) this.findViewById(R.id.listMessages);
Log.i("XMPPClient", "mList = " + mList);
setListAdapter();
// Dialog for getting the xmpp settings
mDialog = new SettingsDialog(this);
// Set a listener to show the settings dialog
Button setup = (Button) this.findViewById(R.id.setup);
setup.setOnClickListener(new View.OnClickListener()
public void onClick(View view)
mHandler.post(new Runnable()
public void run()
mDialog.show();
);
);
// Set a listener to send a chat text message
Button send = (Button) this.findViewById(R.id.send);
send.setOnClickListener(new View.OnClickListener()
public void onClick(View view)
String to = mRecipient.getText().toString();
String text = mSendText.getText().toString();
Log.i("XMPPClient", "Sending text [" + text + "] to [" + to + "]");
Message msg = new Message(to, Message.Type.chat);
msg.setBody(text);
connection.sendPacket(msg);
messages.add(connection.getUser() + ":");
messages.add(text);
setListAdapter();
);
/**
* Called by Settings dialog when a connection is establised with the XMPP server
*
* @param connection
*/
public void setConnection
(XMPPConnection
connection)
this.connection = connection;
if (connection != null)
// Add a packet listener to get messages sent to us
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
connection.addPacketListener(new PacketListener()
public void processPacket(Packet packet)
Message message = (Message) packet;
if (message.getBody() != null)
String fromName = StringUtils.parseBareAddress(message.getFrom());
Log.i("XMPPClient", "Got text [" + message.getBody() + "] from [" + fromName + "]");
messages.add(fromName + ":");
messages.add(message.getBody());
// Add the incoming message to the list view
mHandler.post(new Runnable()
public void run()
setListAdapter();
);
, filter);
private void setListAdapter
()
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.multi_line_list_item,
messages);
mList.setAdapter(adapter);
提前致谢
【问题讨论】:
【参考方案1】:希望这还不算太晚,错误是指 SASL 验证,我注意到您没有在 doInBackground() 中设置任何相关内容,请在您的 try 块中尝试以下操作(可能不完全是你需要,但这是基本的):
ConnectionConfiguration config = new ConnectionConfiguration(server, port);
//... any other stuff you need
//very basic security stuff just to get you going...
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
XMPPTCPConnection connection = new XMPPTCPConnection(config);
SASLAuthentication.supportSASLMechanism("DIGEST-MD5", 0);
connection.connect();
//... any other stuff you want
connection.login(user, passw);
希望这会有所帮助!
【讨论】:
以上是关于android中的XMPP连接使用smack的主要内容,如果未能解决你的问题,请参考以下文章
Android 中的 XMPP 聊天:ChatManager 未解决
xmpp连接Android Studio中的NetworkOnMainThreadException [重复]