在与Facebook的问题啪聊天应用程序为Android:Connection.getRoster()getEntries()总是空的。 [英] Problem with Smack in Facebook chat app for Android: Connection.getRoster().getEntries() is always empty

查看:228
本文介绍了在与Facebook的问题啪聊天应用程序为Android:Connection.getRoster()getEntries()总是空的。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现在Android上一个简单的Facebook聊天应用程序。它可以让用户登录,应用程序打开之后,一个新的 ListActivity 枚举用户的在线联系人,并在点击一个项目,另一个活动打开,他们的谈话会发生。

I'm trying to implement a simple Facebook chat application on Android. It lets the user login, after which the app opens a new ListActivity enumerating the user's online contacts, and upon clicking on an item, another Activity opens where their conversation will take place.

第一个屏幕,在被称为用户登录 MainActivity 。它包含两个的EditText S:一个是FB用户名和其他密码。此外,还有两个按钮:晴间多云,其中清空的EditText s和确定,其在点击,通过执行以下AsyncTask的新LoginTask()。执行()

The first screen where the user logs in is called MainActivity. It contains two EditTexts: one for the FB username, and the other for password. There are also two buttons: Clear, which empties the EditTexts, and OK, which upon click, executes the following AsyncTask via 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();
   }
}

我的问题是,每当第二个屏幕打开时,ListView控件通常不会显示anythying,但因为有时。我决定将日志信息添加到我通过 conn.getRoster检索联系人()的一部分,我发现大部分的时间,调用 conn.getRoster()。getEntries.size()返回零,但是当我通过浏览器进行实际的登录到Facebook的,我可以看到我有在线联系人。我不明白的,虽然,这就是为什么它有时会返回正确的号码,但只有在几乎每一个十亿倍,一旦我运行应用程序。

My problem is that whenever the second screen is opened, the ListView often doesn't show anythying, BUT IT SOMETIMES DOES. I decided to add log messages to the part where I'm retrieving the contacts via conn.getRoster() and I found out that most of the time, a call to conn.getRoster().getEntries.size() returns a zero, but when I actually login to Facebook via browser, I can see that I do have online contacts. What I don't understand, though, is why it sometimes returns the correct number, but only once in almost every billion times I run the application.

有人帮助,好吗?该应用程序的原因在四个小时内,我不知道该怎么办了,因为似乎有什​​么错我的code。

Somebody help, please? This app's due in four hours and I don't know what to do anymore since there seems to be nothing wrong with my code.

推荐答案

我找到了答案,这个问题一天后,我把它贴在这里。显然,当 conn.login()被调用时,该用户成为身份验证和Facebook服务器开始发送名册项目。为什么没有出现在第二个屏幕的大部分时间的原因是,code到达呼叫 startActivity()甚至在Facebook的服务器进行发送数据包含名册项目。然而,有时候,服务器足够快的数据包发送,但 startActivity()被调用,并增加了的ArrayList 成为中断,导致到一个不完整的的ListView在线联系人。一种解决方法我所做的就是调用视频下载() conn.login(),并创建一个5到10秒钟的延迟,使服务器有足够的时间来发送所有的数据包。

I found the answer to this question the day after I posted it here. Apparently, when conn.login() is called, the user becomes authenticated and the Facebook server starts sending the roster items. The reason why nothing appears in the second screen most of the time is that the code reaches the call to startActivity() EVEN BEFORE the Facebook server is done sending the packets containing the roster items. Sometimes, though, the server is fast enough to send the packets but startActivity() is called and adding to the ArrayList becomes interrupted, resulting to an incomplete ListView of your online contacts. A workaround I did was to call Thread.sleep() after conn.login() and create a 5- to 10-second delay so that the server would have enough time to send all the packets.

这仅仅工作了一段时间,但是当我有检索,甚至相关的照片我的联系人(使用电子名片)的添加的任务,甚至是30秒的延迟WASN吨就够了。你应该找到一种方法,然后才能确定当服务器完成发送数据包和电子名片,并继续添加到ArrayList只有当你得到信号。

That worked only for a while but when I has the added task of retrieving even the photos of my contacts (using VCard), even a 30-second delay wasn't enough. You should find a way then to determine when the server is done sending packets and the VCards and proceed with adding to the ArrayList only when you get the signal.

不幸的是,望着啪的文档,似乎没有成为一个办法做到这一点。但是,那是因为我的目标是,总体而言,是错误的。我试图做的是这样的:

Unfortunately, looking at the Smack documentation, there doesn't seem to be a way to do that. But that's because my goal was, overall, wrong. What I was trying to do is this:

  1. 登录到Facebook上。
  2. 在获取所有在线联系人。
  3. 把它们放在一个的ArrayList
  4. 打开一个 ListActivity
  5. 显示的ArrayList 内容的 ListActivity
  1. Log in to Facebook.
  2. Get all online contacts.
  3. Put them in an ArrayList.
  4. Open a ListActivity.
  5. Display the ArrayList contents in the ListActivity.

当它应该做的:

  1. 登录到Facebook上。
  2. 打开一个 ListActivity
  3. 获取所有的联系人。
  4. 动态更新的ListView 根据联系人的presence(还没有做这部分)。
  1. Log in to Facebook.
  2. Open a ListActivity.
  3. Get ALL your contacts.
  4. Dynamically update the ListView depending on your contacts' presence (still haven't done this part).

总之,啪API已经被设计用于处理实时的事件,因为它是一个即时信息库,我不认为它应该被设计并非如此。我试图做第一个例子是相当静态的。

In short, the Smack API has been designed to handle real-time events, and because it's an instant messaging library, I don't think it should have been designed otherwise. What I was trying to do in the first example was rather static.

这篇关于在与Facebook的问题啪聊天应用程序为Android:Connection.getRoster()getEntries()总是空的。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