Starten Sie eine benutzerdefinierte Android-Anwendung über den Android-Browser


Antworten:


616

Verwenden Sie ein <intent-filter>mit einem <data>Element. Wenn Sie beispielsweise alle Links zu twitter.com bearbeiten möchten, fügen Sie dies <activity>in Folgendes ein AndroidManifest.xml:

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

Wenn der Benutzer dann im Browser auf einen Link zu Twitter klickt, wird er gefragt, welche Anwendung er verwenden soll, um die Aktion abzuschließen: den Browser oder Ihre Anwendung.

Wenn Sie eine enge Integration zwischen Ihrer Website und Ihrer App gewährleisten möchten, können Sie natürlich Ihr eigenes Schema definieren:

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

Dann können Sie in Ihre Web-App Links einfügen wie:

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

Und wenn der Benutzer darauf klickt, wird Ihre App automatisch gestartet (da sie wahrscheinlich die einzige ist, die mit my.special.scheme://Uristypen umgehen kann). Der einzige Nachteil dabei ist, dass der Benutzer einen bösen Fehler erhält, wenn er die App nicht installiert hat. Und ich bin mir nicht sicher, ob es eine Möglichkeit gibt, dies zu überprüfen.


Bearbeiten: Um Ihre Frage zu beantworten, können Sie verwenden, getIntent().getData()welche ein UriObjekt zurückgibt . Sie können dann Uri.*Methoden verwenden, um die benötigten Daten zu extrahieren. Angenommen, der Benutzer hat auf einen Link geklickt zu 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"

Sie können das oben genannte überall in Ihrem tun Activity, aber Sie werden es wahrscheinlich in tun wollen onCreate(). Sie können auch verwenden params.size(), um die Anzahl der Pfadsegmente in der zu ermitteln Uri. Weitere UriMethoden, mit denen Sie bestimmte Teile extrahieren können, finden Sie auf javadoc oder auf der Android-Entwickler-Website .


6
Vielen Dank für Ihre schnelle Antwort. Aber können Sie mir bitte sagen, wie ich nach "my.special.scheme: //" auf die Parameter zugreifen soll?
Parimal Modi

4
Ich habe meine Antwort so bearbeitet, dass sie Anweisungen zum Extrahieren der Daten aus dem Uri enthält. Bitte markieren Sie diese Antwort als akzeptiert (nur), wenn Sie dies berücksichtigen, indem Sie auf das Häkchen daneben klicken.
Felix

9
Was ist, wenn die Ziel-Android-Anwendung nicht installiert ist? Wie man damit umgeht.
Nemo

13
Jeder, der wie ich nicht in der Lage ist, dieses Schema zum Laufen android:exported="true"zu bringen, muss sein ActivityManifest ergänzen . Überprüfen Sie diese Antwort stackoverflow.com/a/13044911/1276636
Sufian

4
Ich bin mir nicht sicher, wie das für die ganze Welt funktioniert. Funktioniert einfach nicht mit Chrome und öffnet den Link immer im Browser, bis Sie das Element "android: pathPrefix" platzieren. Die Antwort hat sowieso nicht die in der Dokumentation angegebenen Kategoriewerte. Wenn es für jemanden immer noch nicht funktioniert, lesen Sie dies bitte: stackoverflow.com/a/21727055/2695276 PS: tagelang darum gekämpft.
Rajat Sharma

70

Alle oben genannten Antworten haben bei mir CHROMEzum 28. Januar 2014 nicht funktioniert

Meine App wurde ordnungsgemäß über http://example.com/someresource/ Links von Apps wie Hangouts, Google Mail usw. gestartet, jedoch nicht über den Chrome-Browser.

Um dies zu lösen, damit es ordnungsgemäß von CHROME gestartet wird, müssen Sie den Absichtsfilter wie folgt einstellen

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

Beachten Sie das pathPrefixElement

Ihre App wird jetzt in der Aktivitätsauswahl angezeigt, wenn der Benutzer das Muster http://example.com/someresource/ vom Chrome-Browser anfordert, indem er auf einen Link in den Google-Suchergebnissen oder auf einer anderen Website klickt


Das hat mir sehr geholfen. Vielen Dank! Bitte poste deine Antwort hier, damit ich dir das Kopfgeld geben kann! stackoverflow.com/questions/21663001/…
Vlad Schnakovszki

Welche Sprache ist das?
Dims

Hallo, ich weiß, dass es zu alt ist. Ich bin auch im gleichen Szenario getroffen. Ich habe pathPrefix, Schema und Host angegeben, aber es funktioniert nicht. Ich habe es nur mit Schema versucht, dann hat es funktioniert. Aber als ich Host hinzufügte, funktionierte es nicht mehr. Irgendeine Idee, was das Problem sein kann?
Seema

Verbrachte Tage damit, bis ich zu dieser Antwort kam. Ich bin mir nicht sicher, wie es für die ganze Welt ohne das pathPrefix-Element funktioniert hat. Ich habe nie für Chrom gearbeitet, obwohl ich alles gemäß der Dokumentation gemacht habe. Ich danke dir sehr.
Rajat Sharma

66

Bitte beachten Sie meinen Kommentar hier: Einen Link im Android-Browser erstellen meine App starten?

Wir raten Menschen dringend davon ab, ihre eigenen Systeme zu verwenden, es sei denn, sie definieren ein neues weltweites Internet-System.


10
Hackbod ist einer der Google-Ingenieure hinter der Android-Plattform. Es ist wahrscheinlich eine gute Idee, diesen Rat zu befolgen. Tatsächlich scheint die Unterstützung von benutzerdefinierten Schemata wie diese in Honeycomb gebrochen zu sein.
nmr

23
Ich kann nicht für Einschränkungen verantwortlich gemacht werden, die Entwicklern von iOS auferlegt werden. ;)
Hackbod

