Запустите пользовательское приложение для Android из браузера Android

416

Кто-нибудь может подсказать, пожалуйста, как запустить мое приложение для Android из браузера Android?

Parimal Modi
источник

Ответы:

616

Используйте <intent-filter>с <data>элементом. Например, чтобы обработать все ссылки на twitter.com, вы должны поместить это <activity>в свой AndroidManifest.xml:

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

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

Конечно, если вы хотите обеспечить тесную интеграцию между вашим сайтом и вашим приложением, вы можете определить свою собственную схему:

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

Затем в вашем веб-приложении вы можете разместить ссылки вроде:

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

И когда пользователь щелкает по нему, ваше приложение будет запущено автоматически (потому что оно, вероятно, будет единственным, которое может обрабатывать my.special.scheme://тип Uris). Единственным недостатком этого является то, что если у пользователя нет установленного приложения, он получит неприятную ошибку. И я не уверен, что есть способ проверить.


Изменить: Чтобы ответить на ваш вопрос, вы можете использовать, getIntent().getData()который возвращает Uriобъект. Затем вы можете использовать Uri.*методы для извлечения необходимых данных. Например, скажем, пользователь щелкнул ссылку на 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"

Вы можете сделать вышеупомянутое в любом месте Activity, но вы, вероятно, захотите сделать это в onCreate(). Вы также можете использовать, params.size()чтобы получить количество сегментов пути в Uri. Посмотрите на javadoc или на сайт разработчика Android для других Uriметодов, которые вы можете использовать для извлечения определенных частей.

Феликс
источник
6
Большое спасибо за ваш быстрый ответ. Но можете ли вы сказать мне, как получить доступ к параметрам после "my.special.scheme: //".
Parimal Modi
4
Я отредактировал свой ответ, чтобы включить инструкции о том, как извлечь данные из Uri. Пожалуйста, отметьте этот ответ как принятый (только), если вы считаете это, нажав на флажок рядом с ним.
Феликс
9
Что делать, если целевое приложение для Android не установлено? Как справиться с этим.
Немо
13
Любой, кто, как и я, не может заставить работать эту схему, должен добавить android:exported="true"ее Activityв манифест. Проверьте этот ответ stackoverflow.com/a/13044911/1276636
Суфийский
4
Не уверен, как это работает для всего мира. Просто не работает на Chrome, и он всегда открывает ссылку в браузере, пока вы не разместите элемент «android: pathPrefix». Ответ в любом случае не имеет значений категории, как указано в документации. Если это все еще не работает для кого-то, отошлите это, пожалуйста: stackoverflow.com/a/21727055/2695276 PS: боролись за это несколько дней.
Раджат Шарма
71

Все вышеперечисленные ответы не работают для меня с CHROME28 января 2014 г.

мое приложение правильно запущено с http://example.com/someresource/ из таких приложений, как видеовстречи, gmail и т. д., но не из браузера Chrome.

чтобы решить эту проблему, чтобы он правильно запускался из CHROME, вы должны установить намеренный фильтр следующим образом

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

Обратите внимание pathPrefix элемент

Ваше приложение теперь будет отображаться в средстве выбора активности всякий раз, когда пользователь запрашивает http://example.com/someresource/ шаблон из браузера Chrome, щелкая ссылку в результатах поиска Google или на любом другом веб-сайте.

AndroidGecko
источник
Это мне очень помогло. Большое спасибо! Пожалуйста, оставьте свой ответ здесь, чтобы я мог наградить вас за вознаграждение! stackoverflow.com/questions/21663001/…
Влад Шнаковски
Что это за язык?
Dims
Здравствуйте, я знаю, что это слишком старое. Я также поражен в том же сценарии. Я указал pathPrefix, схему и хост, но он не работает. Я пробовал только со схемой, потом все заработало. Но когда я добавил хост, он перестал работать. Есть идеи, в чем может быть проблема?
Сима
Прошло несколько дней, пока я не пришел к этому ответу. Не уверен, как это работает для всего мира без элемента pathPrefix. Никогда не работал для меня на Chrome, несмотря на все в соответствии с документацией. Огромное спасибо.
Раджат Шарма
66

Пожалуйста, смотрите мой комментарий здесь: Сделать ссылку в браузере Android, чтобы запустить мое приложение?

Мы настоятельно не рекомендуем людям использовать свои собственные схемы, если они не определяют новую всемирную интернет-схему.

hackbod
источник
10
Hackbod является одним из инженеров Google за платформу Android. Вероятно, это хорошая идея следовать этому совету. На самом деле, похоже, что в Honeycomb сломалась поддержка пользовательских схем.
ЯМР
23
Я не могу нести ответственность за ограничения, наложенные на разработчиков iOS. ;)
hackbod
12
нести ответственность? нет. Но вы можете принять это во внимание, поскольку, независимо от того, нравится вам это или нет, эти ограничения накладываются на многих ваших разработчиков
ByteMe
6
hackbod отвечает на вопрос специально для Android. Там нет упоминания об iOS, поэтому не нужно принимать это во внимание.
Nilskp
4
@hackbod будет хорошей схемой использовать пространство имен схемы (т.е. href = "com.ourdomain.myapp // что угодно"), предполагая, что подобную ссылку можно найти на разных сайтах?
Жюльен Берубе
48

В моем случае я должен был установить две категории для, <intent-filter>и тогда это сработало:

<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
То же самое здесь, необходимо добавить дополнительную категорию.
КПК
Может кто-нибудь объяснить, каков фактический процесс достижения этой цели? Любая ссылка на точную реализацию, предпосылки будут полезны. Спасибо
Анкит Гарг
Проверено на установке dev. На самом деле я дал неправильное доменное имя. Виноват.
Анкит Гарг
Ответ с самым высоким рейтингом не сработал для меня, но это сработало. Спасибо.
EL45
25

