with tutorial linking link example custom application app android deep-linking

android - tutorial - deep link ios



Deep linking y mĂșltiples instancias de aplicaciones (6)

Implementé enlaces profundos en mi aplicación. Agregué este filtro de intención en mi archivo de manifiesto, y el enlace profundo está funcionando.

<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.VIEW" /> <data android:host="www.mywebsite.com" android:pathPrefix="/something" android:scheme="http" /> </intent-filter>

El problema es que a través de enlaces profundos, mi aplicación se lanza sobre la aplicación actual. Si estoy en Gmail y hago clic en un enlace, mi aplicación se lanza sobre Gmail. Quiero iniciar mi aplicación de manera diferente.

Si mi aplicación ya se está ejecutando en segundo plano y hago clic en un enlace en Gmail que redirecciona a mi aplicación, tendré dos instancias de mi aplicación ejecutándose al mismo tiempo; uno en el fondo, y otro en la parte superior de Gmail. Quiero ejecutar solo una instancia de mi aplicación a la vez, por lo que no está en la parte superior de la aplicación actual (Gmail). ¿Cómo puedo hacer eso?


Bueno, tuvimos varios problemas con deeplinks. Me gusta:

  1. haga clic en el mismo enlace dos veces solamente, primer clic activó la vista correcta
  2. abrió instancias múltiples
  3. Los enlaces en WhatsApp o Facebook abrieron una vista en WhatsApp en sí debido a su navegador web.
  4. en Android 6 se abrió solo una instancia, pero solo se manejaba la primera intención, la segunda y tercera aplicación se abre pero no se realizó ninguna acción porque los datos intencionales no cambiaron de alguna manera.

Por lo tanto, la siguiente no es una respuesta clara a la pregunta más una solución completa para varios problemas que tuvimos.

Nuestra solución:

a) Creó una nueva FragmentActivity

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); //well can be anything some "loading screen" Intent intent = getIntent(); String intentUrl = intent.getDataString(); Intent newIntent = new Intent(this, MainActivity.class); newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); newIntent.putExtra("intentUrl",intentUrl); newIntent.setAction(Long.toString(System.currentTimeMillis())); startActivity(newIntent); finish(); }

b) Manifiesto:

<activity android:name="YOUR.NEW.FRAGMENT.ACTIVITY" android:label="@string/app_name" android:launchMode="singleTop"> <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="http" /> <data android:scheme="https" /> <data android:scheme="scheme1" /> <!-- sheme1://--> <data android:host="yourdomain.com" /> <data android:host="www.yourdomain.com" /> </intent-filter> </activity>

c) maneje el nuevo intento pasado en sus actividades onCreate () y onResume () llamando a la siguiente función de ejemplo:

private void handleUrl(Intent i){ String intentUrl = null; if (i != null) { intentUrl = i.getStringExtra("intentUrl"); if (intentUrl == null){ //hmm intent is damaged somehow } else { //because of onResume() if ( i.getBooleanExtra("used",false) ) { return; } i.putExtra("used", true); //DO SOMETHING WITH YOUR URL HERE } }


Debe hacer las siguientes cosas para su Actividad en su Manifiesto.

android:launchMode="singleTask"

Esto le dice al sistema que siempre inicie la instancia existente de la Actividad si ya está creada.

Y puede manejar el Intento luego anulando el método

onNewIntent

Consulte http://developer.android.com/guide/topics/manifest/activity-element.html para obtener más información.


Resuelvo estos problemas simplemente agregue android: launchMode = "singleTask" en el archivo de manifiesto


Tenía exactamente el mismo problema, excepto que quería que el usuario volviera a la tarea principal con la pila completa, como si acabaran de usar el conmutador de aplicaciones para cambiar a mi aplicación. Para lograr esto tuve que reordenar las tareas.

1) Dar permiso a mi aplicación para reordenar tareas

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.app"> <uses-permission android:name="android.permission.REORDER_TASKS"/> </manifest>

2) Mantenga un registro de cuál es la identificación de la tarea principal

public class MainActivity { public static int mainTaskId; @Override protected void onCreate(Bundle savedInstanceState) { super(savedInstanceState); //set the main task ID taskId = getTaskId(); } }

3) Cuando se inicia mi actividad de enlace profundo guarda algunos datos para usarlos más tarde y luego lleva la tarea principal al frente

public class DeepLinkActivity { @Override protected void onCreate(Bundle savedInstanceState) { super(savedInstanceState); //persist deep link data Uri uri = intent.getData(); String action = intent.getAction(); saveForLater(uri, action); if(isTaskRoot()){ //I''m in my own task and not the main task final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); activityManager.moveTaskToFront(MainActivity.taskId, ActivityManager.MOVE_TASK_NO_USER_ACTION); } } } }

4) Cuando se inicia cualquier actividad que esté en la parte superior de la pila posterior de la tarea principal, comprueba si hay datos guardados para trabajar y funciona en él.


la respuesta aceptada no funcionó para mí, esto es lo que hizo:

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish();

del documento oficial:

Si se establece, y la actividad que se está iniciando ya se está ejecutando en la tarea actual, en lugar de lanzar una nueva instancia de esa actividad, todas las demás actividades que se encuentren encima se cerrarán y esta intención se entregará al (ahora encendido arriba) actividad anterior como un nuevo propósito.


solo solucione este problema solo para una instancia

android: launchMode = "singleInstance"

<activity android:name=".SplashScreen" android:screenOrientation="portrait" android:launchMode="singleInstance" android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter android:autoVerify="true"> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="nvd.abc" /> </intent-filter> </activity>