12
verantwortlich gemacht? Nein. Aber Sie könnten es berücksichtigen, da diese Einschränkungen vielen Ihrer Entwickler auferlegt werden, unabhängig davon, ob Sie es mögen oder nicht
ByteMe

6
hackbod beantwortet eine Frage speziell für Android. IOS wird nicht erwähnt, daher muss es nicht berücksichtigt werden.
Nilskp

4
@hackbod würde ein Namespace eines Schemas (dh href = "com.ourdomain.myapp // was auch immer") eine gute Praxis sein, vorausgesetzt, ein solcher Link könnte auf verschiedenen Websites gefunden werden?
Julien Bérubé

48

In meinem Fall musste ich zwei Kategorien für das festlegen <intent-filter>und dann funktionierte es:

<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
Gleiches hier, benötigt, um die zusätzliche Kategorie hinzuzufügen.
KPK

Kann jemand erklären, was der eigentliche Prozess ist, um dies zu erreichen? Jeder Link zur genauen Implementierung, Voraussetzungen sind hilfreich. Vielen Dank
Ankit Garg

Getestet auf Dev Setup. Eigentlich habe ich einen falschen Domainnamen angegeben. Mein Fehler.
Ankit Garg

Die am besten bewertete Antwort hat bei mir nicht funktioniert, aber das hat funktioniert. Vielen Dank.
EL45

25

Zum Beispiel haben Sie die nächsten Dinge:

Ein Link zum Öffnen Ihrer App: http://example.com

Der Paketname Ihrer App: com.example.mypackage

Dann müssen Sie als nächstes tun:

1) Fügen Sie Ihrer Aktivität einen Absichtsfilter hinzu (kann eine beliebige Aktivität sein. Weitere Informationen finden Sie in der Dokumentation ).

        <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) Erstellen Sie eine HTML-Datei, um den Link zu testen, oder verwenden Sie diese Methoden.

<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) Verwenden Sie Mobile Chrome zum Testen

4) Das war's.

Und es ist nicht notwendig, eine App auf dem Markt zu veröffentlichen, um Deep Linking zu testen =)

Weitere Informationen finden Sie in der Dokumentation und in der nützlichen Präsentation .


Ich musste eine HTML-Datei erstellen und hochladen, damit sie funktioniert. Ich frage mich, warum, besonders der zweite, nicht direkt über einen Browser (Chrome) funktioniert.
Makalele

18

Es sollte auch <category android:name="android.intent.category.BROWSABLE"/>zum Absichtsfilter hinzugefügt werden, damit die Aktivität über den Link richtig erkannt wird.


4
Als Referenz bedeutet das Hinzufügen von CATEGORY_BROWSABLE, dass "die Zielaktivität vom Browser sicher aufgerufen werden kann, um Daten anzuzeigen, auf die durch einen Link verwiesen wird - beispielsweise ein Bild oder eine E-Mail-Nachricht."
Greg7gkb

Ist dies eine bestehende Kategorie oder schlagen Sie eine neue vor?
Anish

Es existiert. Anscheinend sollten Sie einen separaten Website-Host in verschiedenen Intent-Filter-Tags haben, da dies sonst zu Problemen führt.
NoBugs

2
Nicht nur BROWSABLE, sondern auch android.intent.category.DEFAULT - damit der Link geöffnet werden kann, wenn er in anderen Apps wie E-Mail (nicht nur in Browsern)
initiiert wird


