Fazer um link no navegador Android iniciar meu aplicativo?

229

É possível criar um link como:

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

fazer com que meu aplicativo Anton seja iniciado?

Sei que isso funciona para o aplicativo Android Market com o protocolo de mercado, mas algo semelhante pode ser feito com outros aplicativos?

Aqui está um exemplo de um link que iniciará o Android Market:

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

Atualização: A resposta que aceitei, fornecida por eldarerathis, funciona muito bem, mas só quero mencionar que tive alguns problemas com a ordem dos subelementos da <intent-filter>tag. Sugiro que você faça outro <intent-filter>com os novos subelementos dessa tag para evitar os problemas que tive. Por exemplo, minha AndroidManifest.xmlaparência é assim:

<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
fonte
Isso resolveu meu problema quando não consigo abrir o aplicativo no meu celular.
Unomono
9
+1 por mencionar a ordem das tags xml. Não faz absolutamente nenhum sentido e não está documentado em nenhum lugar, mas descobri que quando eu tinha a tag de dados abaixo das tags de ação e categoria, simplesmente não funcionava.
9113 Adam
Redirecionar para o aplicativo e retornar corretamente se o aplicativo não estiver presente também pode ser um pesadelo, dadas as complexidades de todos os diferentes navegadores Android (Chrome, Padrão, Webviews, Firefox, etc.). O serviço branch.io ajuda a fazer isso e é gratuito.
Alex Austin
@Anton .... olá senhor ... pelo seu código acima, eu só entendo lidar com os dados do link ... Você pode me dizer que como posso criar um link que contenha meus dados ... por favor ajude me ... Eu quero criar a ligação com dados sobre evento click do botão ..
Ravindra Kushwaha
1
Trip️Eu tropecei em um obstáculo de depuração do qual outras pessoas também deveriam estar cientes: os links funcionam a partir de <a href=""> links em páginas da web e quando iniciados com adb, mas agora quando você digita o URL no celular barra de endereço do navegador.⚠️
Johannes Brodwall

Respostas:

96

Eu acho que você vai querer olhar para o <intent-filter>elemento do seu arquivo Mainfest. Especificamente, dê uma olhada na documentação para o <data>subelemento.

Basicamente, o que você precisa fazer é definir seu próprio esquema. Algo ao longo das linhas de:

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

Em seguida, você poderá iniciar seu aplicativo com links que começam com o anton:esquema de URI.

eldarerathis
fonte
3
Tente dar uma olhada neste tópico. Ele tem um exemplo muito bom: stackoverflow.com/questions/2958701/…
eldarerathis
3
Para referência, adicionar CATEGORY_BROWSABLE significa que "A atividade de destino pode ser invocada com segurança pelo navegador para exibir dados referenciados por um link - por exemplo, uma imagem ou uma mensagem de email".
22612 greg7gkb
3
Isso funciona perfeitamente nas versões anteriores do Android, mas não no pirulito, alguma solução?
Salmaan
1
@eldarerathis isso funciona se o aplicativo estiver fechado, mas se o aplicativo estiver sendo executado em segundo plano e a atividade for diferente daquela que o filtro de intenção anexou, eu não poderia lidar com isso. Como você gerencia isso para trabalhar em todas as atividades? Você coloca o filtro de intenção em todos eles?
Mustafa Güven
5
Esta resposta é outdated..this não funcionará cromo pós 40. O esquema personalizado foi desativado no cromo por questões de segurança
Utsav Gupta
280

Por favor, NÃO use seu próprio esquema personalizado assim !!! Os esquemas de URI são um espaço de nomes global da rede . Você possui o esquema "anton:" em todo o mundo? Não? Então não o use.

Uma opção é ter um site e ter um filtro de intenção para um URI específico nesse site. Por exemplo, é isso que o Market faz para interceptar URIs em seu site:

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

Como alternativa, existe o esquema "intenção:". Isso permite que você descreva praticamente qualquer Intenção como um URI, que o navegador tentará iniciar quando clicado. Para criar esse esquema, a melhor maneira é escrever o código para construir o Intent que você deseja iniciar e, em seguida, imprimir o resultado de intent.toUri (Intent.URI_INTENT_SCHEME).

Você pode usar uma ação com essa intenção para encontrar qualquer atividade que suporte essa ação. O navegador adicionará automaticamente a categoria NAVEGÁVEL à intenção antes de iniciá-la, por motivos de segurança; também removerá qualquer componente explícito que você forneceu pelo mesmo motivo.

A melhor maneira de usar isso, se você deseja garantir que ele ative apenas seu aplicativo, é com sua própria ação no escopo e usando Intent.setPackage () para dizer que o Intent corresponderá apenas ao seu pacote de aplicativos.

Trade-offs entre os dois:

  • Os URLs http exigem que você tenha um domínio que você possui. O usuário sempre terá a opção de mostrar o URI no navegador. Possui propriedades de reserva muito agradáveis, nas quais, se o aplicativo não estiver instalado, eles simplesmente chegarão ao seu site.

  • URIs de intenção exigem que seu aplicativo já esteja instalado e apenas em telefones Android. Isso permite quase qualquer intenção (mas sempre inclui a categoria BROWSABLE e não suporta componentes explícitos). Eles permitem que você direcione o lançamento apenas para seu aplicativo, sem que o usuário tenha a opção de acessar o navegador ou qualquer outro aplicativo.

