2009-12-17 14 views
6

Soy nuevo en Smack API. Intento desarrollar una aplicación de chat donde estaba tratando de establecer y obtener la presencia.No se puede obtener la presencia de la lista mediante el uso de smack, openfire

Cuando cambio la presencia de un usuario, funciona perfectamente y se refleja en el servidor Openfire.

Pero cuando trato de obtener la presencia de un usuario, siempre obtengo el estado como 'no disponible' incluso si su presencia en openfire se muestra como 'disponible'.

Estoy usando el siguiente código para establecer el estado.

 Presence presence = new Presence(Presence.Type.available); 
     presence.setStatus("Online, Programmatically!"); 
     presence.setPriority(24); 
     presence.setMode(Presence.Mode.available); 
     user.getConnection().sendPacket(presence); 

Estoy utilizando la clase de lista para obtener la presencia de la siguiente manera.

Roster roster = avatar.getRoster(); 
Collection<RosterEntry> entries = roster.getEntries(); 

for(RosterEntry rosterEntry: entries) { 
    String user = rosterEntry.getUser(); 

    Presence presence = roster.getPresence(user); 

    System.out.println("Presence : "+presence);          // 1 
    System.out.println("Presence type: "+presence.getType());    // 2 
    System.out.println("Presence mode: "+presence.getMode());    // 3 

} 

Línea 1 No se da alwasys 'no disponible', mientras que la línea 2 y 3 siempre dan nula

no soy capaz de averiguar la causa de este problema. Por favor, ayúdame a resolver este problema.

Gracias de antemano.

+0

¿El usuario que desea obtener presencia acepta su suscripción? Si no, no puedes obtener Presencia. –

Respuesta

7

el problema es que después de iniciar sesión inmediatamente, va a tomar algún tiempo para que la presencia de los usuarios se actualice.Así, entre el inicio de sesión y llamar a la función de amigos en línea debería haber un thread.sleep() para unos pocos segundos. Luego se recuperarán los contactos en línea. Lo hice y pude recuperarlos. después del inicio de sesión use

Thread.sleep (5000);

uso en el beginiing del método también

+0

Tenía exactamente el mismo problema que en la declaración original. Ponga "Thread.sleep (5000)" luego de iniciar sesión como lo sugirió. Trabajado como un encanto. Gracias ! – Vini

+0

@Winnie ¿funcionó para ti? ¿¿cómo?? –

+0

funcionó para mí. aunque necesita implementar el lister de Roster para la actualización en tiempo real de la presencia. (Y) +1. –

3

Yo tenía el mismo problema y buscó un tiempo antes de encontrar cuál era el problema. De hecho, no es necesario hacer un Thread.sleep(). El problema es que no tienes el "permiso" para obtener la presencia de otros usuarios.

Para resolver el problema, solo ingrese en el administrador de Openfire -> sus opciones de usuario -> Lista // Luego simplemente configure la suscripción del amigo que desea obtener la presencia a "ambos" (ambos usuarios pueden ver la presencia) .

Espero que ayude.

Editar: De hecho, necesita agregar un Thread.sleep() antes de obtener la lista de la conexión. Sin Thread.sleep(), a veces funciona, a veces no ...

8

El uso de RosterListener es la solución adecuada a este problema. No hay ninguna razón para que el código tenga un Thread.sleep() para que funcione correctamente.

Roster roster = con.getRoster(); 
roster.addRosterListener(new RosterListener() { 
    // Ignored events public void entriesAdded(Collection<String> addresses) {} 
    public void entriesDeleted(Collection<String> addresses) {} 
    public void entriesUpdated(Collection<String> addresses) {} 
    public void presenceChanged(Presence presence) { 
     System.out.println("Presence changed: " + presence.getFrom() + " " + presence); 
    } 
}); 

(fuente: http://www.igniterealtime.org/builds/smack/docs/latest/documentation/roster.html)

+0

este código no funciona en absoluto en mi caso, pero mi problema es el mismo. por favor, ayúdenme @Andrea –

+0

está mostrando "nulo" cuando imprime presencia aquí para mí ?? – Vinay

+0

funcionó como un encanto (Y). Este enfoque es preferible cuando desea recibir notificaciones en tiempo real para sus contactos. De lo contrario, thread.sleep() también es una solución. (Y) +1. –

1

I fija que la adición de:

if (!roster.isLoaded()) 
    roster.reloadAndWait(); 

después:

Roster roster = Roster.getInstanceFor(connection); 

Ref: Smack 4.1.0 android Roster not displaying

+0

La pregunta no es sobre el problema con las entradas ... El problema es con la presencia de entradas. También estoy teniendo exactamente el mismo problema. –

0

Este código completo

public void getRoaster(final Callback<List<HashMap<String, String>>> callback) { 
    final Roster roster = Roster.getInstanceFor(connection); 
    boolean success = true; 

    if (!roster.isLoaded()) 
     try { 
      roster.reloadAndWait(); 
     } catch (SmackException.NotLoggedInException | SmackException.NotConnectedException | InterruptedException e) { 
      android.util.Log.e(AppConstant.PUBLIC_TAG, TAG + " " + e.getMessage()); 
      success = false; 
     } 

    if (!success) { 
     if (callback != null) { 
      callback.onError(new Throwable()); 
     } 
    } 

    Collection<RosterEntry> entries = roster.getEntries(); 
    List<HashMap<String, String>> maps = new ArrayList<HashMap<String, String>>(entries.size()); 
    for (RosterEntry entry : entries) { 
     HashMap<String, String> map = new HashMap<String, String>(3); 
     Presence presence = roster.getPresence(entry.getUser()); 

     map.put(ROASTER_KEY, entry.getName()); 
     map.put(ROASTER_BARE_JID, entry.getUser()); 
     map.put(PRESENCE_TYPE, presence.isAvailable() == true ? PRESENCE_ONLINE : PRESENCE_OFFLINE); 
     maps.add(map); 
    } 

    if (maps != null && maps.size() > 0 && callback != null) { 
     callback.onSuccess(maps); 
    } else { 
     callback.onError(new Throwable()); 
    } 
} 
Cuestiones relacionadas