Например, у вас есть следующие вещи:

Ссылка для открытия вашего приложения: http://example.com

Название пакета вашего приложения: com.example.mypackage

Тогда вам нужно сделать следующее:

1) Добавьте фильтр намерений к вашей активности (может быть любым действием, которое вы хотите. Для получения дополнительной информации проверьте документацию ).

        <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) Создайте HTML-файл для проверки ссылки или используйте этот метод.

<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) Используйте Mobile Chrome для тестирования

4) Вот и все.

И нет необходимости публиковать приложение в маркете, чтобы проверить глубокие ссылки =)

Также, для получения дополнительной информации, проверьте документацию и полезную презентацию .

Denshov
источник
Мне пришлось создать HTML-файл и загрузить его, чтобы заставить его работать. Интересно, почему, особенно второй, не работает напрямую из браузера (Chrome).
Makalele
18

Также следует <category android:name="android.intent.category.BROWSABLE"/>добавить фильтр намерений, чтобы действие было правильно распознано по ссылке.

Georgij
источник
4
Для справки добавление CATEGORY_BROWSABLE означает, что «целевое действие может быть безопасно вызвано браузером для отображения данных, на которые ссылается ссылка - например, изображение или сообщение электронной почты».
greg7gkb
Это существующая категория или вы предлагаете новую?
Аниш
Это существует. Очевидно, у вас должен быть отдельный хост сайта в разных тегах фильтра намерений, иначе это вызовет проблемы.
NoBugs
2
Не только BROWSABLE, но также android.intent.category.DEFAULT - так что ссылка может открываться при запуске в других приложениях, таких как электронная почта (не только браузеры)
AlikElzin-kilaka
8

Следующая ссылка содержит информацию о запуске приложения (если оно установлено) непосредственно из браузера. В противном случае он напрямую открывает приложение в игровом магазине, так что пользователь может легко загрузить.

https://developer.chrome.com/multidevice/android/intents

Варун Бхатия
источник
7

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

    <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>
Zoltan
источник
5

Хамарин порт Феликс ответ

В вашем MainActivity, добавьте это ( docs: Android.App.IntentFilterAttribute Class ):

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

Xamarin добавит следующее AndroidManifest.xmlдля вас:

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

И для того, чтобы получить параметры ( я тестировал в OnCreate of MainActivity ):

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

Насколько я знаю, выше можно добавить в любой вид деятельности, а не только MainActivity

Ноты:

  1. Когда пользователь нажимает на ссылку, ОС Android перезапускает ваше приложение (прервите предыдущий экземпляр, если есть, и запустите новое) , означает, что OnCreateсобытие приложения MainLauncher Activityбудет запущено снова.
  2. С помощью этой ссылки: <a href="my.special.scheme://host/arg1/arg2">в приведенном выше последнем коде значения фрагмента будут:
scheme: my.special.scheme
host: host
args: ["arg1", "arg2"]
first: arg1
second: arg2

Обновление: если Android создает новый экземпляр вашего приложения, вы должны добавить android:launchMode="singleTask"тоже.

Мехди Дехани
источник
3

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

https://github.com/airbnb/DeepLinkDispatch

Вы можете использовать аннотации, чтобы зарегистрировать свою активность для определенного URI глубокой ссылки, и она будет извлекать параметры для вас, не выполняя обычную процедуру получения сегментов пути, сопоставления и т. Д. Вы можете просто аннотировать и выполнять действия, подобные этой :

@DeepLink("somePath/{someParameter1}/{someParameter2}")
public class MainActivity extends Activity {
   ...
}
Кристиан
источник
0

Привет, я получил решение. Я не установил категорию как «По умолчанию». Также я использовал основной вид деятельности для данных. Теперь я использую другую активность для данных о намерениях. Спасибо за помощь. :)

Parimal Modi
источник
Звучит маловероятно (хотя я признаю, что это старый вопрос, и, возможно, все изменилось.) От developer.android.com/guide/components/intents-filters.html#ifs "Для намерения пройти тест по категориям каждая категория в объект Intent должен совпадать с категорией в фильтре . Фильтр может перечислять дополнительные категории, но он не может опускать те, которые находятся в намерении. "
Ноах Магедман
0

Вам нужно добавить псевдо-имя хоста в CALLBACK_URL 'app: //', которое не имеет смысла как URL и не может быть проанализировано.

Пол Линднер
источник
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 
}
T.Todua
источник
1
Это создает два невидимых фрейма: глубокая ссылка и нормальная ссылка. Если приложение установлено, его запустит глубокая ссылка iframe. Если нет, отображается нормальная ссылка. С некоторой дополнительной работой может быть реализована отложенная глубокая связь, когда глубокая ссылка вызывается после установки приложения.
Доминик Черизано
0

Посмотрите ответ @JRuns здесь . Идея состоит в том, чтобы создать HTML с вашей собственной схемой и загрузить его куда-нибудь. Затем, если вы нажмете на свою пользовательскую ссылку в html-файле, вы будете перенаправлены в ваше приложение. Я использовал эту статью для Android. Но не забудьте установить Name = "MyApp.Mobile.Droid.MainActivity"атрибут полного имени для вашей целевой деятельности.

С. Кошельник
источник
0

По состоянию на 15.06.2009

я включил все четыре возможности открыть URL.

т.е. с http/ httpsи 2 с wwwпрефиксом и 2 безwww

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

<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>
Вики Салунхе
источник