Сделать ссылку в браузере Android для запуска моего приложения?


229

Можно ли сделать такую ​​ссылку как:

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

заставить мое приложение Anton запускаться?

Я знаю, что это работает для приложения Android Market с рыночным протоколом, но можно ли сделать нечто подобное с другими приложениями?

Вот пример ссылки, которая запускает Android Market:

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

Обновление: Ответ, который я принял от eldarera, отлично работает, но я просто хочу упомянуть, что у меня возникли некоторые проблемы с порядком подэлементов <intent-filter>тега. Я предлагаю вам просто сделать еще один <intent-filter>с новыми подэлементами в этом теге, чтобы избежать проблем, которые у меня были. Например, моя AndroidManifest.xmlвыглядит так:

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

Это решило мою проблему, когда я не могу открыть приложение на своем мобильном телефоне.
Unomono

9
+1 за упоминание порядка тегов xml. Это не имеет абсолютно никакого смысла и нигде не документировано, но я обнаружил, что, когда у меня есть тег данных ниже тегов action и category, он просто не будет работать.
Адам

Перенаправление на приложение и корректный откат назад, если приложение отсутствует, также может быть немного кошмаром, учитывая сложности всех различных браузеров Android (Chrome, Default, Webviews, Firefox и т. Д.). Служба branch.io помогает сделать это и является бесплатной.
Алекс Остин

@Anton .... привет, сэр ... по приведенному выше коду, я понимаю, что могу обрабатывать только данные из ссылки ... Скажите, пожалуйста, как мне создать ссылку, которая содержит мои данные ... помогите я ... Я хочу создать ссылку с данными о событии нажатия кнопки ..
Равиндра Кушваха

1
⚠️ Я преодолел препятствие отладки, о котором другие, возможно, захотят знать: ссылки работают с <a href=""> ссылок на веб-страницах и при запуске с adb, но теперь, когда вы просто набираете URL-адрес в мобильном телефоне адресная строка браузера.⚠️
Йоханнес Бродуолл

Ответы:


96

Я думаю, вы захотите посмотреть на <intent-filter>элемент вашего файла Mainfest. В частности, посмотрите на документацию для <data>подэлемента.

По сути, вам нужно определить свою собственную схему. Что-то вроде:

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

Тогда вы сможете запустить свое приложение со ссылками, которые начинаются со anton:схемы URI.


3
Попробуйте взглянуть на эту тему. Он имеет довольно хороший пример: stackoverflow.com/questions/2958701/...
eldarerathis

3
Для справки добавление CATEGORY_BROWSABLE означает, что «целевое действие может безопасно вызываться браузером для отображения данных, на которые ссылается ссылка - например, изображение или сообщение электронной почты».
greg7gkb

3
Это прекрасно работает на предыдущих версиях Android, но не на леденец, любое решение?
Салман

1
@eldarerathis это работает, если приложение близко, но если приложение работает в фоновом режиме и активность отличается от той, к которой прикреплен фильтр намерений, я не смог справиться с этим. Как вам удается работать во всех видах деятельности? Вы ставите намеренный фильтр во всех них?
Мустафа Гювен

5
Этот ответ устарел .. этот пост не будет работать после Chrome 40. Пользовательская схема была отключена в Chrome из-за проблем с безопасностью
Утсав Гупта,

280

Пожалуйста, НЕ используйте свою собственную схему! Схемы URI являются сетевым глобальным пространством имен. У вас есть схема "anton:" во всем мире? Нет? Тогда не используйте его.

Одним из вариантов является наличие веб-сайта и фильтр намерений для определенного URI на этом веб-сайте. Например, вот что Market делает для перехвата URI на своем веб-сайте:

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

В качестве альтернативы, есть схема «намерение:». Это позволяет вам описать практически любой Намерение как URI, который браузер попытается запустить при нажатии. Чтобы построить такую ​​схему, лучше всего написать код для создания намерения, которое вы хотите запустить, а затем распечатать результат intent.toUri (Intent.URI_INTENT_SCHEME).

Вы можете использовать действие с этим намерением, чтобы найти любое действие, поддерживающее это действие. Из соображений безопасности браузер автоматически добавит категорию BROWSABLE в намерение перед его запуском; он также удалит любой явный компонент, который вы предоставили по той же причине.

Лучший способ использовать это, если вы хотите, чтобы он запускал только ваше приложение, - это использовать собственное действие с заданной областью действия и использовать Intent.setPackage (), чтобы сказать, что Intent будет соответствовать только вашему приложению.

Компромиссы между двумя:

  • Для http URI необходим домен, которым вы владеете. Пользователь всегда получит возможность показать URI в браузере. У него очень хорошие резервные свойства, при которых, если ваше приложение не установлено, они просто окажутся на вашем веб-сайте.

  • целевые URI требуют, чтобы ваше приложение уже было установлено и только на телефонах Android. Разрешить почти любое намерение (но всегда включать категорию BROWSABLE и не поддерживать явные компоненты). Они позволяют направить запуск только на ваше приложение, при этом у пользователя нет возможности вместо этого перейти в браузер или любое другое приложение.


32
С другой стороны, приложение Market также обрабатывает market://ссылки :)
Феликс

38
Было ошибкой использовать market:, и это удаляется.
hackbod

82
Причина, по которой люди используют пользовательские схемы в Android, заключается в том, что большинство проектов разрабатываются параллельно с (или после) версией iPhone, и это единственный способ заставить его работать там ...
LambergaR

