Mat*_*ros 3 android smack facebook-chat
我正试图在Android上实现一个简单的Facebook聊天应用程序.它允许用户登录,之后应用程序打开一个新的ListActivity枚举用户的在线联系人,点击一个项目,另一个Activity打开他们的对话将发生的地方.
调用用户登录的第一个屏幕MainActivity.它包含两个EditTexts:一个用于FB用户名,另一个用于密码.还有两个按钮:清除,清空EditTexts,然后单击确定,执行以下AsyncTask new LoginTask().execute():
class LoginTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog loading;
@Override
protected void onPreExecute() {
loading = ProgressDialog.show(MainActivity.this, "", "Loading...");
}
@Override
protected Void doInBackground(Void... params) {
// setup XMPP connection
ConnectionConfiguration config = new ConnectionConfiguration(
"chat.facebook.com", 5222, "chat.facebook.com");
config.setDebuggerEnabled(true);
config.setSASLAuthenticationEnabled(true); // TRUE for fb
conn = new XMPPConnection(config);
try {
// attempt login
conn.connect();
SASLAuthentication.supportSASLMechanism("PLAIN", 0);
conn.login(login_field.getText().toString(),
pwd_field.getText().toString(), "");
Log.d("TRACE", "isAuthenticated? " + conn.isAuthenticated());
// list online contacts
Roster roster = conn.getRoster();
Collection<RosterEntry> entries = roster.getEntries();
Log.d("TRACE", "entries.size()=" + entries.size());
for (RosterEntry e : entries) {
Log.d("PRESENCE", e.getUser() + "=" + roster.getPresence(e.getUser()).isAvailable());
if (roster.getPresence(e.getUser()).isAvailable()) {
HashMap<String, String> contact = new HashMap<String, String>();
contact.put(NAME_KEY, e.getName());
contact.put(USERJID_KEY, e.getUser());
Log.d("ADD", "NAME_KEY=" + e.getName() + " USERJID_KEY=" + e.getUser());
contacts.add(contact);
}
}
Collections.sort(contacts, new ContactComparator()); // sort alphabetically
Log.d("TRACE", "MainActivity.contacts.size(): " + contacts.size());
Intent in = new Intent(MainActivity.this, ContactList.class);
startActivity(in);
} catch (Exception e) {
Log.d("EXCEPTION", e.toString());
}
return null;
}
@Override
protected void onPostExecute(Void result) {
loading.dismiss();
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,无论何时打开第二个屏幕,ListView通常都不会显示任何事情,但有时会这样做.我决定将日志消息添加到我正在检索联系人的部分,我conn.getRoster()发现在大多数情况下,呼叫conn.getRoster().getEntries.size()返回零,但当我实际通过浏览器登录Facebook时,我可以看到我做的有在线联系人.但是,我不明白为什么它有时会返回正确的数字,但是在我运行应用程序的时候几乎每十亿次只返回一次.
有人帮帮忙吗?这个应用程序将在四个小时内到期,我不知道该怎么办,因为我的代码似乎没有任何问题.
我在这里发布这个问题的第二天就找到了这个问题的答案.显然,当conn.login()被呼叫时,用户被认证并且Facebook服务器开始发送名册项目.大部分时间在第二个屏幕中没有出现任何内容的原因是代码startActivity()在Facebook服务器完成发送包含名册项目的数据包之前到达调用.但有时候,服务器的速度足以发送数据包但startActivity()被调用并且添加到服务器ArrayList会中断,从而导致ListView在线联系人不完整.一种解决方法我所做的就是调用Thread.sleep()后conn.login(),并创建一个5到10秒钟的延迟,使服务器有足够的时间来发送的所有数据包.
这只能工作一段时间但是当我有额外的任务来检索我的联系人的照片(使用VCard)时,即使是30秒的延迟也是不够的.您应该找到一种方法来确定服务器何时完成发送数据包和VCard,并在获得信号时继续添加到ArrayList.
不幸的是,看看Smack文档,似乎没有办法做到这一点.但那是因为我的目标总的来说是错误的.我试图做的是这样的:
ArrayList.ListActivity.ArrayList内容ListActivity.什么时候应该这样做:
ListActivity.ListView取决于您的联系人的存在(仍未完成此部分).简而言之,Smack API设计用于处理实时事件,因为它是一个即时消息库,我认为不应该设计它.我在第一个例子中试图做的是相当静态的.