7

Bitte beachten Sie, wenn Ihr Symbol bei der Implementierung dieser Funktion aus dem Android Launcher verschwindet, müssen Sie den Intent-Filter aufteilen.

    <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 Hafen von Felix 'Antwort

In Ihrem MainActivity, fügen Sie diese ( docs: Android.App.IntentFilterAttribute Klasse ):

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

Xamarin wird AndroidManifest.xmlfür Sie Folgendes hinzufügen :

<activity android:label="Something" android:screenOrientation="portrait" android:theme="@style/MyTheme" android:name="blahblahblah.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>

Und um Parameter zu erhalten ( ich habe in OnCreate of MainActivity getestet ):

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];
        ...
    }
}

Soweit ich weiß, kann das oben Genannte in jeder Aktivität hinzugefügt werden, nicht nur in MainActivity

Anmerkungen:

  1. Wenn der Benutzer auf den Link klickt , startet das Android-Betriebssystem Ihre App neu (ggf. vorherige Instanz beenden und neue ausführen) , was bedeutet, dass das OnCreateEreignis der App MainLauncher Activityerneut ausgelöst wird.
  2. Mit diesem Link: <a href="my.special.scheme://host/arg1/arg2">Im obigen letzten Code werden Snippet-Werte angezeigt:
scheme: my.special.scheme
host: host
args: ["arg1", "arg2"]
first: arg1
second: arg2

3

Felix 'Ansatz zum Umgang mit Deep Links ist der typische Ansatz zum Umgang mit Deep Links. Ich würde auch vorschlagen, diese Bibliothek zu überprüfen, um das Routing und Parsen Ihrer Deep Links zu handhaben:

https://github.com/airbnb/DeepLinkDispatch

Sie können Anmerkungen verwenden, um Ihre Aktivität für einen bestimmten Deep Link-URI zu registrieren, und die Parameter werden für Sie extrahiert, ohne dass Sie die üblichen Schritte zum Abrufen der Pfadsegmente, zum Abgleichen usw. ausführen müssen. Sie können einfach Anmerkungen und Aktivitäten wie diese ausführen ::

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

0

Hey, ich habe die Lösung. Ich habe die Kategorie nicht als "Standard" festgelegt. Außerdem habe ich die Hauptaktivität für die Absichtsdaten verwendet. Jetzt verwende ich eine andere Aktivität für die Absichtsdaten. Danke für die Hilfe. :) :)


Klingt unwahrscheinlich (obwohl ich erkenne, dass dies eine alte Frage ist und sich möglicherweise etwas geändert hat). Von developer.android.com/guide/components/intents-filters.html#ifs "Für die Absicht, den Kategorietest zu bestehen, wird jede Kategorie in Das Intent- Objekt muss mit einer Kategorie im Filter übereinstimmen . Der Filter kann zusätzliche Kategorien auflisten, aber keine der ausgelassenen Kategorien weglassen. "
Noach Magedman

0

Sie müssen der CALLBACK_URL 'app: //' einen Pseudo-Hostnamen hinzufügen, der als URL keinen Sinn ergibt und nicht analysiert werden kann.


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
Dadurch werden zwei unsichtbare Iframes erstellt: Deep Link und Normal Link. Wenn die App installiert ist, wird sie vom Deep Link-Iframe gestartet. Wenn nicht, wird der normale Link angezeigt. Mit etwas zusätzlicher Arbeit könnte eine verzögerte Deep Linking implementiert werden, bei der die Deep Link aufgerufen wird, nachdem die App installiert wurde.
Dominic Cerisano

0

Schau @JRuns Antwort hier rein . Die Idee ist, HTML mit Ihrem benutzerdefinierten Schema zu erstellen und es irgendwo hochzuladen. Wenn Sie dann auf Ihren benutzerdefinierten Link in Ihrer HTML-Datei klicken, werden Sie zu Ihrer App weitergeleitet. Ich habe diesen Artikel für Android verwendet. Vergessen Sie jedoch nicht, das vollständige Name = "MyApp.Mobile.Droid.MainActivity"Namensattribut für Ihre Zielaktivität festzulegen.


0

Stand 15.06.2019

Was ich getan habe, ist, alle vier Möglichkeiten zum Öffnen der URL einzuschließen.

dh mit http/ httpsund 2 mit wwwim Präfix und 2 ohnewww

Mit dieser Option wird meine App jetzt automatisch gestartet, ohne dass ich aufgefordert werde, einen Browser und eine andere Option auszuwählen.

<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>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.