Avvia l'applicazione Android personalizzata dal browser Android


Risposte:


616

Usa un <intent-filter>con un <data>elemento. Ad esempio, per gestire tutti i collegamenti a twitter.com, lo inseriresti <activity>nel tuo AndroidManifest.xml:

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

Quindi, quando l'utente fa clic su un collegamento a Twitter nel browser, gli verrà chiesto quale applicazione utilizzare per completare l'azione: il browser o l'applicazione.

Naturalmente, se desideri fornire una stretta integrazione tra il tuo sito Web e la tua app, puoi definire il tuo schema:

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

Quindi, nella tua app web puoi inserire collegamenti come:

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

E quando l'utente fa clic su di essa, l'app verrà avviata automaticamente (perché probabilmente sarà l'unica in grado di gestire il my.special.scheme://tipo di uris). L'unico aspetto negativo di questo è che se l'utente non ha installato l'app, otterrà un brutto errore. E non sono sicuro che ci sia un modo per controllare.


Modifica: per rispondere alla tua domanda, puoi usare getIntent().getData()quale restituisce un Urioggetto. È quindi possibile utilizzare i Uri.*metodi per estrarre i dati necessari. Ad esempio, supponiamo che l'utente abbia fatto clic su un collegamento per 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"

Puoi fare quanto sopra ovunque nel tuo Activity, ma probabilmente vorrai farlo onCreate(). È inoltre possibile utilizzare params.size()per ottenere il numero di segmenti di percorso in Uri. Cerca su javadoc o sul sito web degli sviluppatori Android altri Urimetodi che puoi utilizzare per estrarre parti specifiche.


6
Grazie mille per la pronta risposta. Puoi dirmi come accedere ai parametri dopo "my.special.scheme: //".
Parimal Modi

4
Ho modificato la mia risposta per includere le istruzioni su come estrarre i dati da Uri. Contrassegna questa risposta come accettata (solo) se la considera così facendo clic sul segno di spunta accanto ad essa.
Felix,

9
cosa succede se l'applicazione Android di destinazione non è installata? Come gestirlo.
Nemo,

13
Chiunque, come me, non è in grado di far funzionare questo schema, deve aggiungersi android:exported="true"al proprio Activitymanifest. Controlla questa risposta stackoverflow.com/a/13044911/1276636
Sufian

4
Non sono sicuro di come funzioni per tutto il mondo. Semplicemente non funziona su Chrome e apre sempre il collegamento nel browser fino a quando non si inserisce l'elemento "android: pathPrefix". La risposta comunque non ha i valori di categoria come indicato nella documentazione. Se ancora non funziona per qualcuno, fai riferimento a questo: stackoverflow.com/a/21727055/2695276 PS: faticato per giorni su questo.
Rajat Sharma,

70

Tutte le risposte di cui sopra non hanno funzionato per me dal CHROME28 gennaio 2014

la mia app è stata avviata correttamente da http://example.com/someresource/ collegamenti da app come hangout, gmail ecc. ma non dal browser Chrome.

per risolvere questo problema, in modo che si avvii correttamente da CHROME devi impostare un filtro di intenti come questo

<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>

notare l' pathPrefixelemento

l'app verrà ora visualizzata nel selettore attività ogni volta che l'utente richiede http://example.com/someresource/ pattern dal browser Chrome facendo clic su un collegamento dai risultati di ricerca di Google o su qualsiasi altro sito Web


Questo mi ha aiutato moltissimo. Molte grazie! Pubblica la tua risposta qui in modo che io possa assegnarti la generosità! stackoverflow.com/questions/21663001/...
Vlad Schnakovszki

Che lingua è questa?
Dim

Ciao, so che è troppo vecchio. Sono anche colpito nello stesso scenario. Ho specificato pathPrefix, schema e host ma non funziona. Ho provato solo con lo schema, quindi ha funzionato. Ma quando ho aggiunto l'host, ha smesso di funzionare. Qualche idea su quale possa essere il problema?
seema

Ci ho passato giorni fino a quando sono arrivato a questa risposta. Non sono sicuro di come abbia funzionato per tutto il mondo senza l'elemento pathPrefix. Non ho mai lavorato per me su Chrome nonostante abbia fatto tutto secondo la documentazione. Grazie mille.
Rajat Sharma,

66

Si prega di vedere il mio commento qui: creare un collegamento nel browser Android avviare la mia app?

Scoraggiamo fortemente le persone dall'utilizzare i propri schemi, a meno che non stiano definendo un nuovo schema Internet mondiale.


10
Hackbod è uno degli ingegneri di Google dietro la piattaforma Android. È probabilmente una buona idea seguire questo consiglio. In effetti, sembra che il supporto dello schema personalizzato come questo si sia rotto in Honeycomb.
nmr

23
Non posso essere ritenuto responsabile delle limitazioni imposte agli sviluppatori da iOS. ;)
hackbod,

12
ritenuti responsabili? no. Ma potresti tenerne conto dal momento che, indipendentemente dal fatto che ti piaccia o no, tali limitazioni sono imposte a molti dei tuoi sviluppatori
ByteMe

6
hackbod sta rispondendo a una domanda specifica per Android. Non si parla di iOS, quindi non è necessario tenerne conto.
nilskp,

4
@hackbod definirebbe uno schema (ad esempio href = "com.ourdomain.myapp // qualunque") una buona pratica, supponendo che un link del genere possa essere trovato su siti Web diversi?
Julien Bérubé,

48

Nel mio caso ho dovuto impostare due categorie per il <intent-filter>e poi ha funzionato:

<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
Lo stesso qui, necessario per aggiungere la categoria aggiuntiva.
KPK,

