Czy link w przeglądarce Androida uruchamia moją aplikację?


229

Czy można utworzyć link, taki jak:

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

spowodować uruchomienie mojej aplikacji Anton?

Wiem, że działa to dla aplikacji Android Market z protokołem rynku, ale czy można zrobić coś podobnego z innymi aplikacjami?

Oto przykład linku, który uruchomi Android Market:

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

Aktualizacja: Odpowiedź, którą zaakceptowałem, udzielona przez eldarerathis, działa świetnie, ale chcę tylko wspomnieć, że miałem pewne problemy z kolejnością podelementów <intent-filter>tagu. Sugeruję, aby po prostu zrobić kolejny <intent-filter>z nowymi podelementami w tym tagu, aby uniknąć problemów, które miałem. Na przykład mój AndroidManifest.xmlwygląda następująco:

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

To rozwiązało mój problem, gdy nie mogę otworzyć aplikacji w telefonie komórkowym.
Unomono,

9
+1 za wzmiankę o kolejności znaczników xml. Nie ma to absolutnie żadnego sensu i nie jest nigdzie udokumentowane, ale odkryłem, że gdybym miał tag danych poniżej tagów akcji i kategorii, po prostu nie działałby.
Adam

Przekierowanie do aplikacji i prawidłowe cofnięcie się, jeśli aplikacja nie jest obecna, może być trochę koszmarem, biorąc pod uwagę złożoność wszystkich różnych przeglądarek Androida (Chrome, Default, Webviews, Firefox itp.). Usługa branch.io pomaga to zrobić i jest bezpłatna.
Alex Austin,

@Anton .... witam pana ... według twojego powyższego kodu, rozumiem tylko, jak obsługiwać dane z linku ... Czy możesz mi powiedzieć, jak mogę utworzyć link, który zawiera moje dane ... proszę o pomoc ja ... Chcę utworzyć link z danymi na temat zdarzenia kliknięcia przycisku.
Ravindra Kushwaha

1
⚠️ Potknąłem się o przeszkodę w debugowaniu, o której inni również powinni wiedzieć: linki działają z <a href=""> linków na stronach internetowych i po uruchomieniu z adb, ale teraz, gdy po prostu wpisujesz adres URL w telefonie komórkowym pasek adresu przeglądarki. ⚠️
Johannes Brodwall

Odpowiedzi:


96

Myślę, że będziesz chciał przyjrzeć się <intent-filter>elementowi twojego pliku Mainfest. W szczególności zapoznaj się z dokumentacją <data>podelementu.

Zasadniczo musisz zdefiniować własny schemat. Coś w stylu:

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

Następnie powinieneś być w stanie uruchomić aplikację z linkami rozpoczynającymi się od anton:schematu URI.


3
Spróbuj spojrzeć na ten wątek. Ma całkiem dobry przykład: stackoverflow.com/questions/2958701/…
eldarerathis

3
Dla porównania, dodanie CATEGORY_BROWSABLE oznacza, że ​​„Działanie docelowe można bezpiecznie wywołać w przeglądarce, aby wyświetlić dane, do których odwołuje się łącze - na przykład obraz lub wiadomość e-mail”.
greg7gkb

3
Działa to doskonale na poprzednich wersjach Androida, ale nie na Lollipop, jakieś rozwiązanie?
Salmaan

1
@eldarerathis to działa, jeśli aplikacja jest zamknięta, ale jeśli aplikacja działa w tle, a aktywność jest inna niż ta, do której dołączono filtr celowy, nie mogłem tego obsłużyć. Jak sobie z tym poradzisz we wszystkich działaniach? Czy umieszczasz filtr celowy w nich wszystkich?
Mustafa Güven

5
Ta odpowiedź jest nieaktualna. To nie będzie działać po Chrome 40. Schemat niestandardowy został wyłączony w Chrome z powodu problemów bezpieczeństwa
Utsav Gupta

280

NIE używaj własnego schematu niestandardowego w ten sposób !!! Schematy URI to globalna przestrzeń nazw sieci . Czy posiadasz program „anton:” na całym świecie? Nie? Więc NIE używaj go.

