Einen Link im Android-Browser erstellen Meine App starten?

229

Ist es möglich, einen Link zu erstellen wie:

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

meine Anton App starten lassen?

Ich weiß, dass dies für die Android Market-App mit dem Marktprotokoll funktioniert, aber kann etwas Ähnliches mit anderen Apps gemacht werden?

Hier ist ein Beispiel für einen Link, mit dem der Android Market gestartet wird:

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

Update: Die Antwort, die ich von eldarerathis akzeptiert habe, funktioniert hervorragend, aber ich möchte nur erwähnen, dass ich Probleme mit der Reihenfolge der Unterelemente des <intent-filter>Tags hatte. Ich schlage vor, Sie <intent-filter>erstellen einfach ein anderes mit den neuen Unterelementen in diesem Tag, um die Probleme zu vermeiden, die ich hatte. Zum Beispiel AndroidManifest.xmlsieht mein so aus:

<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
quelle
Dies löste mein Problem, wenn ich die Anwendung auf meinem Handy nicht öffnen kann.
Unomono
9
+1 für die Erwähnung der Reihenfolge der XML-Tags. Es macht absolut keinen Sinn und ist nirgendwo dokumentiert, aber ich stellte fest, dass es einfach nicht funktionieren würde, wenn ich das Daten-Tag unter den Aktions- und Kategorie-Tags hätte.
Adam
Das Umleiten zur App und das korrekte Zurückgreifen, wenn die App nicht vorhanden ist, kann angesichts der Komplexität der verschiedenen Android-Browser (Chrome, Standard, Webviews, Firefox usw.) ebenfalls ein Albtraum sein. Der branch.io- Dienst hilft dabei und ist kostenlos.
Alex Austin
@Anton .... hallo sir ... mit Ihrem obigen Code verstehe ich nur die Daten aus dem Link ... Können Sie mir bitte sagen, wie ich einen Link erstellen kann, der meine Daten enthält ... bitte helfen Sie Ich ... Ich möchte den Link mit Daten zum Button-Click-Ereignis erstellen.
Ravindra Kushwaha
1
⚠️Ich bin über eine Debugging-Hürde gestolpert, die auch andere beachten möchten: Die Links funktionieren über <a href=""> Links auf Webseiten und beim Start mit adb, aber jetzt, wenn Sie nur die URL in das Handy eingeben Browser-Adressleiste.⚠️
Johannes Brodwall

Antworten:

96

Ich denke, Sie möchten sich das <intent-filter>Element Ihrer Mainfest-Datei ansehen . Schauen Sie sich insbesondere die Dokumentation für das <data>Unterelement an.

Grundsätzlich müssen Sie Ihr eigenes Schema definieren. Etwas in der Art von:

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

Dann sollten Sie in der Lage sein, Ihre App mit Links zu starten, die mit dem anton:URI-Schema beginnen.

Eldarerathis
quelle
3
Schauen Sie sich diesen Thread an. Es hat ein ziemlich gutes Beispiel: stackoverflow.com/questions/2958701/…
eldarerathis
3
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
3
Dies funktioniert perfekt auf früheren Android-Versionen, aber nicht auf Lollipop, irgendeine Lösung?
Salmaan
1
@eldarerathist dies funktioniert, wenn die Anwendung geschlossen ist, aber wenn die Anwendung im Hintergrund ausgeführt wird und die Aktivität anders ist als die, an die der Absichtsfilter angehängt ist, konnte ich nicht damit umgehen. Wie schaffen Sie es, dass dies bei allen Aktivitäten funktioniert? Setzen Sie Vorsatzfilter in alle ein?
Mustafa Güven
5
Diese Antwort ist veraltet. Dies funktioniert nach Chrome 40 nicht. Das benutzerdefinierte Schema wurde aus Sicherheitsgründen in Chrome deaktiviert
Utsav Gupta
280

Bitte verwenden Sie NICHT Ihr eigenes benutzerdefiniertes Schema !!! URI-Schemata sind ein globaler Netzwerk- Namespace. Besitzen Sie das "anton:" - Programm weltweit? Nein? Dann benutze es NICHT.

Eine Möglichkeit besteht darin, eine Website und einen Absichtsfilter für einen bestimmten URI auf dieser Website zu haben. Dies ist beispielsweise das, was Market tut, um URIs auf seiner Website abzufangen:

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

