Создать APK бесплатно

Функции устройства

Мост веб-API

Нативные полифилы для уведомлений, «Поделиться», буфера обмена и не только

1Что такое мосты Web API?#

Android WebView не поддерживает несколько современных Web API, которые есть в Chrome. Созданное вами приложение автоматически добавляет полифилы для этих API, поэтому сайты работают так же, как в Chrome:

✅ Веб-уведомления (Notification API)
✅ Web Share (navigator.share)
✅ Буфер обмена (navigator.clipboard)
✅ window.close()
✅ ссылки target="_blank" и window.open()

Настройка не нужна — это автоматически работает в каждом созданном приложении.

2Веб-уведомления#

Сайты, использующие Notification.requestPermission() и new Notification(), будут показывать настоящие уведомления Android.

  • На Android 13+ пользователь видит системное окно запроса разрешения
  • На Android 12 и ниже уведомления разрешены по умолчанию
  • Нажатие на уведомление открывает приложение
  • Параметр «tag» заменяет предыдущие уведомления (как в веб-спецификации)
// Your website JS — works the same as in Chrome:
Notification.requestPermission().then(function(result) {
  if (result === 'granted') {
    new Notification('Hello!', {
      body: 'This is a native Android notification',
      tag: 'my-notif'
    });
  }
});

3Web Share API#

navigator.share() открывает нативное окно «Поделиться» Android, позволяя отправлять контент в WhatsApp, Telegram, почту и другие приложения.

  • Поддерживает title, text и url
  • navigator.canShare() возвращает true
  • Работает точно так же, как окно «Поделиться» в Chrome
// Share content from your website:
navigator.share({
  title: 'Check this out',
  text: 'Amazing content!',
  url: 'https://example.com/page'
});

4API буфера обмена#

navigator.clipboard.writeText() и readText() связаны с нативным буфером обмена Android.

  • writeText() копирует текст в системный буфер обмена
  • readText() читает из системного буфера обмена
  • Оба возвращают Promise (как в веб-спецификации)
// Copy to clipboard:
await navigator.clipboard.writeText('Hello World');

// Read from clipboard:
const text = await navigator.clipboard.readText();

5window.close() и target="_blank"#

Также исправлены две распространённые проблемы WebView:

  • window.close() — закрывает/завершает активность приложения (полезно для страниц обратного вызова оплаты/авторизации)
  • ссылки target="_blank" — открываются внутри WebView, а не молча отбрасываются
  • вызовы window.open() — обрабатываются так же

Менять сайт не нужно — это просто работает.

Когда установлено «Внешние ссылки → Открывать в браузере», приложение умно сопоставляет домены:

  • google.com и www.google.com считаются одним и тем же доменом
  • В Chrome открываются только действительно другие домены
  • Перенаправления в пределах одного сайта остаются в WebView

Это устраняет проблему, когда сайт вроде google.com перенаправляет на www.google.com и случайно открывается в Chrome.

Любая ссылка, схема которой не является веб-страницей, автоматически открывает приложение Android, которому она принадлежит, — без настройки и без списка схем:

  • upi://pay — общий UPI-интент (пользователь выбирает своё приложение UPI)
  • paytmmp:// (Paytm), phonepe://, tez:// (Google Pay), gpay://
  • tel:, mailto:, sms:, whatsapp://, tg://, intent://

Это работает везде, куда может перейти страница:
✅ нажатая ссылка <a href="upi://pay?...">
✅ JS-перенаправление (window.location.href = 'upi://...')
✅ всплывающее окно — window.open('paytmmp://...') — именно так Razorpay Checkout передаёт управление приложениям UPI

Поэтому страницы оплаты Razorpay / Cashfree / PhonePe работают как есть: покупатель выбирает вариант UPI, открывается платёжное приложение, он подтверждает платёж, а обработчик успеха на вашей странице срабатывает, когда он возвращается. Если ни одно приложение на телефоне не может обработать схему, пользователь увидит понятное сообщение вместо пустой страницы ошибки.

⚠️ Продаёте ЦИФРОВЫЕ товары в приложении для Play Store? Google требует для них Play Billing — используйте руководство по покупкам в приложении. Оплата через UPI/карту подходит для физических товаров, услуг и приложений, распространяемых вне Play.

<!-- Simplest form — a plain UPI intent link. The user's phone
     shows every installed UPI app (GPay/PhonePe/Paytm/BHIM): -->
<a href="upi://pay?pa=merchant@bank&pn=MyStore&am=99.00&cu=INR&tn=Order%20123">
  Pay ₹99 via UPI
</a>

8Полный пример — Razorpay Checkout с UPI от начала до конца#

Полный пример, который можно скопировать, с использованием Razorpay Checkout. Что происходит на телефоне:

  1. Покупатель нажимает «Оплатить ₹499» → на странице открывается Razorpay Checkout
  2. Покупатель выбирает UPI → автоматически открывается его приложение UPI (это передача управления через paytmmp:// / phonepe://, которую приложение выполняет за вас)
  3. Покупатель подтверждает платёж в приложении UPI и возвращается — Android сам возвращает ваше приложение
  4. Функция-обработчик вызывается с ID платежа → покажите свой экран успеха
  5. dismiss срабатывает при отмене → дайте возможность повторить

Замените rzp_test_XXXXXXXX своим ключом из dashboard.razorpay.com. Сначала тестируйте с ключом key_test — в тестовом режиме Razorpay имитируется подтверждение UPI.

⚠️ В реальном магазине подтверждайте платёж на сервере (вебхук Razorpay или Orders API + проверка подписи) перед отправкой товара — обработчик в браузере можно подделать.

<!doctype html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>

<h2>Premium Plan — ₹499</h2>
<button id="payBtn">Pay ₹499</button>
<p id="result"></p>

<script>
document.getElementById('payBtn').onclick = function () {
  var rzp = new Razorpay({
    key: 'rzp_test_XXXXXXXX',      // your Razorpay Key ID
    amount: 49900,                  // paise — ₹499.00
    currency: 'INR',
    name: 'My Store',
    description: 'Premium Plan',
    prefill: { contact: '', email: '' },
    theme: { color: '#2563eb' },

    // Fires after the customer returns from their UPI app
    handler: function (response) {
      document.getElementById('result').textContent =
        '✅ Paid! Payment ID: ' + response.razorpay_payment_id;
      // Real store: send response.razorpay_payment_id to your
      // server / webhook flow and verify before unlocking anything.
    },

    modal: {
      ondismiss: function () {
        document.getElementById('result').textContent =
          'Payment cancelled — tap Pay to try again.';
      }
    }
  });
  rzp.open();
};
</script>

Эта страница создана из руководства по интеграции внутри самого приложения, поэтому в ней написано ровно то, что и в текущей сборке. Читать в формате Markdown.

Сверено с актуальным руководством 22.10.2026.