ventana una sesion restaurar recuperar recientemente que páginas por pestañas paginas las internet estaban cómo como chrome cerradas cerrada anterior accidente abiertas android google-chrome android-intent oauth-2.0

android - una - Intento del navegador y regreso a la actividad correcta(cerrar pestaña cerrada)



restaurar sesion anterior chrome (1)

Al implementar un tipo de cuenta personalizada en AccountManager en Android tengo el siguiente problema para el flujo de inicio de sesión:

El inicio de sesión debe realizarse a través de un proveedor de OAuth. Por lo tanto, he creado un SignInActivity que inicia un WebView e inicia un flujo de OAuth. Esto funciona bien, cuando la devolución de llamada se recibe en my-custom-scheme://callback el WebView detecta, recibe el parámetro querystring de code y completa el flujo. La desventaja de utilizar un WebView es que, aunque el usuario ya tenga una sesión activa en el navegador, esta sesión no se usa en WebView por lo que el usuario tendrá que volver a iniciar sesión en WebView .

Para resolver esto, intenté cambiar al uso de un intent-filter en AndroidManifest.xml , así:

<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="my-custom-scheme" android:path="callback"/> </intent-filter>

En lugar de abrir WebView en SignInActivity , inicio una intención del navegador y espero que el navegador SignInActivity a my-custom-scheme://callback .

Intent browserIntent = new Intent(Intent.ACTION_VIEW, "http://oauth2provider/authorize"); startActivity(browserIntent); finish();

En mi SignInActivity tengo el siguiente código para manejar la devolución de llamada:

if (intent != null && intent.getData() != null && getString("my-custom-scheme").equals(intent.getData().getScheme())) { String code = getIntent().getData().getQueryParameter("code"); // complete oauth flow }

Esto funciona. Pero, al problema (¡por fin!):

  1. Si el usuario no ha iniciado sesión, la intención del navegador mostrará la página de inicio de sesión del proveedor de Oauth. Después de que el usuario haya SignInActivity , Chrome se redireccionará a mi esquema personalizado: // callback y se iniciará SignInActivity para manejar el intento. Como esta actividad es invisible, el navegador permanecerá abierto en la página de inicio de sesión, y para el usuario parecerá que no pasó nada. El navegador nunca se cierra.
  2. Si el usuario ya inició sesión, el proveedor oauth se redirigirá directamente a my-custom-scheme: // callback. En este caso, la pestaña del navegador se cierra automáticamente, pero el navegador permanece abierto (sin pestañas visibles).

Entonces mi pregunta es: ¿hay alguna forma de hacer que el navegador se comporte de manera diferente después de haber sido redirigido a mi esquema personalizado: // devolución de llamada? Idealmente, me gustaría simplemente cerrar después de haber redirigido a la devolución de llamada, y volver a la actividad anterior en la pila de actividades (es decir, a la actividad que inició SignInActivity desde el principio).


Usé el siguiente enfoque para arreglar el mismo problema.

Supongamos que tenemos MainActivity con el botón Sign In . En lugar de iniciar el navegador directamente al hacer clic en ese botón, estoy iniciando SignInActivity usando el método startActivityForResult . Está usando para que pueda manejar el resultado del flujo de inicio de sesión.

startActivityForResult(new Intent(this, SignInActivity.class), requestCode);

SignInActivity es responsable de:

  • abrir el navegador con la página de inicio de sesión
  • capturar redirigir a custom-scheme://callback
  • finalizar el flujo de inicio de sesión utilizando token recibido de la URL redireccionada
  • devolver el resultado a MainActivity

Entonces, su método onCreate se ve así:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.login); if (intent != null && intent.getData() != null && "custom-scheme".equals(intent.getData().getScheme())) { String code = getIntent().getData().getQueryParameter("code"); // complete oauth flow } else { Intent browserIntent = new Intent(Intent.ACTION_VIEW, "http://oauth2provider/authorize") .setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND); startActivity(browserIntent); finish(); } }

Admitir banderas establecidas en la intención del navegador.

De esta forma, si se abre MainActivity desde MainActivity , solo abre la página de inicio de sesión en el navegador y si se abre atrapando la URL de redirección, completa el flujo de inicio de sesión al enviar la solicitud correspondiente.

Después de completar el flujo de inicio de sesión enviando el código a algún punto final en su método de devolución de llamada, debe hacer lo siguiente:

setResult(Activity.RESULT_OK); this.finish();

Naturalmente, recibe access_token desde ese punto final. Puede almacenarlo en algún lugar aquí, en la devolución de llamada exitosa o devolverlo a MainActivity para manejarlo allí.

Como diseño para SignInActivity puede usar solo ProgressBar en el centro de la página. Aparecerá durante la finalización del flujo de inicio de sesión después de que SignInActivity se abra y se redireccione url ( custom-scheme://callback ).

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ProgressBar android:layout_width="48dp" android:layout_height="48dp" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> </RelativeLayout>

Aquí está la declaración de SignInActivity en AndroidManifest.xml

<activity android:name=".SignInActivity" android:launchMode="singleTask" android:noHistory="true" > <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="custom-scheme" android:host="callback"/> </intent-filter> </activity>