Lancer une application Android personnalisée à partir du navigateur Android


Réponses:


616

Utilisez un <intent-filter>avec un <data>élément. Par exemple, pour gérer tous les liens vers twitter.com, vous devez mettre cela <activity>dans votre AndroidManifest.xml:

<intent-filter>
    <data android:scheme="http" android:host="twitter.com"/>
    <action android:name="android.intent.action.VIEW" />
</intent-filter>

Ensuite, lorsque l'utilisateur clique sur un lien vers twitter dans le navigateur, il lui sera demandé quelle application utiliser pour mener à bien l'action: le navigateur ou votre application.

Bien sûr, si vous souhaitez assurer une intégration étroite entre votre site Web et votre application, vous pouvez définir votre propre schéma:

<intent-filter>
    <data android:scheme="my.special.scheme" />
    <action android:name="android.intent.action.VIEW" />
</intent-filter>

Ensuite, dans votre application Web, vous pouvez mettre des liens comme:

<a href="my.special.scheme://other/parameters/here">

Et lorsque l'utilisateur clique dessus, votre application sera lancée automatiquement (car elle sera probablement la seule à pouvoir gérer le my.special.scheme://type d'uris). Le seul inconvénient est que si l'utilisateur n'a pas installé l'application, il obtiendra une erreur désagréable. Et je ne suis pas sûr qu'il existe un moyen de vérifier.


Modifier: Pour répondre à votre question, vous pouvez utiliser getIntent().getData()ce qui renvoie un Uriobjet. Vous pouvez ensuite utiliser des Uri.*méthodes pour extraire les données dont vous avez besoin. Par exemple, supposons que l'utilisateur ait cliqué sur un lien pour http://twitter.com/status/1234:

Uri data = getIntent().getData();
String scheme = data.getScheme(); // "http"
String host = data.getHost(); // "twitter.com"
List<String> params = data.getPathSegments();
String first = params.get(0); // "status"
String second = params.get(1); // "1234"

Vous pouvez faire ce qui précède n'importe où dans votre Activity, mais vous voudrez probablement le faire onCreate(). Vous pouvez également utiliser params.size()pour obtenir le nombre de segments de chemin dans le Uri. Consultez javadoc ou le site Web des développeurs Android pour d'autres Uriméthodes que vous pouvez utiliser pour extraire des parties spécifiques.


6
Merci beaucoup pour votre réponse rapide. Mais pouvez-vous me dire comment accéder aux paramètres après "my.special.scheme: //".
Parimal Modi

4
J'ai modifié ma réponse pour inclure des instructions sur la façon d'extraire les données de l'Uri. Veuillez marquer cette réponse comme acceptée (uniquement) si vous la considérez comme telle en cliquant sur la coche à côté d'elle.
Felix

9
que faire si l'application Android ciblée n'est pas installée? Comment gérer cela.
Nemo

13
Quiconque, comme moi, n'est pas en mesure de faire fonctionner ce système, doit ajouter android:exported="true"à leur Activitymanifeste. Cochez cette réponse stackoverflow.com/a/13044911/1276636
Sufian

4
Je ne sais pas comment cela fonctionne pour le monde entier. Ne fonctionne tout simplement pas sur Chrome et ouvre toujours le lien dans le navigateur jusqu'à ce que vous placiez l'élément "android: pathPrefix". Quoi qu'il en soit, la réponse n'a pas les valeurs de catégorie mentionnées dans la documentation. Si cela ne fonctionne toujours pas pour quelqu'un, reportez-vous à ceci s'il vous plaît: stackoverflow.com/a/21727055/2695276 PS: a lutté pendant des jours à ce sujet.
Rajat Sharma

71

Toutes les réponses ci-dessus ne fonctionnaient pas pour moi au CHROME28 janvier 2014

mon application a été lancée correctement à partir de http://example.com/someresource/ des liens depuis des applications telles que Hangouts, Gmail, etc., mais pas depuis le navigateur Chrome.

pour résoudre ce problème, afin qu'il démarre correctement à partir de CHROME, vous devez définir un filtre d'intention comme celui-ci

<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="example.com"
        android:pathPrefix="/someresource/"
        android:scheme="http" />
    <data
        android:host="www.example.com"
        android:pathPrefix="/someresource/"
        android:scheme="http" />
</intent-filter>

noter l' pathPrefixélément

votre application apparaîtra désormais dans le sélecteur d'activité chaque fois que l'utilisateur demande un http://example.com/someresource/ modèle à partir du navigateur Chrome en cliquant sur un lien à partir des résultats de recherche Google ou de tout autre site Web


Cela m'a beaucoup aidé. Merci beaucoup! Veuillez poster votre réponse ici afin que je puisse vous attribuer la prime! stackoverflow.com/questions/21663001/…
Vlad Schnakovszki

Quelle langue est-ce?
Dims

