2012-05-18 9 views
14

Estoy trabajando en una aplicación de Android que usa el AccountManager para almacenar las credenciales de las cuentas &. Un problema que he tenido es que, aunque transfiero un conjunto de valores String al de AccountManager addAccountExplicitly paquete de datos.AccountManager getUserData devolviendo nulo a pesar de estar configurado

He comprobado para asegurarse de que el paquete es no está vacío y que contiene los valores antes de añadir la cuenta. Y la mayoría de las veces este es el caso, pero de vez en cuando me sale nulo cuando consulto estos valores.

Los valores de devolución nula son más comunes después de que acabo de eliminar la cuenta y volver a agregarla.

que estoy haciendo mi consulta dentro de la onAccountsUpdated método de una implementación OnAccountsUpdateListener, por lo que la cuenta se debe agregar y bueno para ir, ¿verdad?

Gracias por cualquier ayuda

AuthenticatorActivity

// in the AuthenticatorActivity 
Bundle userData = new Bundle(); 
userData.put (k1, v1); 
userData.put (k2, v2); 
userData.put (k3, v3); 
userData.put (k4, v4); 
userData.put (k1, v1); 

Account a = new Account ("acc name", "com.account.type"); 
AccountManager am = AccountManager.get(this); 

OnAccountsUpdateListener listener = new OnAccountsUpdateListener() { 

     @Override 
     public void onAccountsUpdated(Account[] accounts) { 
      Account mine = findAccount(accounts, account); // match account name 
      notifySignedIn(mine); // tell the world you're signed in 
      am.removeOnAccountsUpdatedListener(this); 
     } 
    }; 

am.addOnAccountsUpdatedListener(listener, handler, false); 
am.addAccountExplicitly(a, "themostsecurepwintheworld", userData); 

algún otro flujo

AccountManager am = AccountManager.get(mContext); 
final string value2 = am.getUserData(mAccount, k2); 

if (TextUtils.isEmpty(value2)) { 
    Log.d("WTF", "value is empty"); 
} 
+1

Algún código, por favor. – kichik

+0

Hay demasiado código para copiar + pase, pero voy a editar la pregunta con un código básico. Hay mucha concurrencia y subprocesamiento, pero todo se inicia a través de _onAccountsUpdatedListener_. – copolii

Respuesta

8

Soy consciente de un fallo en nido de abeja además de que puede causar el problema. Si intenta obtener UserData de la cuenta antes de que se registre, todas las llamadas a getUserData posteriores devolverán nulo.

Si mira el código. AccountManager tiene una memoria caché en memoria respaldada por una base de datos sqlite. Al llamar a getUserData, se rellenan los datos de usuario de la memoria caché en memoria, incluso si no están registrados. Si no está registrado, lo interpreta como no userdata. El registro de una cuenta solo rellena la base de datos y no invalida el almacén en memoria.

Esto puede estar causando el problema.

La solución consiste en eliminar la cuenta antes de llamar a addAccountExplicitly.

Ya este problema apesta y es un error ENORME en AccountManger IMO y permite a los terceros en esencia DOS su aplicación.

+0

Gracias. Desde entonces he rediseñado el código para evitarlo, pero si recuerdo correctamente, ha estado ocurriendo en dispositivos pre-honeycomb y también en dispositivos ICS (Nexus 1, Nexus S, HTC Evo, Samsung Skyrocket, y algunos Más). – copolii

+0

Hola, ¿cómo codificaste esto? – fr1550n

+0

llame a removeAccount en su cuenta antes de llamar a addAccountExplicitly. También verifique que exista una cuenta antes de llamar a getUserData – Bishnu

3

¿Está utilizando un dispositivo de HTC con Android 4? Recibí muchos informes de este problema de los usuarios de mis aplicaciones de sincronización. Todo de ellos utilizó un dispositivo HTC con SDK nivel 15.

Parece un error de HTC para mí.

Varios usuarios informaron que el problema desapareció después de un reinicio.

Actualización: Mientras tanto encontramos una solución adecuada, ver https://stackoverflow.com/a/29776224/1558654

+0

Los AccountMangers anteriores fueron ingenuamente respaldados por una base de datos sqlite (todas las llamadas se leyeron desde el disco). Esto se modificó en HoneyComb, sin embargo, el caché en memoria tiene errores. El reinicio del dispositivo borra la memoria caché en memoria y permite que el dispositivo lea desde el disco (y, por lo tanto, los datos de usuario originales configurados por el usuario). – Bishnu

+0

Recibí unos 25 informes de este problema de los usuarios de HTC y ** informes ** de usuarios que no son de HTC. Eso no me parece una coincidencia. – Marten

+0

Esto no estaba limitado a los dispositivos HTC. Mi dispositivo de prueba principal era un Nexus S con 2.3.7, CM7, 4.0.4 y CM9. Ocurrió en diferentes grados en otros dispositivos también. – copolii

0

Tuve un problema similar, pero mi problema resultó ser el intento de almacenar un valor largo de userData en lugar de un String. Convirtiendo mi larga en una cuerda para el almacenamiento, y analizándola en una longitud larga de nuevo cuando la saqué, el truco fue para mí.

Cuestiones relacionadas