Faire un lien dans le navigateur Android démarrer mon application?

229

Est-il possible de faire un lien tel que:

<a href="anton://useful_info_for_anton_app">click me!</a>

faire démarrer mon application Anton?

Je sais que cela fonctionne pour l'application Android Market avec le protocole de marché, mais peut-on faire quelque chose de similaire avec d'autres applications?

Voici un exemple de lien qui lancera l'Android Market:

<a href="market://search?q=pname:com.nytimes.android">click me!</a>

Mise à jour: La réponse que j'ai acceptée fournie par eldarerathis fonctionne très bien, mais je veux juste mentionner que j'ai eu quelques problèmes avec l'ordre des sous-éléments de la <intent-filter>balise. Je vous suggère simplement d'en créer un autre <intent-filter>avec les nouveaux sous-éléments de cette balise pour éviter les problèmes que j'ai rencontrés. Par exemple, mon AndroidManifest.xmlapparence ressemble à ceci:

<activity android:name=".AntonWorld"
          android:label="@string/app_name">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <intent-filter>
        <data android:scheme="anton" />
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.BROWSABLE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
Anton
la source
Cela a résolu mon problème lorsque je ne peux pas ouvrir l'application sur mon mobile.
Unomono
9
+1 pour avoir mentionné l'ordre des balises xml. Cela n'a absolument aucun sens et n'est documenté nulle part, mais j'ai constaté que lorsque j'avais la balise de données sous les balises d'action et de catégorie, cela ne fonctionnait tout simplement pas.
Adam
Rediriger vers l'application et se replier correctement si l'application n'est pas présente peut également être un peu un cauchemar, compte tenu de la complexité de tous les différents navigateurs Android (Chrome, Default, Webviews, Firefox, etc.). Le service branch.io y contribue et est gratuit.
Alex Austin
@Anton .... bonjour monsieur ... par le vôtre ci-dessus, je ne comprends que pour gérer les données du lien ... Pouvez-vous me dire comment créer un lien qui contient mes données ... aidez-moi moi ... Je veux créer le lien avec les données sur l'événement de clic de bouton ..
Ravindra Kushwaha
1
⚠️Je suis tombé sur un obstacle de débogage que d'autres voudront peut-être également connaître: les liens fonctionnent à partir de <a href=""> liens dans les pages Web et lorsqu'ils sont lancés avec adb, mais maintenant lorsque vous tapez simplement l'URL dans le mobile barre d'adresse du navigateur.⚠️
Johannes Brodwall

Réponses:

96

Je pense que vous voudrez regarder l' <intent-filter>élément de votre fichier Mainfest. Plus précisément, consultez la documentation du <data>sous-élément.

Fondamentalement, ce que vous devrez faire est de définir votre propre schéma. Quelque chose dans le sens de:

<intent-filter>
    <data android:scheme="anton" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" /> <--Not positive if this one is needed
    ...
</intent-filter>

Ensuite, vous devriez pouvoir lancer votre application avec des liens qui commencent par le anton:schéma d'URI.

eldarerathis
la source
3
Essayez de jeter un œil à ce fil. Il a un assez bon exemple: stackoverflow.com/questions/2958701/…
eldarerathis
3
Pour référence, l'ajout de CATEGORY_BROWSABLE signifie que "L'activité cible peut être invoquée en toute sécurité par le navigateur pour afficher les données référencées par un lien - par exemple, une image ou un message électronique."
greg7gkb
3
Cela fonctionne parfaitement sur les versions Android précédentes, mais pas sur les sucettes, une solution?
Salmaan
1
@eldarerathis, cela fonctionne si l'application est proche, mais si l'application s'exécute en arrière-plan et que l'activité est différente de celle à laquelle le filtre d'intention est attaché, je ne peux pas la gérer. Comment gérez-vous cela pour travailler dans toutes les activités? Mettez-vous un filtre d'intention dans chacun d'eux?
Mustafa Güven
5
Cette réponse est obsolète ... cela ne fonctionnera pas après le chrome 40. Le schéma personnalisé a été désactivé dans le chrome en raison de problèmes de sécurité
Utsav Gupta
280

Veuillez NE PAS utiliser votre propre schéma personnalisé comme ça !!! Les schémas URI sont un espace de noms global de réseau . Possédez-vous le programme "anton:" dans le monde entier? Non? Alors ne l'utilisez pas.

Une option consiste à avoir un site Web et à avoir un filtre d'intention pour un URI particulier sur ce site Web. Par exemple, voici ce que fait Market pour intercepter les URI sur son site Web:

        <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" android:host="market.android.com"
                android:path="/search" />
        </intent-filter>

Alternativement, il existe le schéma "intention:". Cela vous permet de décrire presque n'importe quelle intention comme un URI, que le navigateur tentera de lancer en cliquant dessus. Pour créer un tel schéma, la meilleure façon consiste à simplement écrire le code pour construire l'intention que vous souhaitez lancer, puis à imprimer le résultat d'intention.toUri (Intent.URI_INTENT_SCHEME).

