Cihaz özellikleri
Web API'leri Koprusu
Bildirimler, Paylaşım, Pano ve Daha Fazlası için Yerel Polyfill'ler
1Web API Köprüleri Nedir?#
Android WebView, Chrome'un desteklediği birçok modern Web API'sini desteklemez. Oluşturulan uygulamanız bu API'leri otomatik olarak polyfill eder, böylece web siteleri Chrome'daki gibi çalışır:
✅ Web Bildirimleri (Notification API)
✅ Web Paylaşımı (navigator.share)
✅ Pano (navigator.clipboard)
✅ window.close()
✅ target="_blank" bağlantıları ve window.open()
Kurulum gerekmez - bunlar oluşturulan her uygulamada otomatik çalışır.
2Web Bildirimleri#
Notification.requestPermission() ve new Notification() kullanan web siteleri gerçek Android bildirimleri gösterir.
- Android 13+ sürümünde kullanıcı bir sistem izin penceresi görür
- Android 12 ve altında bildirimlere varsayılan olarak izin verilir
- Bir bildirime dokunmak uygulamayı açar
- 'tag' seçeneği önceki bildirimlerin yerini alır (Web spesifikasyonuna uygun)
// 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'in yerel paylaşım sayfasını açar; kullanıcılar içeriği WhatsApp, Telegram, e-posta vb. ile paylaşabilir.
- title, text ve url desteklenir
- navigator.canShare() true döndürür
- Chrome'un paylaşım penceresi gibi çalışır
// Share content from your website:
navigator.share({
title: 'Check this out',
text: 'Amazing content!',
url: 'https://example.com/page'
});4Pano API'si#
navigator.clipboard.writeText() ve readText(), Android'in yerel panosuna köprülenir.
- writeText() metni sistem panosuna kopyalar
- readText() sistem panosundan okur
- İkisi de Promise döndürür (Web spesifikasyonuna uygun)
// Copy to clipboard:
await navigator.clipboard.writeText('Hello World');
// Read from clipboard:
const text = await navigator.clipboard.readText();5window.close() ve target="_blank"#
İki yaygın WebView eksiği de giderilir:
- window.close() - uygulama etkinliğini kapatır/bitirir (ödeme/kimlik doğrulama geri çağrı sayfaları için yararlıdır)
- target="_blank" bağlantıları - sessizce yok sayılmak yerine WebView içinde yüklenir
- window.open() çağrıları - aynı şekilde işlenir
Web sitenizde değişiklik gerekmez - bunlar kendiliğinden çalışır.
6Harici Bağlantılar için Alan Adı Eşleştirme#
'Harici Bağlantılar → Tarayıcıda Aç' ayarlandığında uygulama alan adlarını akıllıca eşleştirir:
- google.com ve www.google.com aynı alan adı olarak değerlendirilir
- Yalnızca gerçekten farklı alan adları Chrome'da açılır
- Aynı site içindeki yönlendirmeler WebView'da kalır
Bu, google.com gibi bir sitenin www.google.com'a yönlendirip yanlışlıkla Chrome'da açılması sorununu önler.
7UPI ve Ödeme Uygulaması Bağlantıları (Razorpay, GPay, PhonePe, Paytm)#
Şeması web sayfası olmayan her bağlantı, sahibi olan Android uygulamasını otomatik açar - kurulum yok, yapılandırılacak şema listesi yok:
- upi://pay - genel UPI niyeti (kullanıcı UPI uygulamasını seçer)
- paytmmp:// (Paytm), phonepe://, tez:// (Google Pay), gpay://
- tel:, mailto:, sms:, whatsapp://, tg://, intent://
Bu, bir sayfanın gidebildiği her yerde çalışır:
✅ Dokunulan bir <a href="upi://pay?..."> bağlantısı
✅ Bir JS yönlendirmesi (window.location.href = 'upi://...')
✅ Bir açılır pencere - window.open('paytmmp://...') - Razorpay Checkout'un UPI uygulamalarına devri böyle yapılır
Böylece Razorpay / Cashfree / PhonePe ödeme sayfaları olduğu gibi çalışır: müşteri bir UPI seçeneğine dokunur, ödeme uygulaması açılır, onaylar ve döndüğünde sayfanızın başarı işleyicisi tetiklenir. Telefonda bu şemayı işleyebilen uygulama yoksa kullanıcı boş bir hata sayfası yerine açık bir bildirim görür.
⚠️ Play Store uygulamasında DİJİTAL ürün mü satıyorsunuz? Google bunlar için Play Billing şart koşar - bunun yerine IAP rehberini kullanın. UPI/kart ödemesi fiziksel ürünler, hizmetler ve Play dışında dağıtılan uygulamalar içindir.
<!-- 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>8Tam Örnek - UPI ile Razorpay Checkout, Baştan Sona#
Razorpay Checkout kullanan, kopyalayıp yapıştırılabilir eksiksiz bir akış. Telefonda olanlar:
- Müşteri 'Pay ₹499'a dokunur → Razorpay Checkout sayfada açılır
- Müşteri UPI'yi seçer → UPI uygulaması otomatik açılır (uygulamanın sizin için yaptığı paytmmp:// / phonepe:// devri budur)
- Müşteri UPI uygulamasında onaylayıp döner - Android uygulamanızı kendiliğinden öne getirir
- İşleyici işlev bir ödeme kimliğiyle tetiklenir → başarı ekranınızı gösterin
- İptal ederlerse dismiss tetiklenir → yeniden denemelerine izin verin
rzp_test_XXXXXXXX yerine dashboard.razorpay.com'dan aldığınız anahtarı yazın. Önce bir key_test anahtarıyla test edin - Razorpay'in test modu UPI onayını simüle eder.
⚠️ Gerçek bir mağaza için ürünleri göndermeden önce ödemeyi sunucu tarafında doğrulayın (Razorpay webhook'u veya Orders API + imza kontrolü) - yalnızca tarayıcı tarafındaki işleyici taklit edilebilir.
<!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>