Jedną z opcji jest posiadanie strony internetowej i filtr zamiarów dla konkretnego identyfikatora URI na tej stronie. Na przykład to, co robi Market, aby przechwycić identyfikatory URI na swojej stronie internetowej:

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

Alternatywnie istnieje schemat „intent:”. Dzięki temu możesz opisać prawie każdy zamiar jako identyfikator URI, który przeglądarka spróbuje uruchomić po kliknięciu. Aby zbudować taki schemat, najlepszym sposobem jest po prostu napisanie kodu w celu skonstruowania zamierzonej intencji, a następnie wydrukowanie wyniku intent.toUri (Intent.URI_INTENT_SCHEME).

Możesz użyć akcji w tym celu, aby znaleźć dowolne działanie wspierające tę akcję. Przeglądarka automatycznie doda kategorię BROWSABLE do intencji przed jej uruchomieniem, ze względów bezpieczeństwa; spowoduje to również usunięcie każdego wyraźnego elementu dostarczonego z tego samego powodu.

Najlepszym sposobem na użycie tego, jeśli chcesz mieć pewność, że uruchamia się tylko twoja aplikacja, jest własna akcja o zasięgu i użycie Intent.setPackage (), aby powiedzieć, że zamiar będzie pasował tylko do pakietu aplikacji.

Kompromisy między nimi:

  • URI http wymagają posiadania własnej domeny. Użytkownik zawsze będzie miał opcję pokazania identyfikatora URI w przeglądarce. Ma bardzo ładne właściwości rezerwowe, w przypadku których jeśli aplikacja nie zostanie zainstalowana, po prostu wylądują na Twojej stronie internetowej.

  • zamierzone identyfikatory URI wymagają, aby Twoja aplikacja była już zainstalowana i tylko na telefonach z Androidem. Zezwalaj na prawie dowolne zamiary (ale zawsze zawiera kategorię BROWSABLE i nie obsługuje jawnych komponentów). Pozwalają one skierować uruchomienie tylko na Twoją aplikację, bez konieczności przechodzenia do przeglądarki lub innej aplikacji.


32
Z drugiej strony aplikacja Market obsługuje również market://linki :)
Felix

38
Wykorzystanie rynku było błędem: i zostało to usunięte.
hackbod

82
Powodem, dla którego ludzie używają niestandardowych schematów w Androidzie, jest to, że większość projektów jest rozwijana równolegle z (lub później) wersją iPhone'a, i to jest jedyny sposób, aby działał tam ...
LambergaR

12
zgadzam się z @LambergaR. Teraz musimy znaleźć sposób, aby link działający w wiadomości e-mail działał na 3 platformach (BB, iPhone, Android)
Ligi,

7
Każdy identyfikator URI, który umieścisz na swojej stronie w niestandardowym schemacie, nie będzie działał w żadnej przeglądarce internetowej, w której nie zainstalowano również aplikacji. Czy to nie wydaje ci się zepsute?
hackbod

13

Przepraszam za promowanie siebie, ale mam wtyczkę jQuery do uruchamiania aplikacji natywnych z łączy internetowych https://github.com/eusonlito/jquery.applink

Możesz użyć tego łatwo:

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

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

12

Zetknąłem się z tym problemem i zobaczyłem wiele absurdalnych stron. Nauczyłem się, że aby twoja aplikacja była dostępna do przeglądania, zmień kolejność elementów XML, to:

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

To działało dla mnie i może ci pomóc.


Piszę znacznik XML w tej samej kolejności, ale nie mogę otworzyć okna dialogowego selektora podczas pisania mojego adresu URL w przeglądarce Androida.
Sunit Kumar Gupta

nie widziałem dużej różnicy, a jeśli go użyję, działa idealnie .. Dziękuję :)
Muthu S

6

Oto mój przepis:

Utwórz statyczny kod HTML, który przekierowuje na żądany adres URL aplikacji, umieść tę stronę w Internecie.

W ten sposób udostępnione linki są „prawdziwymi” linkami, jeśli chodzi o Androida (będą „klikalne”).

„Udostępniasz” zwykły link HTTP, www.twoj.server.com/foo/bar.html Ten adres URL zwraca prosty 8-wierszowy kod HTML, który przekierowuje do identyfikatora URI aplikacji (window.location = "blah: // kuku") ( zauważ, że „bla” nie musi już być HTTP ani HTTPS).