Vous pouvez utiliser une action avec cette intention pour rechercher toute activité prenant en charge cette action. Le navigateur ajoutera automatiquement la catégorie BROWSABLE à l'intention avant de la lancer, pour des raisons de sécurité; il supprimera également tout composant explicite que vous avez fourni pour la même raison.

La meilleure façon d'utiliser cela, si vous voulez vous assurer qu'elle ne lance que votre application, est avec votre propre action de portée et en utilisant Intent.setPackage () pour dire que l'intention ne correspondra qu'à votre package d'application.

Compromis entre les deux:

  • Les URI http nécessitent que vous possédiez un domaine que vous possédez. L'utilisateur aura toujours la possibilité d'afficher l'URI dans le navigateur. Il a de très belles propriétés de secours où, si votre application n'est pas installée, elles atterriront simplement sur votre site Web.

  • Les URI intentionnels nécessitent que votre application soit déjà installée et uniquement sur les téléphones Android. Ils autorisent presque toutes les intentions (mais incluent toujours la catégorie BROWSABLE et ne prennent pas en charge les composants explicites). Ils vous permettent de diriger le lancement uniquement vers votre application sans que l'utilisateur n'ait la possibilité d'aller à la place vers le navigateur ou toute autre application.

hackbod
la source
32
D'autre part, l'application Market gère également les market://liens :)
Felix
38
C'était une erreur pour lui d'utiliser le marché:, et cela est en train d'être supprimé.
hackbod
82
La raison pour laquelle les gens utilisent des schémas personnalisés dans Android est parce que la plupart des projets sont développés en parallèle avec (ou après) la version iPhone, et c'est le seul moyen de le faire fonctionner là-bas ...
LambergaR
12
d'accord avec @LambergaR. Maintenant, nous devons trouver un moyen de créer un lien dans un e-mail sur 3 plates-formes (BB, iphone, Android)
Maragues
7
Tout URI que vous mettez dans votre page Web avec un schéma personnalisé ne fonctionnera pas sur un navigateur Web sur lequel votre application n'est pas également installée. Cela ne vous semble-t-il pas cassé?
hackbod
13

Je m'excuse de me promouvoir, mais j'ai un plugin jQuery pour lancer des applications natives à partir de liens Web https://github.com/eusonlito/jquery.applink

Vous pouvez l'utiliser facilement:

<script>
$('a[data-applink]').applink();
</script>

<a href="https://facebook.com/me" data-applink="fb://profile">My Facebook Profile</a>
Lito
la source
12

J'ai également fait face à ce problème et j'ai vu de nombreuses pages absurdes. J'ai appris que pour rendre votre application consultable, changez l'ordre des éléments XML, ceci:

<activity
    android:name="com.example.MianActivityName"
    android:label="@string/title_activity_launcher">

    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

    <intent-filter>                
        <data android:scheme="http" />     
        <!-- or you can use deep linking like  -->               

        <data android:scheme="http" android:host="xyz.abc.com"/>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <category android:name="android.intent.category.DEFAULT"/>

    </intent-filter>
</activity>

Cela a fonctionné pour moi et pourrait vous aider.

ashwani
la source
J'écris la balise XML dans la même séquence mais je ne peux pas ouvrir la boîte de dialogue du sélecteur lorsque j'écris mon URL dans le navigateur Android.
Sunit Kumar Gupta
je n'ai pas vu beaucoup de différence, et si j'utilise celui-ci, il fonctionne parfaitement .. Merci :)
Muthu S
6

Voici ma recette:

Créez un HTML statique qui redirige vers l'URL de votre application demandée, mettez cette page sur le Web.

De cette façon, les liens que vous partagez sont de «vrais» liens en ce qui concerne Android (ils seront «cliquables»).

Vous «partagez» un lien HTTP normal, www.your.server.com/foo/bar.html Cette URL renvoie un simple code HTML de 8 lignes qui redirige vers l'URI de votre application (window.location = "blah: // kuku") ( notez que 'blah' ne doit plus être HTTP ou HTTPS).

Une fois que vous l'avez mis en place, vous pouvez étendre le code HTML avec toutes les fonctionnalités sophistiquées comme suggéré ci-dessus.