Alternativ gibt es das Schema "Absicht:". Auf diese Weise können Sie nahezu jede Absicht als URI beschreiben, die der Browser beim Klicken zu starten versucht. Um ein solches Schema zu erstellen, schreiben Sie am besten einfach den Code, um die Absicht zu erstellen, die Sie starten möchten, und drucken Sie dann das Ergebnis von intent.toUri (Intent.URI_INTENT_SCHEME).

Sie können eine Aktion mit dieser Absicht verwenden, um Aktivitäten zu finden, die diese Aktion unterstützen. Der Browser fügt der Absicht aus Sicherheitsgründen automatisch die Kategorie BROWSABLE hinzu, bevor er sie startet. Aus dem gleichen Grund werden auch alle expliziten Komponenten entfernt, die Sie angegeben haben.

Der beste Weg, dies zu verwenden, wenn Sie sicherstellen möchten, dass nur Ihre App gestartet wird, ist mit Ihrer eigenen Aktion und mit Intent.setPackage (), dass der Intent nur mit Ihrem App-Paket übereinstimmt.

Kompromisse zwischen den beiden:

  • Für http-URIs benötigen Sie eine Domain, die Sie besitzen. Der Benutzer hat immer die Möglichkeit, den URI im Browser anzuzeigen. Es hat sehr schöne Fallback-Eigenschaften, bei denen Ihre App einfach auf Ihrer Website landet, wenn sie nicht installiert ist.

  • Vorsatz-URIs erfordern, dass Ihre App bereits installiert ist und nur auf Android-Handys. Die erlauben fast jede Absicht (haben aber immer die BROWSABLE-Kategorie enthalten und unterstützen keine expliziten Komponenten). Mit ihnen können Sie den Start nur auf Ihre App lenken, ohne dass der Benutzer die Möglichkeit hat, stattdessen zum Browser oder einer anderen App zu wechseln.

Hackbod
quelle
32
Andererseits behandelt die Market-App auch market://Links :)
Felix
38
Es war ein Fehler, den Markt zu nutzen: und dies wird entfernt.
Hackbod
82
Der Grund, warum Benutzer benutzerdefinierte Schemata in Android verwenden, liegt darin, dass die meisten Projekte parallel zur (oder nach) der iPhone-Version entwickelt wurden und dies nur so funktioniert ...
LambergaR
12
stimme @LambergaR zu. Jetzt müssen wir einen Weg finden, wie ein Link in einer E-Mail auf 3 Plattformen (BB, iPhone, Android)
funktioniert
7
Ein URI, den Sie mit einem benutzerdefinierten Schema in Ihre Webseite einfügen, funktioniert in keinem Webbrowser, in dem nicht auch Ihre Anwendung installiert ist. Kommt dir das nicht kaputt vor?
Hackbod
13

Ich entschuldige mich für die Werbung für mich selbst, habe aber ein jQuery-Plugin zum Starten nativer Apps über Weblinks https://github.com/eusonlito/jquery.applink

Sie können es einfach verwenden:

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

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

Ich habe mich auch diesem Problem gestellt und sehe viele absurde Seiten. Ich habe gelernt, dass Sie die Reihenfolge der XML-Elemente ändern müssen, um Ihre App durchsuchbar zu machen.

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

Das hat bei mir funktioniert und könnte Ihnen helfen.

Ashwani
quelle
Ich schreibe ein XML-Tag in der gleichen Reihenfolge, kann aber den Auswahldialog nicht öffnen, wenn ich meine URL im Android-Browser schreibe.
Sunit Kumar Gupta
Ich habe keinen großen Unterschied gesehen, und wenn ich diesen benutze, funktioniert er perfekt. Danke :)
Muthu S
6

Hier ist mein Rezept:

Erstellen Sie einen statischen HTML-Code, der zu Ihrer angeforderten App-URL umleitet, und stellen Sie diese Seite ins Web.

Auf diese Weise sind die von Ihnen freigegebenen Links für Android "echte" Links (sie können angeklickt werden).

