Posiblemente la razón por la que el póster original tuvo problemas para mantener el estado de la instancia es porque el comportamiento predeterminado de Android es iniciar una nueva actividad para cada nuevo intento. Es por eso que GrkEngineer no vio en que se llamara a RestoreInstanceState después de la devolución de llamada web.
El almacenamiento de su token de solicitud como preferencia compartida es una solución para que se pueda acceder desde la nueva actividad que se inicia después de la devolución de llamada web de OAuth.
Intenté originalmente usar las preferencias compartidas y pareció funcionar bien. Sin embargo, no creo que esa sea la mejor solución. Idealmente, desea forzar a Android a devolver la devolución de llamada a su actividad original (explicaré por qué a continuación).
He intentado usar los modos de inicio singleTask y singleInstance para lograr esto con éxito parcial, pero se sentía mal, y los documentos de Android dan a entender que esos modos no se recomiendan para uso general.
Después de analizar detenidamente la documentación y las pruebas, descubrí que usar los siguientes indicadores al crear la intención hace que Android entregue el intento a una instancia existente de la actividad (recreándola si ha sido eliminada).
intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
La razón por la que necesitaba que la actividad original manejara la devolución de llamada era para poder integrarla con el gestor de cuentas de Android. He utilizado el siguiente ejemplo de ayuda para empezar:
http://developer.android.com/resources/samples/SampleSyncAdapter/index.html
Una de las piezas clave de la integración con el mecanismo AccountManager autenticador es el AccountAuthenticatorResponse que se pasa en su actividad para iniciar el proceso de autenticación.
Encontré que el gran problema con la implementación de esto era mantener una referencia al objeto AccountAuthenticatorResponse. Esto se transfiere a su AuthenticatorActivity y necesita llamar a los métodos una vez que se completa la autenticación para que la UI de las cuentas estándar quede en el estado correcto. Sin embargo, me tocó el mismo problema que GrkEngineer inicialmente golpeó. Cuando intenté reiniciar mi actividad de autenticador de OAuth después de la devolución de llamada de OAuth, siempre obtenía una nueva instancia que había perdido la referencia al objeto AccountAuthenticatorResponse y no veía ninguna forma de persistir en ese objeto.
La clave era usar las banderas de intención que describí anteriormente.
AuthenticatorActivity se inicia utilizando FLAG_ACTIVITY_NEW_TASK por mi AbstractAccountAuthenticator. Recupera el token de solicitud (usando AsyncTask) e inicia el navegador para pedirle al usuario que lo autorice.
OAuthCallbackHandlerActivity está registrada para gestionar mi esquema de devolución de llamada personalizada. Cuando recibe una llamada después de que el usuario concede acceso, realiza una llamada a AuthenticatorActivity utilizando los indicadores Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP intento.
Esto hace que mi AuthenticatorActivity original se reactive. El objeto AccountAuthenticatorResponse todavía está disponible (al igual que el token/secret de la solicitud, que guardé en OnSaveInstanceState). La actividad ahora puede obtener el token de acceso (nuevamente usando AsyncTask) y luego llamar a los métodos de finalización en el objeto AccountAuthenticatorResponse.
La clave para hacer esto fue utilizar los indicadores de intención que mencioné, y también asegurarme de que AuthenticatorActivity se inicia en la tarea de la aplicación en lugar de en la tarea del administrador de la cuenta. FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP solo causará que una instancia existente de una actividad se reutilice si están en la misma tarea. Por lo tanto, si la actividad que desea reanudar se inicia en alguna otra tarea, entonces la instancia original no se volverá a utilizar.
Probé esto en un emulador usando Dev Tools para matar mi AuthenticatorActivity inmediatamente para poder probar el proceso de recreación. Funcionó muy bien utilizando onSaveInstanceState/onRestoreInstanceState para el token/secret de solicitud. Y ni siquiera tuve que preocuparme por restaurar el objeto AccountAuthenticatorResponse. Eso fue restaurado por el propio Android: ¡magia!
De hecho, comencé con su publicación anterior. Muy útil. Podría intentar tu solución, pero quería probar algo más para ayudarme a comprender mejor algunas de las cosas de OAuth. Encontré este ejemplo, http://code.google.com/p/jpoco/source/browse/trunk/jpoco-android-app/src/jpoco/android/MainActivity.java?r=346 en el cual él almacenó varios tokens como SharedPreferences para la aplicación. Si quisiera hacer algo similar, ¿qué partes del consumidor y el proveedor necesitaría guardar? También pensé que esto podría ser útil para no tener que volver a autenticarse cada vez que se ejecuta la aplicación. – GrkEngineer
No tiene que volver a autenticarse, simplemente guarde el token y vuelva a utilizarlo. Twitter no caduca. Tiene razón: en mi ejemplo, no estaba intentando comprender cómo se realiza la firma (por ejemplo), sino simplemente cómo usarla. De mi experiencia con DroidIn y de los comentarios que recibo, funciona bastante bien. Como alternativa, veo personas que usan la solución de generación de claves donde el usuario después de la autenticación se presenta con la clave que necesita ingresar en la página de firma de la aplicación, pero eso parece más dolor – Bostone
Sí, su ejemplo fue realmente útil. Supongo que tenía curiosidad por saber si los campos proveedor/consumidor podrían guardarse en el disco usando SharedPreferences. Luego, cuando vuelva la devolución de llamada, puede volver a llenar el proveedor/consumidor con los campos guardados. – GrkEngineer