Bonjour, je sais que c'est trop vieux. Je suis également frappé dans le même scénario. J'ai spécifié pathPrefix, schéma et hôte mais cela ne fonctionne pas. J'ai essayé avec le schéma uniquement, puis cela a fonctionné. Mais quand j'ai ajouté l'hôte, cela a cessé de fonctionner. Une idée de ce qui peut être le problème?
seema

J'ai passé des jours dessus jusqu'à ce que j'arrive à cette réponse. Je ne sais pas comment cela a fonctionné pour le monde entier sans l'élément pathPrefix. Je n'ai jamais travaillé pour moi sur Chrome, malgré tout faire selon la documentation. Merci beaucoup.
Rajat Sharma

66

S'il vous plaît voir mon commentaire ici: Faire un lien dans le navigateur Android démarrer mon application?

Nous décourageons fortement les gens d'utiliser leurs propres schémas, à moins qu'ils ne définissent un nouveau schéma Internet mondial.


10
Hackbod est l'un des ingénieurs de Google derrière la plate-forme Android. C'est probablement une bonne idée de suivre ces conseils. En fait, il semble que le support de schéma personnalisé comme celui-ci ait éclaté dans Honeycomb.
nmr

23
Je ne peux être tenu responsable des limitations imposées aux développeurs par iOS. ;)
hackbod

12
être tenu respondable? non. Mais vous pouvez en tenir compte car, que cela vous
plaise

6
hackbod répond à une question spécifiquement pour Android. Il n'y a aucune mention d'iOS, donc pas besoin d'en tenir compte.
nilskp

4
@hackbod serait un espace de noms un schéma (ie href = "com.ourdomain.myapp // quoi que ce soit") une bonne pratique, en supposant qu'un lien comme celui-ci pourrait être trouvé sur différents sites Web?
Julien Bérubé

48

Dans mon cas, j'ai dû définir deux catégories pour le <intent-filter>puis cela a fonctionné:

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

2
Idem ici, nécessaire pour ajouter la catégorie supplémentaire.
KPK

Quelqu'un peut-il expliquer quel est le processus réel pour y parvenir? Tout lien vers une implémentation exacte, les conditions préalables seront utiles. Merci
Ankit Garg

Testé sur la configuration des développeurs. En fait, je donnais un mauvais nom de domaine. Ma faute.
Ankit Garg

La réponse la mieux notée n'a pas fonctionné pour moi, mais cela a fonctionné. Je vous remercie.
EL45

25

Par exemple, vous avez des choses suivantes:

Un lien pour ouvrir votre application: http://example.com

Le nom du package de votre application: com.example.mypackage

Ensuite, vous devez faire ensuite:

1) Ajoutez un filtre d'intention à votre activité (il peut s'agir de n'importe quelle activité. Pour plus d'informations, consultez la documentation ).

        <activity
        android:name=".MainActivity">

        <intent-filter android:label="@string/filter_title_view_app_from_web">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <!-- Accepts URIs that begin with "http://example.com" -->

            <data
                android:host="example.com"
                android:scheme="http" />
        </intent-filter>

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

    </activity> 

2) Créez un fichier HTML pour tester le lien ou utilisez ces méthodes.

<a href="intent://example.com#Intent;scheme=http;package=com.example.mypackage;end">Open your Activity directly (just open your Activity, without a choosing dialog). </a>

<a href="http://example.com">Open this link with browser or your programm (by choosing dialog).</a>

3) Utilisez Mobile Chrome pour tester

4) C'est tout.

Et il n'est pas nécessaire de publier une application sur le marché pour tester le lien profond =)

De plus, pour plus d'informations, consultez la documentation et la présentation utile .


J'ai dû créer un fichier html et le télécharger afin de le faire fonctionner. Je me demande pourquoi, surtout le second, ne fonctionne pas directement à partir d'un navigateur (chrome).
Makalele

18

Il devrait également être <category android:name="android.intent.category.BROWSABLE"/>ajouté au filtre d'intention pour que l'activité soit correctement reconnue à partir du lien.


4
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

S'agit-il d'une catégorie existante ou en proposez-vous une nouvelle?
Anish

Ça existe. Apparemment, vous devriez avoir un hôte de site Web distinct dans différentes balises de filtre d'intention, sinon cela pose des problèmes.
NoBugs

2
Pas seulement BROWSABLE, mais aussi android.intent.category.DEFAULT - pour que le lien puisse être ouvert lorsqu'il est lancé dans d'autres applications, comme la messagerie électronique (pas seulement les navigateurs)
AlikElzin-kilaka


7

Veuillez noter que si votre icône disparaît du lanceur Android lorsque vous implémentez cette fonctionnalité, vous devez diviser le filtre d'intention.

    <activity
        android:name=".MainActivity"
        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>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="your-own-uri" />
        </intent-filter>
    </activity>


5

Port Xamarin de Felix 's answer

Dans votre MainActivity, ajoutez ceci ( docs: Android.App.IntentFilterAttribute Class ):