Sie "teilen" einen regulären HTTP-Link, www.your.server.com/foo/bar.html Diese URL gibt einen einfachen 8-zeiligen HTML-Code zurück, der zum URI Ihrer App umleitet (window.location = "blah: // kuku") ( Beachten Sie, dass 'blah' nicht mehr HTTP oder HTTPS sein muss.

Sobald Sie dies eingerichtet haben, können Sie den HTML-Code mit allen ausgefallenen Funktionen erweitern, wie oben vorgeschlagen.

Dies funktioniert mit dem integrierten Browser, Opera und Firefox (haben keinen anderen Browser getestet). Firefox fragt 'Dieser Link muss mit einer Anwendung geöffnet werden' (ok, abbrechen). Andere Browser sorgen sich anscheinend nicht so sehr um die Sicherheit, sie öffnen einfach die App, ohne Fragen zu stellen.

JRun
quelle
Toll! Es hat bei mir funktioniert. Deshalb haben wir eine HTML-Seite mit einem Link zu einem benutzerdefinierten Schema hinzugefügt, das zu meiner App weiterleitet. Mein Link ist<a href="iamnearby://register_activate">Activate</a>
S. Koshelnyk
4

Sobald Sie die Absicht und das benutzerdefinierte URL-Schema für Ihre App eingerichtet haben, hat dieser Javascript-Code oben auf einer Empfangsseite sowohl für iOS als auch für Android für mich funktioniert:

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

Dies wurde nur im Android-Browser getestet. Ich bin mir bei Firefox oder Opera nicht sicher. Der Schlüssel ist, dass der Android-Browser zwar keine nette Ausnahme für Sie auslöst window.open(custom_url, '_blank'), aber fehlschlägt und zurückkehrt, nullwas Sie später testen können.

Update: Verwenden Sie store_loc = "https://play.google.com/store/apps/details?id=com.raditaz";diese Option, um auf Android auf Google Play zu verlinken.

Pete
quelle
1
Was ist der Sinn von loadDateTime / timeOutDateTime? Kommt das irgendwie um Popup-Blocker herum oder so?
Matt Wolfe
Dies scheint in meinen Tests nicht zu funktionieren. window.open (...) öffnet immer ein neues Fenster, auch wenn das Schema nicht behandelt wird.
Jtomson
@ MattWolfe Entschuldigung für die späte Antwort. Auf dem iPhone (Safari) wird keine Ausnahme ausgelöst. Das Zeitlimit dient dazu, das veraltete Fenster in Safari zu schließen, das übrig bleibt, nachdem die Seite zur App umgeleitet wurde. Ich habe keine Möglichkeit gefunden, eine URL zu öffnen, ohne Safari zu durchlaufen, und die meisten anderen Apps, die solche URLs erkennen, tun dasselbe. Das war einer der Vorteile von "Deep Linking" von Facebook: Sie erhalten dieses veraltete übrig gebliebene Fenster nicht, wenn Sie Mobile Safari durchlaufen.
Pete
@jtomson: Interessant. Ich habe auf dem Emulator und verschiedenen Geräten von Android 2.1 bis 3 (zu der Zeit) getestet. Auf welchem ​​Gerät und welcher Android-Version haben Sie getestet?
Pete
4

Möglicherweise möchten Sie eine Bibliothek in Betracht ziehen, um den Deep Link zu Ihrer App zu verwalten:

https://github.com/airbnb/DeepLinkDispatch

Sie können den Absichtsfilter zu einer kommentierten Aktivität hinzufügen, wie oben vorgeschlagen. Es übernimmt das Routing und Parsen von Parametern für alle Ihre Deep Links. Ihre MainActivity könnte beispielsweise Folgendes haben:

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

Es kann auch Abfrageparameter verarbeiten.

Christian
quelle
1

Versuchen Sie meinen einfachen Trick:

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

und mein HTML-Link:

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

oder Sie können machen <a href = "classRegister: wahr "> < ! - "true" Wert für die Klasse Dateinamen

Dieses Skript funktioniert jedoch für mailto link :)

        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
quelle
Dies ist im Wesentlichen ein Aufruf von a JavascriptInterfacemit der Problemumgehung. Dies ist die richtige Problemumgehung, wenn Sie 2.3 unterstützen müssen, bei dem JavascriptInterface fehlerhaft ist.
EpicPandaForce
1

Diese Methode ruft nicht den Disambiguierungsdialog auf, in dem Sie aufgefordert werden, entweder Ihre App oder einen Browser zu öffnen.

Wenn Sie Folgendes in Ihrem Manifest registrieren

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

und klicken Sie beispielsweise in einer E-Mail auf Ihrem Telefon auf diese URL

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

Dann wird Android versuchen, eine App mit dem Paket com.myApp zu finden , die auf Ihre Galerie- Absicht reagiert und ein myApp- Schema hat. Falls dies nicht möglich ist, werden Sie zum Store gebracht und suchen nach com.myApp , die Ihre App sein sollte.

Seekatze
quelle
Wie gehe ich zu einer Android-Aktivität?
Mohsen Emami