hackbod
fonte
32
Por outro lado, o aplicativo Market também lida com market://ligações :)
Felix
38
Foi um erro usar o market: e isso está sendo removido.
21711 hackbod
82
A razão pela qual as pessoas usam esquemas personalizados em Android é porque a maioria dos projetos são desenvolvidos em paralelo com (ou depois) da versão do iPhone, e esta é a única maneira de fazê-lo funcionar lá ...
LambergaR
12
concorde com @LambergaR. Agora precisamos descobrir uma maneira de fazer um link em um e-mail de trabalho em 3 plataformas (BB, iPhone, Android)
Maragues
7
Qualquer URI que você colocar na sua página da Web com um esquema personalizado não funcionará em nenhum navegador da Web que também não tenha seu aplicativo instalado. Isso não parece quebrado para você?
hackbod
13

Peço desculpas por me promover, mas tenho um plugin jQuery para iniciar aplicativos nativos a partir de links da web https://github.com/eusonlito/jquery.applink

Você pode usá-lo facilmente:

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

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

Eu também enfrentei esse problema e vi muitas páginas absurdas. Aprendi que, para tornar seu aplicativo navegável, altere a ordem dos elementos XML, isto é:

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

Isso funcionou para mim e pode ajudá-lo.

ashwani
fonte
Escrevo uma marca XML na mesma sequência, mas não consigo abrir a caixa de diálogo do seletor quando escrevo meu URL no navegador Android.
Sunit Kumar Gupta
eu não vi muita diferença, e se eu usar este que está funcionando perfeitamente .. Obrigado :)
Muthu S
6

Aqui está a minha receita:

Crie um HTML estático que redirecione para o URL do aplicativo solicitado, coloque essa página na web.

Dessa forma, os links que você compartilha são links "reais" no que diz respeito ao Android (eles serão "clicáveis").

Você 'compartilha' um link HTTP comum, www.your.server.com/foo/bar.html Este URL retorna um HTML simples de 8 linhas que redireciona para o URI do seu aplicativo (window.location = "blah: // kuku") ( observe que 'blah' não precisa mais ser HTTP ou HTTPS).

Depois de instalar e executar, você pode aumentar o HTML com todos os recursos sofisticados, conforme sugerido acima.

Isso funciona com o navegador embutido, Opera e Firefox (não testou nenhum outro navegador). O Firefox pergunta 'Este link precisa ser aberto com um aplicativo' (ok, cancelar). Outros navegadores aparentemente não se preocupam tanto com segurança, eles apenas abrem o aplicativo, sem fazer perguntas.

JRun
fonte
Ótimo! Funcionou para mim. Então, adicionamos a página html com um link para o esquema personalizado que redireciona para o meu aplicativo. Meu link é<a href="iamnearby://register_activate">Activate</a>
S. Koshelnyk
4

Depois de configurar o esquema de URLs de intenção e personalizado para seu aplicativo, esse código javascript na parte superior de uma página de recebimento funcionará para mim no iOS e no Android:

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

Isso foi testado apenas no navegador Android. Não tenho certeza sobre o Firefox ou Opera. A chave é que, apesar de o navegador Android não lançar uma boa exceção para você window.open(custom_url, '_blank'), ele falhará e retornará, o nullque você poderá testar posteriormente.

Atualização: use store_loc = "https://play.google.com/store/apps/details?id=com.raditaz";para vincular ao Google Play no Android.

Pete
fonte
1
qual é o ponto do loadDateTime / timeOutDateTime? De alguma forma isso contorna bloqueadores de pop-up ou algo assim?
Matt Wolfe
isso não parece funcionar nos meus testes, window.open (...) sempre abrirá uma nova janela, mesmo que o esquema não seja tratado.
Jtomson #
@MattWolfe desculpe pela resposta tardia. No iPhone (Safari), nenhuma exceção é lançada. O tempo limite está aí para fechar a janela obsoleta no Safari que resta depois que a página foi redirecionada para o aplicativo. Não encontrei uma maneira de abrir um URL sem passar pelo Safari e a maioria dos outros aplicativos que reconhecem URLs como esse fazem a mesma coisa. Essa foi uma das vantagens do "link direto" do Facebook: você não obtém aquela janela obsoleta de passar pelo Safari móvel.
Pete
@ jtomson: Interessante. Testei no emulador e em vários dispositivos do Android 2.1 a 3 (na época). Em qual dispositivo e versão do Android você estava testando?
Pete
4

Você pode considerar uma biblioteca para lidar com o link direto para o seu aplicativo:

https://github.com/airbnb/DeepLinkDispatch

Você pode adicionar o filtro de intenção a uma Atividade anotada, como as pessoas sugeridas acima. Ele manipulará o roteamento e a análise de parâmetros para todos os seus links diretos. Por exemplo, sua MainActivity pode ter algo parecido com isto:

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

Ele também pode manipular parâmetros de consulta também.

cristão
fonte
1

Tente meu truque simples:

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

e meu link html:

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

ou você pode fazer <a href = "classRegister: verdadeiro "> <- valor "true" para filename class

no entanto, este script funciona para o link 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);
        }
IRvanFauziE
fonte
Esta é essencialmente uma chamada para a JavascriptInterfacecom a solução alternativa, esta é a solução correta se você precisar oferecer suporte ao 2.3, onde o JavascriptInterface está com erros.
EpicPandaForce 13/03/2015
1

Este método não chama a caixa de diálogo de desambiguação solicitando que você abra seu aplicativo ou um navegador.

Se você registrar o seguinte em seu manifesto

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

e clique neste URL em um email no seu telefone, por exemplo

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

o android tentará encontrar um aplicativo com o pacote com.myApp que responda à intenção da sua galeria e tenha um esquema myApp . Caso contrário, você será levado à loja, procurando por com.myApp , que deve ser seu aplicativo.

gato do mar
fonte
Como ir para uma atividade android?
Mohsen Emami