....
[IntentFilter(new[] { 
    Intent.ActionView }, 
    Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, 
    DataScheme = "my.special.scheme")
]
public class MainActivity : Activity
{
    ....

Xamarin ajoutera les éléments suivants AndroidManifest.xmlpour vous:

<activity
    android:label="Something"
    android:screenOrientation="portrait"
    android:theme="@style/MyTheme"
    android:name="blah.MainActivity">
    <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.special.scheme" />
    </intent-filter>
</activity>

Et pour obtenir des paramètres ( j'ai testé dans OnCreate of MainActivity ):

var data = Intent.Data;
if (data != null)
{
    var scheme = data.Scheme;
    var host = data.Host;
    var args = data.PathSegments;

    if (args.Count > 0)
    {
        var first = args[0];
        var second = args[1];
        ...
    }
}

Pour autant que je sache, ce qui précède peut être ajouté dans n'importe quelle activité, non seulement MainActivity

Remarques:

  1. Lorsque l'utilisateur clique sur le lien, Android OS relance votre application (tuez l'instance précédente, le cas échéant, et exécutez-en une nouvelle) , signifie que l' OnCreateévénement de l'application MainLauncher Activitysera à nouveau déclenché.
  2. Avec ce lien: <a href="my.special.scheme://host/arg1/arg2">en - dessus dernière valeurs extrait de code , sont les suivants:
scheme: my.special.scheme
host: host
args: ["arg1", "arg2"]
first: arg1
second: arg2

Mise à jour: si Android crée une nouvelle instance de votre application, vous devez android:launchMode="singleTask"également l' ajouter .


3

L'approche de Felix pour gérer les liens profonds est l'approche typique de la gestion des liens profonds. Je suggère également de consulter cette bibliothèque pour gérer le routage et l'analyse de vos liens profonds:

https://github.com/airbnb/DeepLinkDispatch

Vous pouvez utiliser des annotations pour enregistrer votre activité pour un URI de lien profond particulier, et il extraira les paramètres pour vous sans avoir à faire le rigmarole habituel pour obtenir les segments de chemin, les faire correspondre, etc. Vous pouvez simplement annoter et effectuer une activité comme celle-ci :

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

0

Hé, j'ai la solution. Je n'ai pas défini la catégorie comme "Par défaut". J'utilisais également l'activité principale pour les données d'intention. Maintenant, j'utilise une activité différente pour les données d'intention. Merci pour l'aide. :)


Cela semble peu probable (bien que je reconnaisse que c'est une vieille question et que les choses ont peut-être changé.) De developer.android.com/guide/components/intents-filters.html#ifs " l' objet Intention doit correspondre à une catégorie dans le filtre . Le filtre peut répertorier des catégories supplémentaires, mais il ne peut en omettre aucune qui est dans l'intention. "
Noach Magedman

0

Vous devez ajouter un pseudo-nom d'hôte à l'application CALLBACK_URL 'app: //' n'a pas de sens en tant qu'URL et ne peut pas être analysé.


0

example.php:

<?php
if(!isset($_GET['app_link'])){  ?>   
    <iframe src="example.php?app_link=YourApp://blabla" style="display:none;" scrolling="no" frameborder="0"></iframe>
    <iframe src="example.php?full_link=http://play.google.com/xyz" style="display:none;" scrolling="no" frameborder="0"></iframe>
    <?php 
}
else { ?>
    <script type="text/javascript">
    self.window.location        = '<?php echo $_GET['app_link'];?>';
    window.parent.location.href = '<?php echo $_GET['full_link'];?>';
    </script>
<?php 
}

1
Cela crée deux iframes invisibles: lien profond et lien normal. Si l'application est installée, le lien profond iframe la lancera. Sinon, le lien normal s'affiche. Avec un peu de travail supplémentaire, un lien profond différé pourrait être implémenté lorsque le lien profond est appelé après l'installation de l'application.
Dominic Cerisano

0

Regardez la réponse de @JRuns ici . L'idée est de créer du HTML avec votre schéma personnalisé et de le télécharger quelque part. Ensuite, si vous cliquez sur votre lien personnalisé dans votre fichier html, vous serez redirigé vers votre application. J'ai utilisé cet article pour Android. Mais n'oubliez pas de définir l' Name = "MyApp.Mobile.Droid.MainActivity"attribut de nom complet pour votre activité cible.


0

Au 15/06/2019

ce que j'ai fait est d'inclure les quatre possibilités pour ouvrir l'url.

c'est-à-dire avec http/ httpset 2 avec wwwen préfixe et 2 sanswww

et en utilisant cela, mon application se lance automatiquement maintenant sans me demander de choisir un navigateur et une autre option.

<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="https" android:host="example.in" />
    <data android:scheme="https" android:host="www.example.in" />
    <data android:scheme="http" android:host="example.in" />
    <data android:scheme="http" android:host="www.example.in" />

</intent-filter>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.