Fitur perangkat
Web APIs Bridge
Polyfill Asli untuk Notifikasi, Berbagi, Clipboard & Lainnya
1Apa Itu Web API Bridges?#
Android WebView tidak mendukung beberapa Web API modern yang didukung Chrome. Aplikasi yang Anda buat otomatis menambal API ini sehingga situs web berfungsi seperti di Chrome:
β
Web Notifications (Notification API)
β
Web Share (navigator.share)
β
Clipboard (navigator.clipboard)
β
window.close()
β
tautan target="_blank" & window.open()
Tidak perlu pengaturan - semua ini berfungsi otomatis di setiap aplikasi yang dibuat.
2Web Notifications#
Situs web yang memakai Notification.requestPermission() dan new Notification() akan menampilkan notifikasi Android sungguhan.
- Di Android 13+, pengguna mendapat dialog izin sistem
- Di Android 12 ke bawah, notifikasi diizinkan secara default
- Mengetuk notifikasi membuka aplikasi
- Opsi 'tag' menggantikan notifikasi sebelumnya (sesuai spesifikasi Web)
// 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() membuka lembar berbagi asli Android, sehingga pengguna dapat membagikan konten ke WhatsApp, Telegram, email, dan lainnya.
- Mendukung title, text, dan url
- navigator.canShare() mengembalikan true
- Bekerja persis seperti dialog berbagi Chrome
// Share content from your website:
navigator.share({
title: 'Check this out',
text: 'Amazing content!',
url: 'https://example.com/page'
});4Clipboard API#
navigator.clipboard.writeText() dan readText() dihubungkan ke clipboard asli Android.
- writeText() menyalin teks ke clipboard sistem
- readText() membaca dari clipboard sistem
- Keduanya mengembalikan Promise (sesuai spesifikasi Web)
// Copy to clipboard:
await navigator.clipboard.writeText('Hello World');
// Read from clipboard:
const text = await navigator.clipboard.readText();5window.close() & target="_blank"#
Dua celah umum WebView juga diperbaiki:
- window.close() - menutup/mengakhiri aktivitas aplikasi (berguna untuk halaman callback pembayaran/autentikasi)
- tautan target="_blank" - dimuat di dalam WebView alih-alih diabaikan begitu saja
- Panggilan window.open() - ditangani dengan cara yang sama
Tidak perlu mengubah situs web - semuanya langsung berfungsi.
6Pencocokan Domain untuk Tautan Eksternal#
Saat 'External Links β Open in Browser' diaktifkan, aplikasi mencocokkan domain dengan cerdas:
- google.com dan www.google.com dianggap sebagai domain yang sama
- Hanya domain yang benar-benar berbeda yang terbuka di Chrome
- Pengalihan di dalam situs yang sama tetap di WebView
Ini mencegah masalah ketika situs seperti google.com mengalihkan ke www.google.com dan tanpa sengaja terbuka di Chrome.
7UPI & Tautan Aplikasi Pembayaran (Razorpay, GPay, PhonePe, Paytm)#
Tautan apa pun yang skemanya bukan halaman web otomatis membuka aplikasi Android yang memilikinya - tanpa pengaturan, tanpa daftar skema yang perlu dikonfigurasi:
- upi://pay - intent UPI generik (pengguna memilih aplikasi UPI-nya)
- paytmmp:// (Paytm), phonepe://, tez:// (Google Pay), gpay://
- tel:, mailto:, sms:, whatsapp://, tg://, intent://
Ini berfungsi di mana pun halaman bisa bernavigasi:
β
Tautan <a href="upi://pay?..."> yang diketuk
β
Pengalihan JS (window.location.href = 'upi://...')
β
Popup - window.open('paytmmp://...') - cara Razorpay Checkout menyerahkan ke aplikasi UPI
Jadi halaman checkout Razorpay / Cashfree / PhonePe berfungsi apa adanya: pelanggan mengetuk opsi UPI, aplikasi pembayaran terbuka, mereka menyetujui, dan success handler halaman Anda berjalan saat mereka kembali. Jika tidak ada aplikasi di ponsel yang bisa menangani skema itu, pengguna melihat toast yang jelas, bukan halaman kesalahan kosong.
β οΈ Menjual barang DIGITAL di aplikasi Play Store? Google mewajibkan Play Billing untuk itu - gunakan panduan IAP. Checkout UPI/kartu untuk barang fisik, layanan, dan aplikasi yang didistribusikan di luar 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>8Contoh Lengkap - Razorpay Checkout dengan UPI, dari Awal sampai Akhir#
Alur lengkap yang bisa disalin-tempel memakai Razorpay Checkout. Yang terjadi di ponsel:
- Pelanggan mengetuk 'Pay βΉ499' β Razorpay Checkout terbuka di halaman
- Pelanggan memilih UPI β aplikasi UPI-nya terbuka otomatis (ini serah-terima paytmmp:// / phonepe:// yang ditangani aplikasi untuk Anda)
- Pelanggan menyetujui di aplikasi UPI dan kembali - Android membawa aplikasi Anda kembali dengan sendirinya
- Fungsi handler berjalan dengan ID pembayaran β tampilkan layar sukses Anda
- dismiss berjalan jika mereka membatalkan β biarkan mereka mencoba lagi
Ganti rzp_test_XXXXXXXX dengan kunci Anda dari dashboard.razorpay.com. Uji dulu dengan kunci key_test - mode uji Razorpay mensimulasikan persetujuan UPI.
β οΈ Untuk toko sungguhan, konfirmasi pembayaran di sisi server (webhook Razorpay atau Orders API + pemeriksaan signature) sebelum mengirim barang - handler di sisi browser saja bisa dipalsukan.
<!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>