Qualcuno può spiegare qual è l'effettivo processo per ottenere questo risultato? Qualsiasi collegamento all'esatta implementazione, prerequisiti sarà utile. Grazie
Ankit Garg,

Testato sulla configurazione degli sviluppatori. In realtà stavo dando un nome di dominio sbagliato. Colpa mia.
Ankit Garg,

La risposta più votata non ha funzionato per me, ma ha funzionato. Grazie.
EL45,

25

Ad esempio, hai le prossime cose:

Un link per aprire la tua app: http://example.com

Il nome del pacchetto dell'app: com.example.mypackage

Quindi devi fare il prossimo:

1) Aggiungi un filtro intento alla tua attività (può essere qualsiasi attività tu voglia. Per maggiori informazioni consulta la documentazione ).

        <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) Creare un file HTML per testare il collegamento o utilizzare questi metodi.

<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) Usa Mobile Chrome per testare

4) Questo è tutto.

E non è necessario pubblicare app sul mercato per testare il deep linking =)

Inoltre, per ulteriori informazioni, consultare la documentazione e la presentazione utile .


Ho dovuto creare un file html e caricarlo per farlo funzionare. Mi chiedo perché, soprattutto il secondo, non funziona direttamente da un browser (Chrome).
Makalele,

18

Dovrebbe anche essere <category android:name="android.intent.category.BROWSABLE"/>aggiunto al filtro intento per rendere l'attività riconosciuta correttamente dal collegamento.


4
Per riferimento, l'aggiunta di CATEGORY_BROWSABLE significa che "l'attività di destinazione può essere invocata in modo sicuro dal browser per visualizzare i dati a cui fa riferimento un collegamento, ad esempio un'immagine o un messaggio di posta elettronica".
greg7gkb,

È una categoria esistente o ne stai proponendo una nuova?
Anish,

Esiste. Apparentemente dovresti avere un host del sito web separato in diversi tag di filtro intenti, o causa problemi.
NoBugs,

2
Non solo BROWSABLE, ma anche android.intent.category.DEFAULT - quindi il link potrebbe essere aperto quando avviato in altre app, come la posta elettronica (non solo i browser)
AlikElzin-kilaka


7

Nota se la tua icona scompare dal launcher Android quando implementi questa funzione, allora devi dividere il filtro degli intenti.

    <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

Xamarin porta della risposta di Felix

Nel tuo MainActivity, aggiungi questo ( docs: Android.App.IntentFilterAttribute Class ):

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

Xamarin aggiungerà quanto segue AndroidManifest.xmlper te:

<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>

E per ottenere i parametri ( ho testato in OnCreate di 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];
        ...
    }
}

Per quanto ne so, sopra può essere aggiunto in qualsiasi attività, non solo MainActivity

Appunti:

  1. Quando l'utente fa clic sul collegamento, il sistema operativo Android riavvia la tua app (uccidi l'istanza precedente, se presente, ed eseguine una nuova) , significa che l' OnCreateevento dell'app MainLauncher Activityverrà nuovamente attivato.
  2. Con questo link <a href="my.special.scheme://host/arg1/arg2">:, nell'ultimo codice i valori dello snippet saranno:
scheme: my.special.scheme
host: host
args: ["arg1", "arg2"]
first: arg1
second: arg2

Aggiornamento: se Android crea una nuova istanza della tua app, dovresti aggiungere android:launchMode="singleTask"anche tu .


3

L'approccio di Felix alla gestione dei deep link è l'approccio tipico alla gestione dei deep link. Suggerirei anche di consultare questa libreria per gestire il routing e l'analisi dei tuoi deep link:

https://github.com/airbnb/DeepLinkDispatch

Puoi utilizzare le annotazioni per registrare la tua attività per un particolare URI di deep link, ed estrarrà i parametri per te senza dover fare il solito rigmarole per ottenere i segmenti del percorso, abbinarlo, ecc. Puoi semplicemente annotare e attività come questa :

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

0

Ehi, ho la soluzione. Non ho impostato la categoria come "Predefinita". Inoltre stavo usando l'attività principale per l'intento Data. Ora sto usando un'attività diversa per i dati di intento. Grazie per l'aiuto. :)


Suoni improbabile (anche se riconosco che si tratta di una vecchia questione e forse le cose sono cambiate.) Da developer.android.com/guide/components/intents-filters.html#ifs "Per un intento di superare il test categoria, ogni categoria in l' oggetto Intent deve corrispondere a una categoria nel filtro . Il filtro può elencare altre categorie, ma non può omettere nessuna delle intenzioni presenti nell'intento. "
Noach Magedman,

0

Devi aggiungere uno pseudo-hostname all'app CALLBACK_URL 'app: //' non ha senso come URL e non può essere analizzato.


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
Questo crea due iframe invisibili: deep link e link normale. Se l'app è installata, il deep link iframe la avvierà. In caso contrario, viene visualizzato il collegamento normale. Con un po 'di lavoro extra, è possibile implementare il deep linking posticipato in cui viene chiamato il deep link dopo l'installazione dell'app.
Dominic Cerisano,

0

Guarda la risposta di @JRuns qui . L'idea è quella di creare HTML con il tuo schema personalizzato e caricarlo da qualche parte. Quindi se fai clic sul tuo link personalizzato sul tuo file html, verrai reindirizzato alla tua app. Ho usato questo articolo per Android. Ma non dimenticare di impostare l' Name = "MyApp.Mobile.Droid.MainActivity"attributo nome completo per l'attività di destinazione.


0

Dal 15/06/2019

quello che ho fatto è includere tutte e quattro le possibilità per aprire l'URL.

vale a dire, con http/ httpse 2 con wwwin prefisso e 2 senzawww

e usando questo la mia app si avvia automaticamente ora senza chiedermi di scegliere un browser e altre opzioni.

<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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.