Cela fonctionne avec le navigateur intégré, Opera et Firefox (je n'ai testé aucun autre navigateur). Firefox demande «Ce lien doit être ouvert avec une application» (ok, annuler). Les autres navigateurs ne se soucient apparemment pas beaucoup de la sécurité, ils ouvrent simplement l'application, sans poser de questions.

JRun
la source
Génial! Ça a marché pour moi. Nous avons donc ajouté une page html avec un lien vers un schéma personnalisé qui redirige vers mon application. Mon lien est<a href="iamnearby://register_activate">Activate</a>
S. Koshelnyk
4

Une fois que vous avez l'intention et le schéma d'URL personnalisé pour la configuration de votre application, ce code javascript en haut d'une page de réception a fonctionné pour moi sur iOS et Android:

<script type="text/javascript">
// if iPod / iPhone, display install app prompt
if (navigator.userAgent.match(/(iPhone|iPod|iPad);?/i) ||
    navigator.userAgent.match(/android/i)) {
  var store_loc = "itms://itunes.com/apps/raditaz";
  var href = "/iphone/";
  var is_android = false;
  if (navigator.userAgent.match(/android/i)) {
    store_loc = "https://play.google.com/store/apps/details?id=com.raditaz";
    href = "/android/";
    is_android = true;
  }
  if (location.hash) {
    var app_loc = "raditaz://" + location.hash.substring(2);
    if (is_android) {
      var w = null;
      try {
        w = window.open(app_loc, '_blank');
      } catch (e) {
        // no exception
      }
      if (w) { window.close(); }
      else { window.location = store_loc; }
    } else {
      var loadDateTime = new Date();
      window.setTimeout(function() {
        var timeOutDateTime = new Date();
        if (timeOutDateTime - loadDateTime < 5000) {
          window.location = store_loc;
        } else { window.close(); }
      },
      25);
      window.location = app_loc;
    }
  } else {
    location.href = href;
  }
}
</script>

Cela n'a été testé que sur le navigateur Android. Je ne suis pas sûr de Firefox ou d'Opera. La clé est que même si le navigateur Android ne lèvera pas une belle exception pour vous window.open(custom_url, '_blank'), il échouera et reviendra nullque vous pourrez tester plus tard.

Mise à jour: utilisation store_loc = "https://play.google.com/store/apps/details?id=com.raditaz";pour créer un lien vers Google Play sur Android.

Pete
la source
1
quel est l'intérêt de loadDateTime / timeOutDateTime? Est-ce que cela contourne les bloqueurs de popups ou quelque chose?
Matt Wolfe
cela ne semble pas fonctionner dans mes tests, window.open (...) ouvrira toujours une nouvelle fenêtre, même si le schéma n'est pas géré.
jtomson
@MattWolfe désolé pour la réponse tardive. Sur iPhone (Safari) aucune exception n'est levée. Le délai d'attente est là pour fermer la fenêtre obsolète dans Safari qui reste après la redirection de la page vers l'application. Je n'ai pas trouvé de moyen d'ouvrir une URL sans passer par Safari et la plupart des autres applications qui reconnaissent des URL comme celle-ci font la même chose. C'était l'un des avantages du «lien profond» de Facebook: vous ne bénéficiez pas de cette fenêtre obsolète de passer par Safari mobile.
Pete
@jtomson: Intéressant. J'ai testé sur l'émulateur et divers appareils d'Android 2.1 à 3 (à l'époque). Sur quel appareil et quelle version d'Android testiez-vous?
Pete
4

Vous voudrez peut-être envisager une bibliothèque pour gérer le lien profond vers votre application:

https://github.com/airbnb/DeepLinkDispatch

Vous pouvez ajouter le filtre d'intention sur une activité annotée comme les personnes suggérées ci-dessus. Il gérera le routage et l'analyse des paramètres de tous vos liens profonds. Par exemple, votre MainActivity peut avoir quelque chose comme ceci:

@DeepLink("somePath/{useful_info_for_anton_app}")
public class MainActivity extends Activity {
   ...
}

Il peut également gérer les paramètres de requête.

Christian
la source
1

Essayez mon truc simple:

        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if(url.startsWith("classRegister:")) {                  
                Intent MnRegister = new Intent(getApplicationContext(), register.class); startActivity(MnRegister);
            }               
            view.loadUrl(url);
            return true;
        }

et mon lien html:

<a href="classRegister:true">Go to register.java</a>

ou vous pouvez faire <a href = "classRegister: true "> <- valeur "true" pour nom de fichier de classe

cependant ce script fonctionne pour le lien mailto :)

        if (url.startsWith("mailto:")) {
            String[] blah_email = url.split(":");
            Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
            emailIntent.setType("text/plain");
            emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{blah_email[1]});
            emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, what_ever_you_want_the_subject_to_be)");
            Log.v("NOTICE", "Sending Email to: " + blah_email[1] + " with subject: " + what_ever_you_want_the_subject_to_be);
            startActivity(emailIntent);
        }
IRvanFauziE
la source
Il s'agit essentiellement d'un appel à un JavascriptInterfaceavec la solution de contournement, c'est la bonne solution de contournement si vous devez prendre en charge la version 2.3 où JavascriptInterface est buggé.
EpicPandaForce
1

Cette méthode n'appelle pas la boîte de dialogue de désambiguïsation vous demandant d'ouvrir votre application ou un navigateur.

Si vous enregistrez les éléments suivants dans votre manifeste

<manifest package="com.myApp" .. >
  <application ...>
    <activity ...>
      <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:host="gallery"
          android:scheme="myApp" />
      </intent-filter>
    </activity>
    ..

et cliquez sur cette URL depuis un e-mail sur votre téléphone par exemple

<a href="intent://gallery?directLink=true#Intent;scheme=myApp;package=com.myApp;end"> 
  Click me 
</a>

Android tentera alors de trouver une application avec le package com.myApp qui répond à votre intention de galerie et qui possède un schéma myApp . Dans le cas contraire, il vous amènera au magasin, à la recherche de com.myApp , qui devrait être votre application.

chat de mer
la source
Comment aller à une activité Android?
Mohsen Emami