Gdy już to uruchomisz, możesz rozszerzyć HTML o wszystkie fantazyjne możliwości, jak sugerowano powyżej.

Działa to z wbudowaną przeglądarką, Opera i Firefox (nie testowałem żadnej innej przeglądarki). Firefox pyta „Ten link musi zostać otwarty w aplikacji” (ok, anuluj). Inne przeglądarki najwyraźniej nie martwią się o bezpieczeństwo, po prostu otwierają aplikację, bez zadawania pytań.


Wspaniały! To zadziałało dla mnie. Dodaliśmy więc stronę HTML z linkiem do niestandardowego schematu, który przekierowuje do mojej aplikacji. Mój link to<a href="iamnearby://register_activate">Activate</a>
S. Koshelnyk

4

Po skonfigurowaniu aplikacji i niestandardowego schematu URL aplikacji kod javascript u góry strony odbierającej działa dla mnie zarówno na iOS, jak i na Androidzie:

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

Zostało to przetestowane tylko w przeglądarce Androida. Nie jestem pewien co do Firefoksa lub Opery. Kluczem jest to, że chociaż przeglądarka Androida nie wrzuci dla ciebie miłego wyjątku window.open(custom_url, '_blank'), zawiedzie i wróci, nullktóry możesz przetestować później.

Aktualizacja: za pomocą store_loc = "https://play.google.com/store/apps/details?id=com.raditaz";łącza do Google Play na Androida.


1
jaki jest punkt loadDateTime / timeOutDateTime? Czy to w jakiś sposób omija programy blokujące wyskakujące okienka czy coś takiego?
Matt Wolfe

to wydaje się nie działać w moich testach, window.open (...) zawsze otworzy nowe okno, nawet jeśli schemat nie jest obsługiwany.
jtomson

@MattWolfe przepraszam za spóźnioną odpowiedź. Na iPhonie (Safari) nie jest zgłaszany żaden wyjątek. Upłynął limit czasu, aby zamknąć przestarzałe okno w Safari, które pozostaje po przekierowaniu strony do aplikacji. Nie znalazłem sposobu na otwarcie adresu URL bez korzystania z Safari i większość innych aplikacji, które rozpoznają takie adresy URL, robią to samo. To była jedna z zalet „głębokiego linkowania” z Facebooka: nie przeglądasz tego starego okna po mobilnym Safari.
Pete,

@jtomson: Interesujące. Testowałem na emulatorze i różnych urządzeniach od Androida 2.1 do 3 (w tym czasie). Na jakim urządzeniu i wersji Androida testujesz?
Pete

4

Możesz rozważyć bibliotekę obsługującą precyzyjny link do Twojej aplikacji:

https://github.com/airbnb/DeepLinkDispatch

Możesz dodać filtr zamiaru do działania z adnotacjami, tak jak sugerują to osoby powyżej. Będzie obsługiwał routing i parsowanie parametrów dla wszystkich twoich głębokich linków. Na przykład twoja główna aktywność może mieć coś takiego:

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

Może również obsługiwać parametry zapytania.


1

Wypróbuj moją prostą sztuczkę:

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

i mój link HTML:

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

czy można zrobić <a href = „classRegister: prawdziwe ”> <- „prawdziwa” wartość dla klasy pliku

jednak ten skrypt działa dla linku 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);
        }

Jest to zasadniczo wezwanie do JavascriptInterfaceobejścia z obejściem, jest to właściwe obejście, jeśli potrzebujesz obsługi 2.3, gdzie JavaScriptInterface jest uszkodzony.
EpicPandaForce

1

Ta metoda nie wywołuje okna ujednoznacznienia z prośbą o otwarcie aplikacji lub przeglądarki.

Jeśli zarejestrujesz następujące elementy w swoim Manifeście

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

i na przykład kliknij ten adres URL w wiadomości e-mail w telefonie

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

wtedy Android spróbuje znaleźć aplikację z pakietem com.myApp, która odpowiada intencjom galerii i ma schemat myApp . W przeciwnym razie zabierze Cię do sklepu w poszukiwaniu com.myApp , która powinna być Twoją aplikacją.


Jak przejść do aktywności Androida?
Mohsen Emami
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.