12
согласен с @LambergaR. Теперь нам нужно найти способ заставить ссылку в письме работать на 3 платформах (BB, iphone, Android)
Maragues

7
Любой URI, который вы добавили на свою веб-страницу по специальной схеме, не будет работать ни в одном веб-браузере, в котором также не установлено ваше приложение. Вам это не кажется сломанным?
hackbod

13

Я извиняюсь за продвижение себя, но у меня есть плагин jQuery для запуска нативных приложений по веб-ссылкам https://github.com/eusonlito/jquery.applink

Вы можете использовать это легко:

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

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

12

Я тоже сталкивался с этой проблемой и вижу много нелепых страниц. Я узнал, что для того, чтобы сделать ваше приложение доступным для просмотра, измените порядок элементов XML, вот так:

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

Это сработало для меня и может помочь вам.


Я пишу тег XML в той же последовательности, но не могу открыть диалоговое окно выбора, когда я пишу свой URL в браузере Android.
Сунит Кумар Гупта

я не вижу большой разницы, и если я использую этот, он работает отлично .. Спасибо :)
Muthu S

6

Вот мой рецепт:

Создайте статический HTML-код, который перенаправляет на запрошенный URL-адрес приложения, и разместите эту страницу в Интернете.

Таким образом, ссылки, которыми вы делитесь, являются «реальными» ссылками для Android (они будут «кликабельными»).

Вы «делитесь» обычной HTTP-ссылкой, www.your.server.com/foo/bar.html. Этот URL-адрес возвращает простой восьмистрочный HTML-код, который перенаправляет на URI вашего приложения (window.location = "blah: // kuku") ( обратите внимание, что «бла» больше не должен быть HTTP или HTTPS).

Как только вы это запустите, вы можете дополнить HTML всеми необычными возможностями, как предложено выше.

Это работает со встроенным браузером, Opera и Firefox (не проверял ни один другой браузер). Firefox спрашивает: «Эту ссылку нужно открыть с помощью приложения» (хорошо, отмена). Другие браузеры, очевидно, не слишком беспокоятся о безопасности, они просто открывают приложение, без вопросов.


Большой! Это сработало для меня. Поэтому мы добавили HTML-страницу со ссылкой на пользовательскую схему, которая перенаправляет на мое приложение. Моя ссылка<a href="iamnearby://register_activate">Activate</a>
С. Кошельник

4

Как только у вас есть намерение и настраиваемая схема URL для вашего приложения, этот JavaScript-код в верхней части принимающей страницы работал для меня как на iOS, так и на 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>

Это было проверено только в браузере Android. Я не уверен насчет Firefox или Opera. Ключ в том, что браузер Android не будет выдавать вам приятное исключение window.open(custom_url, '_blank'), он потерпит неудачу и вернет, nullкоторый вы можете проверить позже.

Обновление: используется store_loc = "https://play.google.com/store/apps/details?id=com.raditaz";для ссылки на Google Play на Android.


1
в чем смысл loadDateTime / timeOutDateTime? Это как-то обходит блокировщики всплывающих окон или что-то?
Мэтт Вулф

Это не работает в моих тестах, window.open (...) всегда будет открывать новое окно, даже если схема не обрабатывается.
Jtomson

@MattWolfe извините за поздний ответ. На iPhone (Safari) не исключение. Время ожидания истекло, чтобы закрыть устаревшее окно в Safari, оставшееся после перенаправления страницы в приложение. Я не нашел способа открыть URL-адрес, не пройдя через Safari, и большинство других приложений, которые распознают URL-адреса, делают то же самое. Это было одним из преимуществ «глубоких ссылок» из Facebook: вы не получите это устаревшее оставшееся окно от мобильного Safari.
Пит

@jtomson: интересно. Я тестировал на Эмуляторе и различных устройствах от Android 2.1 до 3 (на тот момент). На каком устройстве и версии Android вы тестировали?
Пит

4

Вы можете рассмотреть библиотеку для обработки глубокой ссылки на ваше приложение:

https://github.com/airbnb/DeepLinkDispatch

Вы можете добавить фильтр намерений к аннотированному действию, как это было предложено выше. Он будет обрабатывать маршрутизацию и анализ параметров для всех ваших глубоких ссылок. Например, ваша MainActivity может иметь что-то вроде этого:

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

Он также может обрабатывать параметры запроса.


1

Попробуйте мой простой трюк:

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

и моя ссылка HTML:

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

или вы можете сделать <A HREF = «classRegister: правда »> <- «истина» значение для класса файла

однако этот скрипт работает для 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);
        }

По сути, это вызов a JavascriptInterfaceс обходным путем, это правильный обходной путь, если вам нужно поддерживать 2.3, где JavascriptInterface содержит ошибки.
EpicPandaForce

1

Этот метод не вызывает диалоговое окно устранения неоднозначности с просьбой открыть приложение или браузер.

Если вы зарегистрируете следующее в своем манифесте

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

и нажмите этот URL-адрес из электронной почты на вашем телефоне, например

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

тогда android попытается найти приложение с пакетом com.myApp, которое отвечает вашим намерениям в галерее и имеет схему myApp . Если это невозможно, он доставит вас в магазин в поисках com.myApp , который должен быть вашим приложением.


Как перейти на андроид активность?
Мохсен Эмами
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.