J'ai mis en place un lien profond dans mon application. J'ai ajouté ce filtre d'intention dans mon fichier manifeste et le lien profond fonctionne.
<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>
Le problème est que grâce à un lien profond, mon application se lance au-dessus de l'application actuelle. Si je suis dans Gmail et que je clique sur un lien, mon application se lance au-dessus de Gmail. Je veux lancer mon application différemment.
Si mon application est déjà en cours d'exécution en arrière-plan et que je clique sur un lien dans Gmail qui redirige vers mon application, j'aurai deux instances de mon application en cours d'exécution en même temps; un en arrière-plan et un autre au-dessus de Gmail. Je souhaite exécuter une seule instance de mon application à la fois, elle n'est donc pas également au-dessus de l'application actuelle (Gmail). Comment puis je faire ça?
la réponse acceptée n'a pas fonctionné pour moi, voici ce qui a fonctionné:
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
du doc officiel:
S'il est défini et que l'activité en cours de lancement est déjà en cours d'exécution dans la tâche en cours, alors au lieu de lancer une nouvelle instance de cette activité, toutes les autres activités au-dessus seront fermées et cette intention sera livrée au (maintenant haut) ancienne activité en tant que nouvelle intention.
Vous devez faire les choses suivantes pour votre activité dans votre manifeste.
Android:launchMode="singleTask"
Cela indique au système de toujours lancer l'instance existante de l'activité si elle est déjà créée.
Et vous pouvez alors gérer l'intention en remplaçant la méthode
onNewIntent
Voir http://developer.Android.com/guide/topics/manifest/activity-element.html pour plus d'informations.
J'ai eu exactement le même problème, sauf que je voulais que l'utilisateur se retrouve dans la tâche principale avec la pile arrière complète, comme s'il venait d'utiliser le sélecteur d'application pour passer à mon application. Pour ce faire, j'ai dû réorganiser les tâches.
1) Autoriser mon application à réorganiser les tâches
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.company.app">
<uses-permission Android:name="Android.permission.REORDER_TASKS"/>
</manifest>
2) Gardez une trace de ce que l'ID de tâche principal est
public class MainActivity {
public static int mainTaskId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super(savedInstanceState);
//set the main task ID
taskId = getTaskId();
}
}
3) Lorsque mon activité de lien profond est lancée, elle enregistre certaines données pour une utilisation ultérieure, puis met la tâche principale au premier plan
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) Lorsque n'importe quelle activité en haut de la pile arrière de la tâche principale démarre, il vérifie s'il y a des données enregistrées sur lesquelles travailler et y travaille.
Eh bien, nous avons eu plusieurs problèmes avec les liens profonds. Comme:
Donc, ce qui suit n'est pas une réponse claire à la question plus une solution globale pour plusieurs problèmes que nous avions.
Notre solution:
a) Créé une nouvelle 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) Manifeste:
<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) gérer la nouvelle intention passée dans vos activités onCreate () et onResume () en appelant l'exemple de fonction suivant:
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
}
}
il suffit de résoudre ce problème pour une seule instance
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>
Je résous ces problèmes en ajoutant simplement Android: launchMode = "singleTask" dans le fichier manifeste