JavaScript köprü API'si
Cihazdaki bildirimler
Sunucusuz gΓΆnderme ve zamanlama, POST_NOTIFICATIONS izni, tam alarmlar ve ΓΆzel sesler.
AppMint.enableNotifications yardımcı#
AppMint.enableNotifications()
Örnek
Android'in bildirim isteΔini reddeden veya atlayan kullanΔ±cΔ±lar iΓ§in tek Γ§aΔrΔ±da "Bildirimleri aΓ§": Android hΓ’lΓ’ gΓΆsterebiliyorsa izin penceresi, deΔilse bu uygulamanΔ±n bildirim ayarlarΔ± β ve kullanΔ±cΔ± geri dΓΆndΓΌΔΓΌnde yeni durum.
DΓΆner deΔer: AppMint.enableNotifications() - her zaman {state, changed, openedSettings} ile Γ§ΓΆzΓΌlen bir Promise; state deΔeri 'granted' | 'prompt' | 'blocked' | 'unavailable'. AppMint.getNotificationState() - o durumun Promise'i. AppMint.openNotificationSettings() - ayarlar ekranΔ± aΓ§Δ±ldΔ±ΔΔ±nda true Promise'i. Gerekenler: enableNotifications() iΕlevini kullanΔ±cΔ±nΔ±n dokunduΔu bir dΓΌΔmeden Γ§aΔΔ±rΔ±n; bildirimler iΓ§in derlemede Bildirimler (veya Push / HatΔ±rlatΔ±cΔ±lar) gerekir.
// A banner that only shows while notifications are off, and turns them on in one tap.
async function setupNotifBanner() {
if (!(window.AppMint && AppMint.enableNotifications)) return; // a browser: no banner
var banner = document.getElementById('notif-banner');
var state = await AppMint.getNotificationState();
banner.hidden = !(state === 'prompt' || state === 'blocked');
document.getElementById('notif-turn-on').onclick = async function () {
var r = await AppMint.enableNotifications();
banner.hidden = r.state === 'granted';
if (r.state === 'blocked') showToast('Switch on "Allow notifications" to get updates.');
};
}
setupNotifBanner();Kendi ayarlar sayfanΔ±zda dΓΌz bir "Bildirim ayarlarΔ±" baΔlantΔ±sΔ±:
document.getElementById('notif-settings').onclick = async function () {
var opened = window.AppMint && AppMint.openNotificationSettings && await AppMint.openNotificationSettings();
if (!opened) showToast('Open Settings > Apps > this app > Notifications.');
};Notlar: baΔlantΔ±sΔ± appmint://notifications/enable olan bir push veya uygulama iΓ§i mesaj dΓΌΔmesi, hiΓ§bir sayfa kodu olmadan aynΔ± akΔ±ΕΔ± Γ§alΔ±ΕtΔ±rΔ±r (sayfa appmint:notifications olayΔ±nΔ± duyar). UygulamanΔ±n push kitlesi ("Bildirimler aΓ§Δ±k / kapalΔ±") kullanΔ±cΔ± bunlarΔ± aΓ§ar aΓ§maz gΓΌncellenir.
AppMint.getNotificationState yardımcı#
window.AppMint.getNotificationState
Örnek
AppMint.enableNotifications ile birlikte belgelenmiştir - oradaki örnek bunu da gösterir.
Android'in bildirim isteΔini reddeden veya atlayan kullanΔ±cΔ±lar iΓ§in tek Γ§aΔrΔ±da "Bildirimleri aΓ§": Android hΓ’lΓ’ gΓΆsterebiliyorsa izin penceresi, deΔilse bu uygulamanΔ±n bildirim ayarlarΔ± β ve kullanΔ±cΔ± geri dΓΆndΓΌΔΓΌnde yeni durum.
DΓΆner deΔer: AppMint.enableNotifications() - her zaman {state, changed, openedSettings} ile Γ§ΓΆzΓΌlen bir Promise; state deΔeri 'granted' | 'prompt' | 'blocked' | 'unavailable'. AppMint.getNotificationState() - o durumun Promise'i. AppMint.openNotificationSettings() - ayarlar ekranΔ± aΓ§Δ±ldΔ±ΔΔ±nda true Promise'i. Gerekenler: enableNotifications() iΕlevini kullanΔ±cΔ±nΔ±n dokunduΔu bir dΓΌΔmeden Γ§aΔΔ±rΔ±n; bildirimler iΓ§in derlemede Bildirimler (veya Push / HatΔ±rlatΔ±cΔ±lar) gerekir.
// A banner that only shows while notifications are off, and turns them on in one tap.
async function setupNotifBanner() {
if (!(window.AppMint && AppMint.enableNotifications)) return; // a browser: no banner
var banner = document.getElementById('notif-banner');
var state = await AppMint.getNotificationState();
banner.hidden = !(state === 'prompt' || state === 'blocked');
document.getElementById('notif-turn-on').onclick = async function () {
var r = await AppMint.enableNotifications();
banner.hidden = r.state === 'granted';
if (r.state === 'blocked') showToast('Switch on "Allow notifications" to get updates.');
};
}
setupNotifBanner();Kendi ayarlar sayfanΔ±zda dΓΌz bir "Bildirim ayarlarΔ±" baΔlantΔ±sΔ±:
document.getElementById('notif-settings').onclick = async function () {
var opened = window.AppMint && AppMint.openNotificationSettings && await AppMint.openNotificationSettings();
if (!opened) showToast('Open Settings > Apps > this app > Notifications.');
};Notlar: baΔlantΔ±sΔ± appmint://notifications/enable olan bir push veya uygulama iΓ§i mesaj dΓΌΔmesi, hiΓ§bir sayfa kodu olmadan aynΔ± akΔ±ΕΔ± Γ§alΔ±ΕtΔ±rΔ±r (sayfa appmint:notifications olayΔ±nΔ± duyar). UygulamanΔ±n push kitlesi ("Bildirimler aΓ§Δ±k / kapalΔ±") kullanΔ±cΔ± bunlarΔ± aΓ§ar aΓ§maz gΓΌncellenir.
AppMint.openNotificationSettings yardımcı#
window.AppMint.openNotificationSettings
Örnek
AppMint.enableNotifications ile birlikte belgelenmiştir - oradaki örnek bunu da gösterir.
Android'in bildirim isteΔini reddeden veya atlayan kullanΔ±cΔ±lar iΓ§in tek Γ§aΔrΔ±da "Bildirimleri aΓ§": Android hΓ’lΓ’ gΓΆsterebiliyorsa izin penceresi, deΔilse bu uygulamanΔ±n bildirim ayarlarΔ± β ve kullanΔ±cΔ± geri dΓΆndΓΌΔΓΌnde yeni durum.
DΓΆner deΔer: AppMint.enableNotifications() - her zaman {state, changed, openedSettings} ile Γ§ΓΆzΓΌlen bir Promise; state deΔeri 'granted' | 'prompt' | 'blocked' | 'unavailable'. AppMint.getNotificationState() - o durumun Promise'i. AppMint.openNotificationSettings() - ayarlar ekranΔ± aΓ§Δ±ldΔ±ΔΔ±nda true Promise'i. Gerekenler: enableNotifications() iΕlevini kullanΔ±cΔ±nΔ±n dokunduΔu bir dΓΌΔmeden Γ§aΔΔ±rΔ±n; bildirimler iΓ§in derlemede Bildirimler (veya Push / HatΔ±rlatΔ±cΔ±lar) gerekir.
// A banner that only shows while notifications are off, and turns them on in one tap.
async function setupNotifBanner() {
if (!(window.AppMint && AppMint.enableNotifications)) return; // a browser: no banner
var banner = document.getElementById('notif-banner');
var state = await AppMint.getNotificationState();
banner.hidden = !(state === 'prompt' || state === 'blocked');
document.getElementById('notif-turn-on').onclick = async function () {
var r = await AppMint.enableNotifications();
banner.hidden = r.state === 'granted';
if (r.state === 'blocked') showToast('Switch on "Allow notifications" to get updates.');
};
}
setupNotifBanner();Kendi ayarlar sayfanΔ±zda dΓΌz bir "Bildirim ayarlarΔ±" baΔlantΔ±sΔ±:
document.getElementById('notif-settings').onclick = async function () {
var opened = window.AppMint && AppMint.openNotificationSettings && await AppMint.openNotificationSettings();
if (!opened) showToast('Open Settings > Apps > this app > Notifications.');
};Notlar: baΔlantΔ±sΔ± appmint://notifications/enable olan bir push veya uygulama iΓ§i mesaj dΓΌΔmesi, hiΓ§bir sayfa kodu olmadan aynΔ± akΔ±ΕΔ± Γ§alΔ±ΕtΔ±rΔ±r (sayfa appmint:notifications olayΔ±nΔ± duyar). UygulamanΔ±n push kitlesi ("Bildirimler aΓ§Δ±k / kapalΔ±") kullanΔ±cΔ± bunlarΔ± aΓ§ar aΓ§maz gΓΌncellenir.
Notification web standardı#
new Notification(title, options) / Notification.requestPermission()
Örnek
Standart Web Notifications API'si uygulama iΓ§inde Γ§alΔ±ΕΔ±r: new Notification() gerΓ§ek bir Android bildirimi gΓΆsterir, close() onu kaldΔ±rΔ±r ve Notification.requestPermission() Android izin penceresini gΓΆsterir ve kullanΔ±cΔ±nΔ±n yanΔ±tΔ±nΔ± bekler.
DΓΆner deΔer: Notification.permission, 'granted', 'denied' veya 'default' olur ve doΔrudan telefondan okunur (Ayarlar'daki bir deΔiΕiklik yenileme olmadan gΓΆrΓΌnΓΌr). requestPermission(), 'granted' veya 'denied' Promise'i dΓΆndΓΌrΓΌr (geri Γ§aΔrΔ± biΓ§imi de Γ§alΔ±ΕΔ±r). Yeni bir bildirim gΓΆnderildiΔinde show, izin yoksa error tetikler. Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) Bildirimler aΓ§Δ±n.
async function notifyWhenSaved() {
if (!('Notification' in window)) return;
let perm = Notification.permission;
if (perm === 'default') perm = await Notification.requestPermission();
if (perm !== 'granted') {
showMessage('Turn on notifications for this app in Settings to get alerts.');
return;
}
const n = new Notification('Saved', {
body: 'Your note was saved',
icon: 'https://example.com/avatar.png', // shown as the large icon
image: 'https://example.com/note.jpg', // big picture
tag: 'note' // same tag replaces the old one
});
n.onshow = function () { console.log('posted'); };
n.onerror = function () { console.log('not posted'); };
setTimeout(function () { n.close(); }, 60000); // removes it from the shade
}
document.getElementById('save').addEventListener('click', notifyWhenSaved);Geri Γ§aΔrΔ± biΓ§imi (eski kod):
Notification.requestPermission(function (result) {
if (result === 'granted') new Notification('Welcome!', { body: 'Alerts are on', silent: true });
});Service worker tarzΔ± (PWA kodu) da uygulama ΓΌzerinden gΓΆnderir, ancak yalnΔ±zca WebView'Δ±n kendisinde navigator.serviceWorker olmayan yerlerde (ΓΆrneΔin file:// veya http:// sayfalarΔ±):
if ('serviceWorker' in navigator && Notification.permission === 'granted') {
navigator.serviceWorker.ready.then(function (reg) {
return reg.showNotification('Backup done', { body: '12 files', tag: 'backup' });
});
}Bir dokunuΕ bildirimde click olayΔ±nΔ± tetikler - uygulama ΓΆne gelir ve sayfa onu alΔ±r. Uygulama kapalΔ±ysa (dokunuΕ onu baΕlattΔ±ysa) nesne yoktur, bu yΓΌzden pencere bunun yerine bir service worker'Δ±nkine benzer Εekilde bir notificationclick olayΔ± alΔ±r - event.notification.tag / title / body / data:
const n = new Notification('Order shipped', { body: '#7', tag: 'order-7', data: { orderId: 7 } });
n.onclick = () => openOrder(7); // the app was running
window.addEventListener('notificationclick', (e) => { // the tap started the app
if (e.notification.data && e.notification.data.orderId) openOrder(e.notification.data.orderId);
});Notlar: kullanΔ±lan seΓ§enekler: body, icon, image, tag, silent, data (JSON, 16 KB altΔ±nda). DokunuΕ, aΓ§Δ±lΔ±Ε ekranΔ± ve PIN ekranlarΔ± ΓΌzerinden sayfaya ulaΕΔ±r (arkasΔ±ndaki olay: appmint:notification-click). Android 12 ve eskisinde Γ§alΔ±Εma zamanΔ± izni yoktur, bu yΓΌzden kullanΔ±cΔ± bildirimleri kapatmadΔ±kΓ§a 'granted' olur. Web Push (pushManager.subscribe) desteklenmez; AppMint Push kullanΔ±n. DΓΌΔmeler, ilerleme veya yapΔ±ΕkΔ±n bildirim iΓ§in WebToApk.notify(...) kullanΔ±n. AynΔ± kod normal bir tarayΔ±cΔ±da da Γ§alΔ±ΕΔ±r.
__badgeSupported köprü#
window.WebToApk.__badgeSupported(): Boolean
Bu baΕlatΔ±cΔ±nΔ±n rozet sayΔ±sΔ± gΓΆsterip gΓΆsteremeyeceΔi (navigator.setAppBadge yalnΔ±zca o zaman vardΔ±r).
Örnek
navigator.setAppBadge varlΔ±ΔΔ±nΔ±n arkasΔ±ndaki iΓ§ aktarΔ±m. Sayfalar standart API'yi kullanΔ±r; bunu asla doΔrudan Γ§aΔΔ±rmayΔ±n β __ yΓΆntemleri haber verilmeden deΔiΕebilir.
DΓΆner deΔer: bu telefonun baΕlatΔ±cΔ±sΔ± rozet sayΔ±sΔ± gΓΆsteriyorsa true. Gerekenler: aΓ§Δ±lacak bir Εey yok.
Genel API'yi kullanın:
if ('setAppBadge' in navigator) navigator.setAppBadge(unreadCount);"Uygulama simgesinde rozet" ayarΔ±nΔ± yalnΔ±zca baΕlatΔ±cΔ±sΔ± sayΔ± gΓΆsterebilen telefonlarda gΓΆsterin:
function renderBadgeSetting() {
const row = document.getElementById('badge-setting');
// setAppBadge exists only when this launcher shows counts
row.hidden = !('setAppBadge' in navigator);
}
renderBadgeSetting();KullanΔ±cΔ± gelen kutusunu aΓ§tΔ±ΔΔ±nda, sayΔ± gΓΆsteren herhangi bir baΕlatΔ±cΔ±da sayΔ±yΔ± temizleyin:
function openInbox() {
showInbox();
if ('clearAppBadge' in navigator) {
navigator.clearAppBadge().catch(function (e) {
console.warn('badge not cleared', e.name); // NotAllowedError
});
}
}Notlar: Badging API yalnΔ±zca baΕlatΔ±cΔ±nΔ±n sayΔ± gΓΆsterebildiΔi yerlerde kurulur (Samsung, Huawei, Xiaomi, OPPO, Sony, β¦); Pixel tarzΔ± baΕlatΔ±cΔ±larda, rozet desteΔi olmayan bir tarayΔ±cΔ±daki gibi bulunmaz.
__closeNotification köprü#
window.WebToApk.__closeNotification(tag: String): Boolean
Notification.close(): sayfanΔ±n gΓΆnderdiΔi bir bildirimi etiketine gΓΆre kaldΔ±rΔ±r.
Örnek
Notification.prototype.close() arkasΔ±ndaki iΓ§ altyapΔ± β sayfalar new Notification(...) kullanΔ±r ve onun ΓΌzerinde close() Γ§aΔΔ±rΔ±r. Bir bildirimi etiketine gΓΆre bildirim gΓΆlgesinden kaldΔ±rΔ±r.
DΓΆner deΔer: kaldΔ±rma isteΔi yapΔ±ldΔ±ΔΔ±nda true (o etikete sahip hiΓ§bir Εey olmadΔ±ΔΔ±nda da); iΓ§ hatada false. Gerekenler: hiΓ§bir Εey.
Genel API'yi kullanın:
let uploadNote = null;
function showUploading() {
if (!('Notification' in window) || Notification.permission !== 'granted') return;
uploadNote = new Notification('Uploading…', { body: 'Keep the app open', tag: 'upload', silent: true });
uploadNote.onclose = function () { uploadNote = null; };
}
function uploadFinished() {
if (uploadNote) uploadNote.close(); // removes it from the notification shade
}Bildirime dokunulduΔunda doΔru sohbeti aΓ§Δ±n, sonra bildirim gΓΆlgesinden kaldΔ±rΔ±n:
function notifyNewMessage(msg) {
if (!('Notification' in window) || Notification.permission !== 'granted') return;
const n = new Notification(msg.from, {
body: msg.text,
tag: 'chat-' + msg.threadId, // one notification per chat
data: { threadId: msg.threadId }
});
n.onclick = function () {
openThread(n.data.threadId);
n.close();
};
}Beq saniye sonra kendiliΔinden kalkan kΔ±sa bir onay gΓΆsterin:
function confirmCopied() {
if (!('Notification' in window) || Notification.permission !== 'granted') return;
const n = new Notification('Link copied', { body: 'Paste it anywhere', tag: 'copied', silent: true });
setTimeout(function () { n.close(); }, 5000);
}Notlar: WebToApk.__closeNotification iΕlevini doΔrudan Γ§aΔΔ±rmayΔ±n; __ yΓΆntemleri haber verilmeden deΔiΕebilir. close(), bildirimin close olayΔ±nΔ± tetikler.
__setAppBadge köprü#
window.WebToApk.__setAppBadge(contents: Long): Boolean
navigator.setAppBadge(n): n >= 0 bir sayΔ±dΔ±r (0 temizler), -1 spesifikasyonun bayrak rozetidir.
Örnek
navigator.setAppBadge(count) / clearAppBadge() arkasΔ±ndaki iΓ§ aktarΔ±m. Sayfalar standart API'yi kullanΔ±r; bunu asla doΔrudan Γ§aΔΔ±rmayΔ±n β __ yΓΆntemleri haber verilmeden deΔiΕebilir.
DΓΆner deΔer: sayΔ± uygulandΔ±ysa true. Gerekenler: aΓ§Δ±lacak bir Εey yok.
Genel API'yi kullanın:
if ('setAppBadge' in navigator) navigator.setAppBadge(unreadCount);Simge sayΔ±sΔ±nΔ± okunmamΔ±Ε sayΔ±sΔ±yla uyumlu tutun ve sΔ±fΔ±rda temizleyin:
async function syncBadge(unread) {
if (!('setAppBadge' in navigator)) return;
try {
if (unread > 0) await navigator.setAppBadge(unread);
else await navigator.clearAppBadge();
} catch (e) {
console.warn('badge not applied', e.name); // NotAllowedError when the launcher refused it
}
}
syncBadge(messages.filter(function (m) { return !m.read; }).length);EΕitlenmemiΕ iΕ varken simgeye bir bayrak rozeti (sayΔ±sΔ±z) koyun:
function markPendingSync(hasPending) {
if (!('setAppBadge' in navigator)) return;
const p = hasPending
? navigator.setAppBadge() // no argument = flag badge; a count launcher shows 1
: navigator.clearAppBadge();
p.catch(function () {});
}Notlar: -1, spesifikasyonun bayrak rozetidir (sayΔ±sΔ±z) ve sayΔ± gΓΆsteren baΕlatΔ±cΔ± bunu 1 olarak gΓΆsterir.
cancelAllNotifications köprü#
window.WebToApk.cancelAllNotifications(): Boolean
POST_NOTIFICATIONS iznini okuma ve isteme, ve sayfanΔ±n zaten zamanladΔ±ΔΔ± bildirimleri yΓΆnetme. GΓΆnderme ve zamanlama kendi yΓΆntemlerinde belgelenmiΕtir.
Kendi baΕΔ±na deΔil, grubu Bildirim izni, iptal ve listeleme ΓΌzerinden aΓ§Δ±klanΔ±r.
Örnek
Bu uygulamanΔ±n zamanladΔ±ΔΔ± her hatΔ±rlatΔ±cΔ±yΔ± iptal eder.
DΓΆner deΔer: iΕlem tamamlandΔ±ΔΔ±nda true; yalnΔ±zca iΓ§ hatada false. Gerekenler: ek olarak hiΓ§bir Εey.
document.getElementById('reset-reminders').addEventListener('click', function () {
if (!(window.WebToApk && window.WebToApk.cancelAllNotifications)) return;
if (!confirm('Remove all your reminders?')) return;
const ok = WebToApk.cancelAllNotifications();
showMessage(ok ? 'All reminders removed' : 'Could not remove reminders');
});Oturum kapatΔ±lΔ±rken ΓΆnceki kullanΔ±cΔ±nΔ±n hatΔ±rlatΔ±cΔ±larΔ±nΔ± durdurun ve simge sayΔ±sΔ±nΔ± temizleyin:
async function signOut() {
if (window.WebToApk && window.WebToApk.cancelAllNotifications) {
WebToApk.cancelAllNotifications();
}
if ('clearAppBadge' in navigator) navigator.clearAppBadge().catch(function () {});
await auth.signOut();
showLoginScreen();
}TΓΌm gΓΌnlΓΌk programΔ± kayΔ±tlΔ± saatlerden yeniden oluΕturun (hepsini iptal edin, sonra her birini ekleyin):
function applyMedicineTimes(times) { // e.g. ['08:00', '20:00']
const b = window.WebToApk;
if (!(b && b.cancelAllNotifications)) return;
b.cancelAllNotifications();
times.forEach(function (hhmm, i) {
const parts = hhmm.split(':');
const at = new Date();
at.setHours(Number(parts[0]), Number(parts[1]), 0, 0);
if (at.getTime() <= Date.now()) at.setDate(at.getDate() + 1); // next occurrence
b.scheduleNotification('med-' + i, 'Medicine', 'Time for your ' + hhmm + ' dose',
String(at.getTime()), 'daily');
});
}Notlar: zamanlanmΔ±Ε listeyi temizler, bΓΆylece daha sonra hiΓ§bir Εey Γ§almaz ve yeniden baΕlatmadan sonra hiΓ§bir Εey tekrar kurulmaz. Tepsi'de zaten gΓΆrΓΌnen bildirimler orada kalΔ±r.
cancelNotification köprü#
window.WebToApk.cancelNotification(id: String): Boolean
POST_NOTIFICATIONS iznini okuma ve isteme, ve sayfanΔ±n zaten zamanladΔ±ΔΔ± bildirimleri yΓΆnetme. GΓΆnderme ve zamanlama kendi yΓΆntemlerinde belgelenmiΕtir.
Kendi baΕΔ±na deΔil, grubu Bildirim izni, iptal ve listeleme ΓΌzerinden aΓ§Δ±klanΔ±r.
Örnek
ZamanlanmΔ±Ε bir hatΔ±rlatΔ±cΔ±yΔ± kimliΔine gΓΆre iptal eder, bΓΆylece bir daha Γ§almaz.
DΓΆner deΔer: true (o kimlikte hatΔ±rlatΔ±cΔ± olmadΔ±ΔΔ±nda da); yalnΔ±zca iΓ§ hatada false. Gerekenler: ek olarak hiΓ§bir Εey (hatΔ±rlatΔ±cΔ±lar derleme zamanΔ±nda β° HatΔ±rlatΔ±cΔ±lar gerektirir).
function stopWaterReminder() {
if (!(window.WebToApk && window.WebToApk.cancelNotification)) return;
WebToApk.cancelNotification('water'); // the id you gave scheduleNotification / scheduleNotificationEx
// Check it is gone:
const left = JSON.parse(WebToApk.getScheduledNotifications() || '[]');
const stillThere = left.some(function (r) { return r.id === 'water'; });
console.log('water reminder still scheduled?', stillThere); // false
}AynΔ± kimlikle zamanlayan veya iptal eden, ayarlardaki bir hatΔ±rlatΔ±cΔ± anahtarΔ±:
document.getElementById('water-toggle').addEventListener('change', function (e) {
const b = window.WebToApk;
if (!(b && b.cancelNotification && b.scheduleNotification)) return;
if (e.target.checked) {
b.scheduleNotification('water', 'Drink water', 'Time for a glass of water',
String(Date.now() + 60 * 60 * 1000), 'hourly');
} else {
b.cancelNotification('water');
}
});Bir gΓΆrev silindiΔinde ona ait her hatΔ±rlatΔ±cΔ±yΔ± iptal edin:
function cancelTaskReminders(taskId) {
const b = window.WebToApk;
if (!(b && b.cancelNotification)) return;
let list = [];
try { list = JSON.parse(b.getScheduledNotifications() || '[]'); } catch (e) { list = []; }
list
.filter(function (r) { return r.id.indexOf('task-' + taskId + '-') === 0; })
.forEach(function (r) { b.cancelNotification(r.id); });
}Notlar: bu, henΓΌz Γ§almamΔ±Ε bir hatΔ±rlatΔ±cΔ±yΔ± (tek seferlik veya tekrarlayΔ±cΔ±) iptal eder. Tepsi'de zaten gΓΆrΓΌnen bir bildirimi kaldΔ±rmaz ve Εununla gΓΆnderilen bildirimleri etkilemez notify() / showNotification().
canOpenAppAtTime köprü#
window.WebToApk.canOpenAppAtTime(): String
ZamanlanmΔ±Ε bir bildirimin UYGULAMANIN KENDΔ°SΔ°NΔ° ekrana getirip getiremeyeceΔi (`openApp`). "granted" - tam ekran bir uyarΔ± kilit ekranΔ±nΔ±n ΓΌzerinde gΓΆrΓΌnΓΌr. "denied" - Android 14+ bunu vermedi; requestOpenAppPermission() Γ§aΔΔ±rΔ±n. UygulamanΔ±n arka planda sessizce kendini baΕlattΔ±ΔΔ± ΓΌΓ§ΓΌncΓΌ bir yanΔ±t yoktur: Android, Android 10'dan beri arka plan etkinlik baΕlatmalarΔ±nΔ± engeller ve tam ekran intent'i geriye kalanΔ±n tamamΔ±dΔ±r.
Örnek
openApp: true olan bir hatΔ±rlatΔ±cΔ±nΔ±n uygulamanΔ±n kendisini ekrana getirip getiremeyeceΔini sΓΆyler (kilit ekranΔ±nda da gΓΆrΓΌnen tam ekran bir uyarΔ±).
DΓΆner deΔer: eΕzamanlΔ± olarak bir dize: 'granted' veya 'denied'. Android 14'ΓΌn altΔ±nda her zaman 'granted'. Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) β° HatΔ±rlatΔ±cΔ±lar aΓ§Δ±n.
function prepareAlarm() {
const b = window.WebToApk;
if (!(b && b.canOpenAppAtTime)) return;
if (b.canOpenAppAtTime() === 'denied') {
showMessage('To open the app at alarm time, allow "full-screen notifications" for this app.');
b.requestOpenAppPermission();
return;
}
const t = new Date();
t.setDate(t.getDate() + 1);
t.setHours(7, 0, 0, 0); // tomorrow 07:00
b.scheduleNotificationEx('wake-up', JSON.stringify({
at: t.getTime(), repeat: 'daily',
title: 'Wake up', body: 'Good morning!',
openApp: true
}));
}
window.addEventListener('appmint:reminder', function (e) {
// e.detail.overLockScreen is true when the app was shown as a full-screen alert
if (e.detail.overLockScreen) showBigAlarmScreen(e.detail.id);
});Her iki alarm anahtarΔ±nΔ± mevcut durumlarΔ±yla gΓΆsteren bir ayarlar ekranΔ±:
function renderAlarmStatus() {
const b = window.WebToApk;
if (!(b && b.canOpenAppAtTime && b.getAlarmPrecision)) return;
const openApp = b.canOpenAppAtTime(); // 'granted' | 'denied'
const precision = b.getAlarmPrecision(); // 'exact' | 'inexact' | 'unavailable'
document.getElementById('open-app-state').textContent =
openApp === 'granted' ? 'Opens over the lock screen' : 'Notification only';
document.getElementById('open-app-fix').hidden = openApp === 'granted';
document.getElementById('timing-state').textContent =
precision === 'exact' ? 'On the minute' : 'May be late';
}
renderAlarmStatus();
document.addEventListener('visibilitychange', function () {
if (!document.hidden) renderAlarmStatus(); // back from Settings
});KayΔ±tlΔ± alarmlar uygulamayΔ± aΓ§acak Εekilde kurulmuΕ ama Android Εu anda buna izin vermiyorsa uyarΔ±n:
function checkSavedAlarms() {
const b = window.WebToApk;
if (!(b && b.canOpenAppAtTime && b.getScheduledNotifications)) return;
if (b.canOpenAppAtTime() === 'granted') return;
// [{ id, title, body, trigger, repeat, options }] - options is the JSON string you scheduled
const items = JSON.parse(b.getScheduledNotifications());
const affected = items.filter(function (r) {
try { return JSON.parse(r.options || '{}').openApp === true; } catch (e) { return false; }
});
if (affected.length) {
showMessage(affected.length + ' alarm(s) will only show a notification. Tap "Allow" to let them open the app.');
}
}Notlar: 'denied' iken, bir openApp hatΔ±rlatΔ±cΔ±sΔ± yine de bir heads-up bildirimi gΓΆnderir ama uygulama kendiliΔinden aΓ§Δ±lmaz. Android, bir uygulamanΔ±n arka planda kendini baΕlatmasΔ± iΓ§in baΕka bir yola izin vermez.
clearNotificationSounds köprü#
window.WebToApk.clearNotificationSounds(): Int
Kopyalanan ses dosyalarΔ±nΔ± bΔ±rakΔ±r ve kaΓ§ tanesinin silindiΔini dΓΆndΓΌrΓΌr. Bir bildirim (veya zamanlanmΔ±Ε bir hatΔ±rlatΔ±cΔ±, tetiklendiΔinde) o sesi bir sonraki kullandΔ±ΔΔ±nda dosya yeniden kopyalanΔ±r β aynΔ± dosya adΔ±nΔ± gΓΆstermeye devam eden mevcut bir kanalda da (NotificationBridge.restoreBundleSound).
Örnek
Γzel bildirim seslerinizin, uygulamanΔ±n paketinizden yaptΔ±ΔΔ± kopyalarΔ±nΔ± siler.
DΓΆner deΔer: eΕzamanlΔ± olarak bir sayΔ±: kaΓ§ dosyanΔ±n silindiΔi. Gerekenler: hiΓ§bir Εey.
Temizleyin, sonra hΓ’lΓ’ kullandΔ±ΔΔ±nΔ±z sesleri geri koyun:
document.getElementById('reset-sounds').addEventListener('click', function () {
const b = window.WebToApk;
if (!(b && b.clearNotificationSounds)) return;
const removed = b.clearNotificationSounds();
// Sounds still in use must be copied again, or they play the default sound:
['/audio/alarm.mp3', '/audio/chime.mp3'].forEach(function (path) {
if (!b.prepareNotificationSound(path)) console.warn('missing sound', path);
});
showMessage(removed + ' sound file(s) refreshed');
});Kopyalanan ses dosyalarΔ±nΔ± boΕaltan ve kaΓ§Δ±nΔ±n kaldΔ±rΔ±ldΔ±ΔΔ±nΔ± sΓΆyleyen bir depolama ekranΔ± dΓΌΔmesi:
document.getElementById('free-space').addEventListener('click', function () {
const b = window.WebToApk;
if (!(b && b.clearNotificationSounds)) return;
const removed = b.clearNotificationSounds();
showMessage(removed === 0 ? 'No sound files to remove.' : 'Removed ' + removed + ' sound file(s).');
});Oturum kapatΔ±lΔ±rken her hatΔ±rlatΔ±cΔ±yΔ± iptal edin ve bu kullanΔ±cΔ±ya ait ses kopyalarΔ±nΔ± silin:
function signOutAndReset() {
const b = window.WebToApk;
if (b && b.cancelAllNotifications) b.cancelAllNotifications();
if (b && b.clearNotificationSounds) b.clearNotificationSounds();
localStorage.removeItem('alarmSound');
goToLoginScreen();
}Notlar: buna nadiren ihtiyaΓ§ duyarsΔ±nΔ±z; kopyalar kΓΌΓ§ΓΌktΓΌr. Bir ses, onu kullanan bir Εey olduΔunda yeniden kopyalanΔ±r β notify(), Γ§aldΔ±ΔΔ±nda bir hatΔ±rlatΔ±cΔ±, scheduleNotificationEx veya prepareNotificationSound(path) β zaten var olan bir bildirim kanalΔ±nda da, bΓΆylece ΓΆzel ses Γ§almaya devam eder.
enableNotifications köprü#
window.WebToApk.enableNotifications(callbackId: String)
KullanΔ±cΔ±yΔ± bildirimlere geri getirir: hΓ’lΓ’ gΓΆsterilebiliyorsa sistem penceresi, deΔilse uygulamanΔ±n bildirim ayarlarΔ±. `window.__appmintReplies[callbackId]` deΔerini {state, changed, openedSettings} ile Γ§ΓΆzer (AppMint.enableNotifications() promise sarmalayΔ±cΔ±sΔ±dΔ±r).
Örnek
Bildirimleri reddeden veya atlayan bir kullanΔ±cΔ±yΔ± geri getirir: hΓ’lΓ’ gΓΆsterilebiliyorsa Android'in izin penceresini gΓΆsterir, deΔilse bu uygulamanΔ±n bildirim ayarlarΔ±nΔ± aΓ§ar ve kullanΔ±cΔ± geri dΓΆndΓΌΔΓΌnde yanΔ±t verir.
DΓΆner deΔer: doΔrudan hiΓ§bir Εey. {state, changed, openedSettings} yanΔ±tΔ± window.__appmintReplies[callbackId] iΓ§ine iletilir; state 'granted' | 'prompt' | 'blocked' | 'unavailable' olur, changed Γ§aΔrΔ±dan ΓΆncekinden farklΔ±ysa true olur, openedSettings ayarlar ekranΔ± kullanΔ±ldΔ±ysa true olur. Zaten 'granted' (veya 'unavailable') ise hemen yanΔ±t verir. Gerekenler: kullanΔ±cΔ±nΔ±n dokunduΔu bir dΓΌΔmeden Γ§aΔΔ±rΔ±n; bildirimler iΓ§in derlemede Bildirimler (veya Push / HatΔ±rlatΔ±cΔ±lar) gerekir.
AppMint.enableNotifications() Promise sarmalayΔ±cΔ±sΔ±nΔ± tercih edin. Kendi yanΔ±tlarΔ±nΔ± yΓΆneten kod iΓ§in ham Γ§aΔrΔ±:
function enableNotificationsRaw() {
return new Promise(function (resolve) {
if (!(window.WebToApk && WebToApk.enableNotifications)) return resolve({ state: 'unavailable', changed: false, openedSettings: false });
var replies = window.__appmintReplies = window.__appmintReplies || {};
var id = 'my_notif_' + Date.now();
replies[id] = resolve;
WebToApk.enableNotifications(id);
});
}
document.getElementById('turn-on-btn').onclick = async function () {
var r = await enableNotificationsRaw();
if (r.state === 'granted') document.getElementById('notif-banner').hidden = true;
};BitmiΕ her akΔ±Ε da duyurulur, bir push dΓΌΔmesinin baΕlattΔ±ΔΔ± akΔ±Ε dahil (appmint://notifications/enable):
window.addEventListener('appmint:notifications', function (e) {
// e.detail = { state, changed, openedSettings }
if (e.detail.state === 'granted') document.getElementById('notif-banner').hidden = true;
});Notlar: baΔlantΔ±sΔ± appmint://notifications/enable olan bir push veya uygulama iΓ§i mesaj dΓΌΔmesi bu akΔ±ΕΔ±n aynΔ±sΔ±nΔ± Γ§alΔ±ΕtΔ±rΔ±r; appmint://notifications/settings ayarlar ekranΔ±nΔ± aΓ§ar. UygulamanΔ±n push kitlesi yeni durumu hemen gΓΆrΓΌr.
getAlarmPrecision köprü#
window.WebToApk.getAlarmPrecision(): String
"exact" - hatΔ±rlatΔ±cΔ±lar tam dakikada Γ§alar. "inexact" - kullanΔ±cΔ± (veya OEM) bu uygulama iΓ§in tam alarmlarΔ± kapattΔ±, bu yΓΌzden Doze bunlarΔ± dakikalarca toplu halde erteleyebilir. DΓΌzeltmek iΓ§in [requestExactAlarms] isteyin. "unavailable" - Android 12+ ve sistem alarm hizmetine ulaΕΔ±lamadΔ±, bu yΓΌzden hassasiyet okunamaz (Εimdi zamanlanan bir hatΔ±rlatΔ±cΔ± da Γ§almayabilir). ZamanΔ±nda olmasΔ± gereken bir sayfa bunu varsaymak yerine denetlemelidir. @return `"exact"`, `"inexact"` veya `"unavailable"`.
Örnek
HatΔ±rlatΔ±cΔ±larΔ±n tam dakikada mΔ± Γ§alacaΔΔ±nΔ±, yoksa kullanΔ±cΔ± (veya telefon ΓΌreticisi) bu uygulama iΓ§in tam alarmlarΔ± kapattΔ±ΔΔ± iΓ§in geΓ§ kalabileceΔini sΓΆyler.
DΓΆner deΔer: eΕzamanlΔ± olarak bir dize: 'exact', 'inexact' (pil tasarrufuyla, genellikle dakikalarca, toplu halde ertelenebilir) veya 'unavailable' (telefonda alarm hizmeti yok). Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) β° HatΔ±rlatΔ±cΔ±lar aΓ§Δ±n.
function checkReminderTiming() {
if (!(window.WebToApk && window.WebToApk.getAlarmPrecision)) return;
const precision = WebToApk.getAlarmPrecision();
const warn = document.getElementById('timing-warning');
warn.hidden = precision === 'exact';
if (precision === 'inexact') {
warn.textContent = 'Reminders may be a few minutes late. Tap to allow exact alarms.';
warn.onclick = function () { WebToApk.requestExactAlarms(); };
}
}
checkReminderTiming();
// Re-check when the user returns from Settings:
document.addEventListener('visibilitychange', function () {
if (!document.hidden) checkReminderTiming();
});Bir uyandΔ±rma alarmΔ± kurmadan ΓΆnce denetleyin ve geΓ§ kalabileceΔini kullanΔ±cΔ±ya sΓΆyleyin:
function setWakeUp(atMs) {
const b = window.WebToApk;
if (!(b && b.getAlarmPrecision && b.scheduleNotificationEx)) return;
const precision = b.getAlarmPrecision();
if (precision === 'unavailable') { showMessage('Alarms cannot be set on this phone right now.'); return; }
b.scheduleNotificationEx('wake', JSON.stringify({ at: atMs, title: 'Wake up', body: 'Good morning', openApp: true }));
if (precision === 'inexact') {
showMessage('Alarm set, but it may ring a few minutes late. Allow exact alarms for on-time alarms.');
}
}HatΔ±rlatΔ±cΔ± zamanlamasΔ±nΔ± ayarlar ekranΔ±nda bir satΔ±r olarak gΓΆsterin:
function renderTimingRow() {
if (!(window.WebToApk && window.WebToApk.getAlarmPrecision)) return;
const labels = {
exact: 'Reminders arrive on time',
inexact: 'Reminders may be a few minutes late',
unavailable: 'Reminders are not available on this phone'
};
document.getElementById('timing-row').textContent = labels[WebToApk.getAlarmPrecision()];
}
renderTimingRow();Notlar: Android 11 ve eskisi her zaman 'exact' yanΔ±tΔ±nΔ± verir. 'inexact' bir hatΔ±rlatΔ±cΔ± yine de Γ§alar, ama tam dakikada deΔil.
getAlarmSupport köprü#
window.WebToApk.getAlarmSupport(): String
`scheduleNotificationEx(id, {alarm: true, ...})` iΕlevinin Εimdi zamanlanΔ±p zamanlanamayacaΔΔ±: "ready" | "not_enabled" (bu derlemede Alarm saati kapalΔ±) | "needs_exact_alarm" (requestExactAlarms Γ§aΔΔ±rΔ±n) | "needs_notification_permission".
Örnek
Bu telefonda Εimdi bir alarm saati (scheduleNotificationEx(id, { alarm: true, ... })) kurulup kurulamayacaΔΔ±nΔ± ve kurulamΔ±yorsa kullanΔ±cΔ±nΔ±n ΓΆnce neye izin vermesi gerektiΔini sΓΆyler.
DΓΆner deΔer: eΕzamanlΔ± olarak bir dize: 'ready', 'not_enabled' (uygulama π Alarm saati olmadan derlendi), 'needs_exact_alarm' (Android 12+: bu uygulama iΓ§in tam alarmlar kapalΔ± β requestExactAlarms() Γ§aΔΔ±rΔ±n) veya 'needs_notification_permission' (Android 13+: bildirim izni yok, bu yΓΌzden Kapat dΓΌΔmesi olmaz β requestNotificationPermission() Γ§aΔΔ±rΔ±n). Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) π Alarm saati aΓ§Δ±n.
function prepareAlarms() {
const b = window.WebToApk;
if (!(b && b.getAlarmSupport)) { showMessage('Alarms work in the installed app only.'); return false; }
switch (b.getAlarmSupport()) {
case 'ready': return true;
case 'needs_exact_alarm':
showMessage('Allow "Alarms & reminders" for this app, then come back.');
b.requestExactAlarms();
return false;
case 'needs_notification_permission':
b.requestNotificationPermission();
return false;
default:
showMessage('This app was built without alarm clocks.');
return false;
}
}KullanΔ±cΔ± Ayarlar'dan geri dΓΆndΓΌΔΓΌnde yeniden denetleyin:
document.addEventListener('visibilitychange', function () {
if (document.hidden || !(window.WebToApk && window.WebToApk.getAlarmSupport)) return;
document.getElementById('alarm-setup').hidden = WebToApk.getAlarmSupport() === 'ready';
});Bir alarmΔ± yalnΔ±zca telefon hazΔ±rken oluΕturun:
function setAlarmIn(hours) {
const b = window.WebToApk;
if (!(b && b.getAlarmSupport)) return false;
if (b.getAlarmSupport() !== 'ready') { prepareAlarms(); return false; } // asks for what is missing
return b.scheduleNotificationEx('wake-up', JSON.stringify({
at: Date.now() + hours * 3600 * 1000,
alarm: true,
title: 'Wake up',
body: 'Good morning'
}));
}Notlar: alarm: true ile scheduleNotificationEx, bu 'ready' olmadΔ±ΔΔ± her durumda false dΓΆndΓΌrΓΌr β asla Γ§alamayacak bir alarm hiΓ§ saklanmaz.
getNotificationPermission köprü#
window.WebToApk.getNotificationPermission(): String
Εu anki bildirim izni, doΔrudan iΕletim sisteminden okunur. Polyfill eskiden her sayfa yΓΌklemesinde `Notification.permission = 'default'` deΔerini sabit kodluyordu, bu yΓΌzden Γ§ok yaygΔ±n olan if (Notification.permission === 'granted') new Notification(...) kalΔ±bΔ± hiΓ§ Γ§alΔ±ΕmΔ±yordu β izni zaten vermiΕ bir kullanΔ±cΔ± iΓ§in bile, ve bildirimlerin hiΓ§ Γ§alΔ±Εma zamanΔ± izni gerektirmediΔi Android 12 ve ΓΆncesinde de.
Örnek
Bu uygulamanΔ±n Εu anda bildirim gΓΆnderip gΓΆnderemeyeceΔini okur.
DΓΆner deΔer: eΕzamanlΔ± olarak bir dize: 'granted'; 'denied' (kullanΔ±cΔ± kesin olarak reddetti veya Ayarlar'dan bu uygulamanΔ±n bildirimlerini kapattΔ± β gΓΆnderilen bildirim gΓΆrΓΌnmez); ya da 'default' (henΓΌz karar verilmedi, uygulama hΓ’lΓ’ sorabilir). Gerekenler: Γ§aΔΔ±rmak iΓ§in hiΓ§bir Εey; gΓΆndermek iΓ§in derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) Bildirimler aΓ§Δ±k olmalΔ±.
Standart web API'si aynΔ± canlΔ± deΔeri okur:
if ('Notification' in window && Notification.permission === 'granted') {
document.getElementById('alerts-on').hidden = false;
}Ham Γ§aΔrΔ±, ΓΆrneΔin kullanΔ±cΔ± Ayarlar'dan geri dΓΆnΓΌnce:
function refreshAlertSetting() {
if (!(window.WebToApk && window.WebToApk.getNotificationPermission)) return;
const perm = WebToApk.getNotificationPermission(); // 'granted' | 'denied' | 'default'
document.getElementById('enable-alerts').hidden = perm !== 'default'; // can still ask
document.getElementById('open-settings-hint').hidden = perm !== 'denied';
}
document.addEventListener('visibilitychange', function () {
if (!document.hidden) refreshAlertSetting();
});
refreshAlertSetting();Zamanlamadan ΓΆnce sorup sormayacaΔΔ±nΔ±za, aΓ§Δ±klayΔ±p aΓ§Δ±klamayacaΔΔ±nΔ±za ya da devam edip etmeyeceΔinize karar verin:
async function ensureAlerts() {
const b = window.WebToApk;
if (!(b && b.getNotificationPermission)) return false;
const perm = b.getNotificationPermission();
if (perm === 'granted') return true;
if (perm === 'denied') {
showMessage('Notifications are off for this app. Turn them on in Settings.');
return false;
}
// 'default': the app can still ask
return (await Notification.requestPermission()) === 'granted';
}Notlar: navigator.permissions.query({ name: 'notifications' }) ile aynΔ± yanΔ±tΔ± verir. KullanΔ±cΔ±ya sormak iΓ§in Εunu kullanΔ±n Notification.requestPermission().
getNotificationState köprü#
window.WebToApk.getNotificationState(): String
'granted' | 'prompt' (Android hΓ’lΓ’ sorabilir) | 'blocked' (kesin olarak reddedildi veya Ayarlar'da kapatΔ±ldΔ± β yalnΔ±zca Ayarlar dΓΌzeltir) | 'unavailable' (Android 13+ ve bu derleme bildirim iznini bildirmiyor). Bkz. NotificationOptIn.
Örnek
Bu uygulamanΔ±n bildirimlerinin Εu anda aΓ§Δ±k olup olmadΔ±ΔΔ±nΔ± okur β deΔilse, uygulamanΔ±n hΓ’lΓ’ sorup soramayacaΔΔ±nΔ± ya da bunlarΔ± yalnΔ±zca Ayarlar'Δ±n geri aΓ§abileceΔini sΓΆyler.
DΓΆner deΔer: eΕzamanlΔ± olarak bir dize: 'granted' (bildirimler telefona ulaΕΔ±r); 'prompt' (Android hΓ’lΓ’ izin penceresini gΓΆsterebilir); 'blocked' (kullanΔ±cΔ± kesin olarak reddetti veya sistem Ayarlar'Δ±nda bu uygulamanΔ±n bildirimlerini kapattΔ± β yalnΔ±zca Ayarlar dΓΌzeltebilir); ya da 'unavailable' (Android 13+ ve uygulama Bildirimler / HatΔ±rlatΔ±cΔ±lar / Push olmadan derlendi, bu yΓΌzden hiΓ§bir Εey bunlarΔ± aΓ§amaz). Gerekenler: Γ§aΔΔ±rmak iΓ§in hiΓ§bir Εey.
Ham Γ§aΔrΔ±, bir "Bildirimleri aΓ§Δ±n" bandΔ± gΓΆsterip gΓΆstermeyeceΔinize karar vermek iΓ§in:
function refreshNotifBanner() {
if (!(window.WebToApk && WebToApk.getNotificationState)) return;
var state = WebToApk.getNotificationState(); // 'granted' | 'prompt' | 'blocked' | 'unavailable'
var banner = document.getElementById('notif-banner');
banner.hidden = !(state === 'prompt' || state === 'blocked');
banner.querySelector('.hint').textContent = state === 'blocked'
? 'Notifications are off. Tap to open Settings and switch them on.'
: 'Get order updates. Tap to turn on notifications.';
}
document.addEventListener('visibilitychange', function () {
if (!document.hidden) refreshNotifBanner();
});
refreshNotifBanner();Notlar: getNotificationPermission() eski sayfalar iΓ§in kendi sΓΆzcΓΌklerini ('granted' / 'default' / 'denied') korur. KullanΔ±cΔ±yΔ± geri getirmek iΓ§in AppMint.enableNotifications() Γ§aΔΔ±rΔ±n (sizin iΓ§in pencereyi veya Ayarlar'Δ± seΓ§er).
getScheduledNotifications köprü#
window.WebToApk.getScheduledNotifications(): String
POST_NOTIFICATIONS iznini okuma ve isteme, ve sayfanΔ±n zaten zamanladΔ±ΔΔ± bildirimleri yΓΆnetme. GΓΆnderme ve zamanlama kendi yΓΆntemlerinde belgelenmiΕtir.
Kendi baΕΔ±na deΔil, grubu Bildirim izni, iptal ve listeleme ΓΌzerinden aΓ§Δ±klanΔ±r.
Örnek
HΓ’lΓ’ zamanlanmΔ±Ε olan hatΔ±rlatΔ±cΔ±larΔ± listeler.
DΓΆner deΔer: eΕzamanlΔ± olarak bir JSON dizesi. AyrΔ±ΕtΔ±rΔ±n. Her ΓΆΔe: { id, title, body, trigger, repeat, options? } - trigger sonraki tetiklenme zamanΔ±dΔ±r (epoch ms), repeat none|minutely|hourly|daily|weekly deΔeridir ve options (yalnΔ±zca scheduleNotificationEx iΓ§in) JSON dizesi olarak seΓ§eneklerdir. CanlΔ± alanlar, nasΔ±l teslim edileceΔini canlΔ± okunarak sΓΆyler: precision ("exact"; "inexact" = "Alarmlar ve hatΔ±rlatΔ±cΔ±lar" uygulama iΓ§in kapalΔ±, bu yΓΌzden Android telefon uyanΔ±kken 10 dakikalΔ±k bir pencerede teslim eder ve uykudayken daha uzun tutabilir; alarm: true iΓ§in "alarm_clock"), windowMs + latestAt (Android'e verilen pencere: kesin olduΔunda 0 / trigger, kesin olmadΔ±ΔΔ±nda 600000 / trigger + 600000) ve notificationsEnabled (false = tetiklenir ama uygulamanΔ±n bildirimleri kapalΔ± olduΔu iΓ§in Android hiΓ§bir Εey gΓΆstermez). Hi Γ§biri yoksa '[]'. Gerekenler: ek olarak hiΓ§bir Εey.
function renderReminders() {
if (!(window.WebToApk && window.WebToApk.getScheduledNotifications)) return;
let list = [];
try { list = JSON.parse(WebToApk.getScheduledNotifications() || '[]'); } catch (e) { list = []; }
const ul = document.getElementById('reminders');
ul.innerHTML = '';
list.sort(function (a, b) { return a.trigger - b.trigger; }).forEach(function (r) {
const li = document.createElement('li');
li.textContent = r.title + ' — ' + new Date(r.trigger).toLocaleString() +
(r.repeat !== 'none' ? ' (' + r.repeat + ')' : '');
ul.appendChild(li);
});
}Bir hatΔ±rlatΔ±cΔ±nΔ±n aΓ§Δ±k olup olmadΔ±ΔΔ±nΔ± ve bir sonraki ne zaman Γ§alacaΔΔ±nΔ± gΓΆsterin:
function describeReminder(id) {
if (!(window.WebToApk && window.WebToApk.getScheduledNotifications)) return 'Not available';
let list = [];
try { list = JSON.parse(WebToApk.getScheduledNotifications() || '[]'); } catch (e) { list = []; }
const r = list.find(function (x) { return x.id === id; });
return r ? 'Next: ' + new Date(r.trigger).toLocaleString() : 'Off';
}
document.getElementById('water-status').textContent = describeReminder('water');Εununla oluΕturulan hatΔ±rlatΔ±cΔ±larΔ±n ek seΓ§eneklerini okuyun scheduleNotificationEx:
function listAlarmStyleReminders() {
if (!(window.WebToApk && window.WebToApk.getScheduledNotifications)) return [];
let list = [];
try { list = JSON.parse(WebToApk.getScheduledNotifications() || '[]'); } catch (e) { list = []; }
return list.filter(function (r) {
if (!r.options) return false; // made with scheduleNotification
let o = {};
try { o = JSON.parse(r.options); } catch (e) { return false; }
return o.openApp === true; // puts the app on screen when it fires
}).map(function (r) { return r.id; });
}Notlar: tek seferlik bir hatΔ±rlatΔ±cΔ± tetiklendiΔinde listeden Γ§Δ±kar. TekrarlayanΔ± kalΔ±r ve trigger sonraki zamana ilerler. Telefon kapalΔ±yken veya uygulama zorla durdurulmuΕken zamanΔ± geΓ§en bir hatΔ±rlatΔ±cΔ±, uygulama veya telefon bir sonraki baΕladΔ±ΔΔ±nda bir kez, geΓ§ olarak gΓΆsterilir; geΓ§ kalan bir alarm: true Γ§almak yerine missed olarak bildirilir. GΓΌnlΓΌk, haftalΔ±k, aylΔ±k veya yΔ±llΔ±k bir hatΔ±rlatΔ±cΔ±, telefon saat dilimini deΔiΕtirdiΔinde yerel saatini korur.
HatΔ±rlatΔ±cΔ±lar zamanΔ±nda gelmeyecekse uyarΔ±n:
function reminderHealth() {
if (!(window.WebToApk && window.WebToApk.getScheduledNotifications)) return '';
let list = [];
try { list = JSON.parse(WebToApk.getScheduledNotifications() || '[]'); } catch (e) { list = []; }
if (!list.length) return '';
if (list.some(function (r) { return r.notificationsEnabled === false; })) return 'Notifications are off for this app: reminders will not appear.';
if (list.some(function (r) { return r.precision === 'inexact'; })) return 'Reminders may arrive late. Turn on Alarms & reminders.';
return '';
}isAlarmRinging köprü#
window.WebToApk.isAlarmRinging(): Boolean
Bir alarm saati Γ§alΔ±yorsa true.
Örnek
UygulamanΔ±n alarm saatlerinden birinin Εu anda Γ§alΔ±p Γ§almadΔ±ΔΔ±nΔ± sΓΆyler, bΓΆylece sayfa kendi durdur / ertele ekranΔ±nΔ± gΓΆsterebilir.
DΓΆner deΔer: bir alarm Γ§alarken true, aksi halde false (eΕzamanlΔ± olarak). Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) π Alarm saati.
function showRingScreenIfNeeded() {
const b = window.WebToApk;
const ringing = !!(b && b.isAlarmRinging && b.isAlarmRinging());
document.getElementById('ring-screen').hidden = !ringing;
}
showRingScreenIfNeeded();
document.addEventListener('visibilitychange', showRingScreenIfNeeded);Γalan alarmΔ± kendi ekranΔ±nΔ±zdan durdurun eΕleΕen Γ§aΔrΔ±larla.
document.getElementById('stop').addEventListener('click', function () {
const b = window.WebToApk;
if (b && b.isAlarmRinging && b.isAlarmRinging()) b.stopAlarm(''); // '' = whichever is ringing
});
document.getElementById('snooze').addEventListener('click', function () {
const b = window.WebToApk;
if (b && b.snoozeAlarm && !b.snoozeAlarm('', 10)) showMessage('Nothing is ringing');
});UygulamanΔ±n Γ§alan bir alarm tarafΔ±ndan aΓ§Δ±lmasΔ±na tepki verin.
window.addEventListener('appmint:reminder', function (e) {
if (e.detail.action === 'open' && e.detail.ringing) {
document.getElementById('ring-screen').hidden = false;
}
});Notlar: Γ§alan alarm uygulamayΔ± aΓ§tΔ±ΔΔ±nda appmint:reminder de ΕunlarΔ± taΕΔ±yarak gelir { action: 'open', ringing: true }.
notify köprü#
window.WebToApk.notify(optionsJson: String): Boolean
Zengin bildirim. Tam seΓ§enek listesi iΓ§in NotificationBridge.show'a bakΔ±n: channel (urgent|default|quiet|ongoing), image, largeIcon, bigText, ongoing, actions, progress, sound, silent, group, color. Resim alma ve Γ§ΓΆzme ana iΕ parΓ§acΔ±ΔΔ± dΔ±ΕΔ±nda yapΔ±lΔ±r, bu yΓΌzden uzak bir resim sayfayΔ± asla engelleyemez.
Örnek
Εimdi bir bildirim gΓΆnderir; resim, bΓΌyΓΌk metin, dΓΌΔmeler, ilerleme Γ§ubuΔu, yapΔ±ΕkΔ±n (ongoing), kanal, ses, renk ve etiket seΓ§eneklerinin herhangi bir karΔ±ΕΔ±mΔ±yla.
DΓΆner deΔer: seΓ§enekler geΓ§erli JSON ise ve bildirim sisteme teslim edildiyse true (arka plan iΕ parΓ§acΔ±ΔΔ±nda oluΕturulur, bu yΓΌzden bozuk bir resim URL'si sayfayΔ± engellemez); geΓ§ersiz JSON iΓ§in false. Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) Bildirimler aΓ§Δ±n ve Android 13+ ΓΌzerinde kullanΔ±cΔ±nΔ±n izni (Εununla isteyin Notification.requestPermission()).
Basit bildirim. tag bir kimliktir: aynΔ± etiketle yeniden gΓΆndermek eskisinin yerini alΔ±r.
async function notifyOrderReady() {
if (!(window.WebToApk && window.WebToApk.notify)) return;
if (window.Notification && Notification.permission !== 'granted') {
const p = await Notification.requestPermission();
if (p !== 'granted') { showMessage('Notifications are off for this app.'); return; }
}
WebToApk.notify(JSON.stringify({
title: 'Order ready',
body: 'Your order is ready to collect',
channel: 'default', // urgent | default | quiet | ongoing
tag: 'order-42'
}));
}Resim, bΓΌyΓΌk simge ve uzun metin. Ikisi de verildiΔinde image, bigText deΔerini geΓ§er.
WebToApk.notify(JSON.stringify({
title: 'New photo',
body: 'Tap to see it',
image: 'https://example.com/photo.jpg', // expanded big picture
largeIcon: 'https://example.com/avatar.png', // round icon on the right
color: '#00C6FF',
tag: 'photo-7'
}));
WebToApk.notify(JSON.stringify({
title: 'Weekly summary',
body: '3 tasks done, 2 left',
bigText: 'Done: pay rent, call bank, water plants. Left: tax form, dentist.',
channel: 'quiet', // no sound, low priority
group: 'summaries'
}));DΓΌΔmeler (en fazla 3). DokunuΕ appmint:notification-action olayΔ± olarak geri gelir.
WebToApk.notify(JSON.stringify({
title: 'Ali sent you a message',
body: 'Are we still on for 6pm?',
channel: 'urgent', // heads-up banner
tag: 'chat-ali',
actions: [
{ id: 'open', label: 'Open chat' },
{ id: 'done', label: 'Mark read' }
]
}));
window.addEventListener('appmint:notification-action', function (e) {
// e.detail = { actionId: 'done', tag: 'chat-ali' }
if (e.detail.actionId === 'open') openChat(e.detail.tag);
if (e.detail.actionId === 'done') markRead(e.detail.tag);
});YapΔ±ΕkΔ±n ilerleme (ongoing). GΓΌncellemek iΓ§in aynΔ± etiketle yeniden gΓΆnderin. Δ°Ε bittiΔinde, kullanΔ±cΔ± kaydΔ±rarak kaldΔ±rabilsin diye son durumu ongoing: false ile gΓΆnderin.
function showUpload(percent) {
WebToApk.notify(JSON.stringify({
title: 'Uploading', body: percent + '%',
ongoing: true, // cannot be swiped away
progress: { current: percent, max: 100 }, // or { indeterminate: true }
silent: true,
tag: 'upload'
}));
}
showUpload(40);
// finished:
WebToApk.notify(JSON.stringify({ title: 'Upload complete', body: '3 photos saved', tag: 'upload' }));DiΔer seΓ§enekler: sound (paketinizdeki '/audio/ding.mp3' gibi bir dosya, bir data:audio/... URL'si veya 'silent'), smallIcon (bir drawable adΔ±), when (zaman olarak gΓΆsterilen epoch ms), openApp: true (tam ekran uyarΔ±; bkz. scheduleNotificationEx).
Notlar: dΓΌΔmelerin satΔ±r iΓ§i yanΔ±t kutusu yoktur ve bir dΓΌΔme dokunuΕu sayfaya yalnΔ±zca uygulama Γ§alΔ±ΕΔ±rken ulaΕΔ±r (uygulamayΔ± aΓ§maz); tanΔ±mladΔ±ysanΔ±z olay ayrΔ±ca window.onAppMintNotificationAction(detail) iΕlevini Γ§aΔΔ±rΔ±r. image ve largeIcon, bir https:// veya data: URL'si ya da uygulamanΔ±zla paketlenmiΕ, sayfanΔ±zΔ±n adlandΔ±rdΔ±ΔΔ± gibi adlandΔ±rΔ±lmΔ±Ε bir resim ('img/logo.png', '/img/logo.png' veya tam https://appassets.androidplatform.net/assets/… adresi) alΔ±r. Bozuk bir resim atlanΔ±r, bildirim yine de gΓΆrΓΌnΓΌr. ongoing: true her zaman sessiz "Ongoing" kanalΔ±nΔ± kullanΔ±r. notify()'in herkese aΓ§Δ±k bir "kaldΔ±r" eΕi yoktur: cancelNotification yalnΔ±zca zamanlanmΔ±Ε hatΔ±rlatΔ±cΔ±larΔ± iptal eder. Daha sonra sayfadan kaldΔ±rmak istediΔiniz bir bildirim new Notification(...) ile gΓΆnderilmeli ve close() ile kaldΔ±rΔ±lmalΔ±dΔ±r; yapΔ±ΕkΔ±n bir ilerleme kartΔ± ise Capacitor.AppwrightLiveProgress ile (end). Android bir kanalΔ±n sesini kanal oluΕturulurken sabitler, bu yΓΌzden yeni bir sound deΔeri yeni bir kanal oluΕturur.
openNotificationSettings köprü#
window.WebToApk.openNotificationSettings(): Boolean
Bu uygulamanΔ±n bildirim ayarlarΔ±nΔ± aΓ§ar; ekran aΓ§Δ±labildiyse true.
Örnek
Bu uygulamanΔ±n kendi bildirim ayarlarΔ± ekranΔ±nΔ± aΓ§ar; kullanΔ±cΔ± buradan bildirimleri (ve her kanalΔ±) aΓ§Δ±p kapatabilir.
DΓΆner deΔer: ekran eΕzamanlΔ± olarak aΓ§Δ±ldΔ±ysa true; aΓ§Δ±lamadΔ±ysa false (Android 13+ ve derlemede bildirim yok). Android 8+ ΓΌzerinde uygulamanΔ±n bildirim sayfasΔ±dΔ±r; daha eski Android'de Uygulama bilgisi ekranΔ±. Gerekenler: aΓ§Δ±lacak bir Εey yok.
document.getElementById('notif-settings-link').onclick = function () {
if (!(window.WebToApk && WebToApk.openNotificationSettings && WebToApk.openNotificationSettings())) {
showMessage('Open Settings > Apps > this app > Notifications.');
}
};Notlar: kullanΔ±cΔ±yΔ± tek dokunuΕta geri getirmek iΓ§in bunun yerine AppMint.enableNotifications() kullanΔ±n: Android hΓ’lΓ’ izin veriyorsa izin penceresini gΓΆsterir, vermiyorsa yalnΔ±zca bu ekranΔ± aΓ§ar.
prepareNotificationSound köprü#
window.WebToApk.prepareNotificationSound(spec: String): Boolean
Pakete dahil bir ses dosyasΔ±nΔ± ΓΆnceden yerine kopyalar ve bildirim sesi olarak kullanΔ±labilir olup olmadΔ±ΔΔ±nΔ± bildirir. Δ°steΔe baΔlΔ± β `notify()` ve `scheduleNotificationEx()` bunu kendileri yapar β ama bir ayarlar ekranΔ±nΔ±n kullanΔ±cΔ± bir ses seΓ§er seΓ§mez onu doΔrulamasΔ±na izin verir.
Örnek
UygulamanΔ±zdaki bir ses dosyasΔ±nΔ±n bildirim sesi olarak kullanΔ±labileceΔini denetler ve Εimdi yerine kopyalar. Δ°steΔe baΔlΔ±: notify() ve scheduleNotificationEx() bunu kendileri yapar; bu, bir ayarlar ekranΔ±nΔ±n kullanΔ±cΔ± bir ses seΓ§er seΓ§mez onu denetlemesine izin verir.
DΓΆner deΔer: ses kullanΔ±labilirse true; dosya yoksa veya desteklenen bir ses tΓΌrΓΌ deΔilse false. Gerekenler: hiΓ§bir Εey.
function chooseAlarmSound(path) { // e.g. '/audio/chime.mp3'
if (!(window.WebToApk && window.WebToApk.prepareNotificationSound)) return;
if (!WebToApk.prepareNotificationSound(path)) {
showMessage('This sound file is missing from the app: ' + path);
return;
}
localStorage.setItem('alarmSound', path);
// Use it:
WebToApk.notify(JSON.stringify({ title: 'Sound test', body: 'This is your alarm sound', sound: path, tag: 'sound-test' }));
}Bir ses seΓ§iciyi yalnΔ±zca gerΓ§ekten kullanΔ±labilir seslerle doldurun:
const SOUNDS = [
{ label: 'Chime', path: '/audio/chime.mp3' },
{ label: 'Bell', path: '/audio/bell.ogg' },
{ label: 'Beep', path: '/audio/beep.wav' }
];
function renderSoundPicker(select) {
const b = window.WebToApk;
if (!(b && b.prepareNotificationSound)) return;
select.innerHTML = '';
SOUNDS.forEach(function (s) {
if (!b.prepareNotificationSound(s.path)) return; // missing or unsupported file
const opt = document.createElement('option');
opt.value = s.path; opt.textContent = s.label;
select.appendChild(opt);
});
}KullanΔ±cΔ±nΔ±n kendi ses dosyasΔ±nΔ± seΓ§mesine ve bunu gΓΌnlΓΌk bir hatΔ±rlatΔ±cΔ± iΓ§in data: URL'si olarak vermesine izin verin:
document.getElementById('own-sound').addEventListener('change', function (e) {
const file = e.target.files[0];
const b = window.WebToApk;
if (!file || !(b && b.prepareNotificationSound)) return;
const reader = new FileReader();
reader.onload = function () {
const dataUrl = reader.result; // 'data:audio/mpeg;base64,...'
if (!b.prepareNotificationSound(dataUrl)) {
showMessage('That file cannot be used as a notification sound.');
return;
}
b.scheduleNotificationEx('daily-walk', JSON.stringify({
at: nextEvening(), repeat: 'daily',
title: 'Walk time', body: 'Time for your evening walk', sound: dataUrl
}));
};
reader.readAsDataURL(file);
});Kabul edilen deΔerler: web paketinizdeki bir yol ('/audio/chime.mp3', 'audio/chime.mp3') veya sayfanΔ±zΔ±n oluΕturduΔu bir data:audio/...;base64,... URL'si. TΓΌrler: mp3, wav, ogg, oga, m4a, aac, flac, opus, mid, midi.
Notlar: klasΓΆrsΓΌz ve uzantΔ±sΔ±z yalΔ±n bir ad (bir res/raw sesi) burada denetlenmez ve notify({sound: 'name'}) bunu kullanabilse de false dΓΆndΓΌrΓΌr. Android kanal baΕΔ±na bir ses tutar, bu yΓΌzden sesi deΔiΕtirmek yeni bir kanal oluΕturur ve kullanΔ±cΔ±nΔ±n o kanal iΓ§in ayarlarΔ±nΔ± sΔ±fΔ±rlar.
requestExactAlarms köprü#
window.WebToApk.requestExactAlarms(): Boolean
Tam alarmlarΔ±n verildiΔi sistem ekranΔ±nΔ± aΓ§ar. Android 12+.
Örnek
KullanΔ±cΔ±nΔ±n bu uygulamanΔ±n tam alarmlarΔ± kullanmasΔ±na izin verdiΔi Android 12+ sistem ekranΔ±nΔ± aΓ§ar, bΓΆylece hatΔ±rlatΔ±cΔ±lar tam dakikada Γ§alar.
DΓΆner deΔer: ayarlar ekranΔ± aΓ§Δ±ldΔ±ysa (ve hiΓ§bir Εeyin gerekmediΔi Android 11 ve eskisinde) true; ekran aΓ§Δ±lamadΔ±ysa false. KullanΔ±cΔ±nΔ±n seΓ§imini sΓΆylemez. Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) β° HatΔ±rlatΔ±cΔ±lar aΓ§Δ±n.
document.getElementById('allow-exact').addEventListener('click', function () {
if (!(window.WebToApk && window.WebToApk.requestExactAlarms)) return;
if (WebToApk.getAlarmPrecision() === 'exact') return; // already fine
WebToApk.requestExactAlarms();
});
// The user comes back from Settings: read the real answer.
document.addEventListener('visibilitychange', function () {
if (document.hidden || !window.WebToApk) return;
const exact = WebToApk.getAlarmPrecision() === 'exact';
document.getElementById('allow-exact').hidden = exact;
});Zaman aΓ§Δ±sΔ±ndan kritik bir hatΔ±rlatΔ±cΔ±yΔ± kaydetmeden ΓΆnce, ayarlar ekranΔ±nΔ± yalnΔ±zca zamanlama gerΓ§ekten kapalΔ±ysa sunun:
function saveMedicineReminder(at) {
const b = window.WebToApk;
if (!(b && b.scheduleNotificationEx && b.getAlarmPrecision)) return;
b.scheduleNotificationEx('medicine', JSON.stringify({
at: at, repeat: 'daily', title: 'Medicine', body: 'Time for your tablet'
}));
const precision = b.getAlarmPrecision(); // 'exact' | 'inexact' | 'unavailable'
if (precision === 'inexact') {
showBanner('Reminders may arrive a few minutes late.', 'Fix timing', function () {
b.requestExactAlarms(); // runs from the banner button tap
});
} else if (precision === 'unavailable') {
showBanner('The phone\'s alarm service is not answering; this reminder may not fire.');
}
}Ayarlar ekranΔ± aΓ§Δ±lamadΔ±ΔΔ±nda (false), kullanΔ±cΔ±ya anahtarΔ± nerede bulacaΔΔ±nΔ± sΓΆyleyin:
document.getElementById('fix-timing').addEventListener('click', function () {
const b = window.WebToApk;
if (!(b && b.requestExactAlarms)) return;
const opened = b.requestExactAlarms();
if (!opened) {
showMessage('Open Settings > Apps > this app > "Alarms & reminders" and turn it on.');
}
// When it did open, read the answer on return with getAlarmPrecision().
});Notlar: bir dΓΌΔme dokunuΕundan Γ§aΔΔ±rΔ±n ve ΓΆnce nedenini aΓ§Δ±klayΔ±n β uygulamanΔ±zdan Γ§Δ±kar. Zaten zamanlanmΔ±Ε hatΔ±rlatΔ±cΔ±lar her iki durumda da Γ§alΔ±Εmaya devam eder; yalnΔ±zca zamanlamalarΔ± deΔiΕir.
requestNotificationPermission köprü#
window.WebToApk.requestNotificationPermission(): String
POST_NOTIFICATIONS iznini okuma ve isteme, ve sayfanΔ±n zaten zamanladΔ±ΔΔ± bildirimleri yΓΆnetme. GΓΆnderme ve zamanlama kendi yΓΆntemlerinde belgelenmiΕtir.
Kendi baΕΔ±na deΔil, grubu Bildirim izni, iptal ve listeleme ΓΌzerinden aΓ§Δ±klanΔ±r.
Örnek
Android 13+ "Bildirimlere izin verilsin mi?" penceresini gΓΆsterir. Sayfalar normalde bunu Γ§aΔΔ±ran ve kullanΔ±cΔ±nΔ±n yanΔ±tΔ±nΔ± bekleyen Notification.requestPermission() kullanΔ±r.
DΓΆner deΔer: eΕzamanlΔ± olarak bir dize: zaten izin verilmiΕse (veya Android 12 ve eskisinde) 'granted', aksi halde pencere aΓ§Δ±lΔ±rken 'default'. KullanΔ±cΔ±nΔ±n yanΔ±tΔ±nΔ± dΓΆndΓΌremez. Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) Bildirimler aΓ§Δ±n.
Promise API'sini kullanΔ±n - gerΓ§ek yanΔ±tla Γ§ΓΆzΓΌlΓΌr ('granted' veya 'denied'):
document.getElementById('enable-alerts').addEventListener('click', async function () {
if (!('Notification' in window)) return;
const perm = await Notification.requestPermission();
if (perm === 'granted') {
showMessage('Alerts are on');
} else {
showMessage('Alerts are off. You can turn them on in Settings.');
}
});Ham Γ§aΔrΔ±, yalnΔ±zca beklemeden pencereyi aΓ§mak iΓ§in:
if (window.WebToApk && window.WebToApk.requestNotificationPermission) {
const now = WebToApk.requestNotificationPermission(); // 'granted' or 'default'
if (now === 'granted') enableAlertFeatures();
// otherwise re-check later with WebToApk.getNotificationPermission()
// ('granted' | 'denied' | 'default')
}Notification.requestPermission iΕlevine geri Γ§aΔrΔ± geΓ§iren eski kod aynΔ± nihai yanΔ±tΔ± alΔ±r:
document.getElementById('turn-on-reminders').addEventListener('click', function () {
if (!('Notification' in window)) return;
if (Notification.permission !== 'default') { updateReminderUi(Notification.permission); return; }
Notification.requestPermission(function (perm) {
updateReminderUi(perm); // 'granted' or 'denied', once the user answers
});
});Notlar: net bir gerekΓ§eyle bir dΓΌΔme dokunuΕundan isteyin. KullanΔ±cΔ± iki kez reddettikten sonra Android pencereyi gΓΆstermeyi bΔ±rakΔ±r ve yanΔ±t hemen 'denied' olur; kullanΔ±cΔ± bunu uygulamanΔ±n Ayarlar'Δ±ndan vermelidir.
requestOpenAppPermission köprü#
window.WebToApk.requestOpenAppPermission(): Boolean
Tam ekran uyarΔ±nΔ±n verildiΔi sistem ekranΔ±nΔ± aΓ§ar. Android 14+.
Örnek
KullanΔ±cΔ±nΔ±n bu uygulama iΓ§in tam ekran uyarΔ±lara izin verdiΔi Android 14+ sistem ekranΔ±nΔ± aΓ§ar, bΓΆylece bir openApp: true hatΔ±rlatΔ±cΔ±sΔ± uygulamayΔ± ekrana getirebilir.
DΓΆner deΔer: ayarlar ekranΔ± aΓ§Δ±ldΔ±ysa (ve hiΓ§bir Εeyin gerekmediΔi Android 14'ΓΌn altΔ±nda) true; aΓ§Δ±lamadΔ±ysa false. KullanΔ±cΔ±nΔ±n seΓ§imini sΓΆylemez. Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) β° HatΔ±rlatΔ±cΔ±lar aΓ§Δ±n.
document.getElementById('allow-open-app').addEventListener('click', function () {
const b = window.WebToApk;
if (!(b && b.requestOpenAppPermission)) return;
if (b.canOpenAppAtTime() === 'granted') return;
b.requestOpenAppPermission();
});
// Read the real answer when the user comes back:
document.addEventListener('visibilitychange', function () {
if (document.hidden || !window.WebToApk) return;
const ok = WebToApk.canOpenAppAtTime() === 'granted';
document.getElementById('allow-open-app').hidden = ok;
});KullanΔ±cΔ±nΔ±n kurmakta olduΔu alarmΔ± hatΔ±rlayΔ±n, onu Ayarlar'a gΓΆnderin ve geri dΓΆndΓΌΔΓΌnde tamamlayΔ±n:
let pendingAlarm = null;
function setWakeAlarm(at) {
const b = window.WebToApk;
if (!(b && b.requestOpenAppPermission)) return;
if (b.canOpenAppAtTime() === 'denied') {
pendingAlarm = at;
b.requestOpenAppPermission();
return;
}
b.scheduleNotificationEx('wake', JSON.stringify({ at: at, title: 'Alarm', body: 'Wake up', openApp: true }));
}
document.addEventListener('visibilitychange', function () {
if (document.hidden || pendingAlarm === null || !window.WebToApk) return;
if (WebToApk.canOpenAppAtTime() === 'granted') setWakeAlarm(pendingAlarm);
else showMessage('Without that setting the alarm cannot open the app by itself.');
pendingAlarm = null;
});Ayarlar ekranΔ± aΓ§Δ±lamadΔ±ΔΔ±nda (false), anahtarΔ±n nerede olduΔunu sΓΆyleyin:
document.getElementById('allow-fullscreen').addEventListener('click', function () {
const b = window.WebToApk;
if (!(b && b.requestOpenAppPermission)) return;
if (!b.requestOpenAppPermission()) {
showMessage('Open Settings > Apps > this app > Notifications and allow full-screen notifications.');
}
});Notlar: nedenini aΓ§Δ±kladΔ±ktan sonra bir dΓΌΔme dokunuΕundan Γ§aΔΔ±rΔ±n β uygulamanΔ±zdan Γ§Δ±kar.
scheduleNotification köprü#
window.WebToApk.scheduleNotification(id: String, title: String, body: String, triggerAtMillis: String, repeat: String): Boolean
POST_NOTIFICATIONS iznini okuma ve isteme, ve sayfanΔ±n zaten zamanladΔ±ΔΔ± bildirimleri yΓΆnetme. GΓΆnderme ve zamanlama kendi yΓΆntemlerinde belgelenmiΕtir.
Kendi baΕΔ±na deΔil, grubu Bildirim izni, iptal ve listeleme ΓΌzerinden aΓ§Δ±klanΔ±r.
Örnek
Gelecekteki bir zaman iΓ§in basit bir hatΔ±rlatΔ±cΔ± (baΕlΔ±k ve metin) zamanlar. Uygulama kapalΔ±yken de Γ§alar ve telefon yeniden baΕlatΔ±ldΔ±ktan sonra tekrar kurulur.
DΓΆner deΔer: zamanlandΔ±ysa true; id boΕsa veya zaman sayΔ± deΔilse false. Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) β° HatΔ±rlatΔ±cΔ±lar aΓ§Δ±n (Bildirimler'i de aΓ§ar) ve Android 13+ ΓΌzerinde kullanΔ±cΔ±nΔ±n bildirim izni.
function remindToDrinkWater() {
if (!(window.WebToApk && window.WebToApk.scheduleNotification)) {
showMessage('Reminders work in the installed app only.');
return;
}
const ok = WebToApk.scheduleNotification(
'water', // your own id; same id replaces the old reminder
'Drink water', // title
'Time for a glass of water', // body
String(Date.now() + 60 * 60 * 1000), // epoch milliseconds, AS A STRING
'daily' // none | minutely | hourly | daily | weekly
);
if (!ok) showMessage('Could not schedule the reminder');
}Bir hatΔ±rlatΔ±cΔ±nΔ±n uygulamayΔ± ne zaman aΓ§tΔ±ΔΔ±nΔ± bilin (kullanΔ±cΔ± ona dokundu):
window.addEventListener('appmint:reminder', function (e) {
// e.detail = { id: 'water', overLockScreen: false }
if (e.detail.id === 'water') openWaterLog();
});Bir gΓΆrevin son tarihi olan gΓΌn saat 8:00'de tek seferlik bir hatΔ±rlatΔ±cΔ±:
function remindTask(task) {
if (!(window.WebToApk && window.WebToApk.scheduleNotification)) return false;
const at = new Date(task.dueDate);
at.setHours(8, 0, 0, 0);
if (at.getTime() <= Date.now()) return false; // that morning has passed
return WebToApk.scheduleNotification(
'task-' + task.id,
'Due today',
task.title,
String(at.getTime()), // epoch ms as a string
'none'
);
}Notlar: hatΔ±rlatΔ±cΔ± "urgent" (heads-up) stilini kullanΔ±r ve etiketi kimliΔidir. Telefon kapalΔ±yken kaΓ§Δ±rΔ±lan tekrarlayΔ±cΔ± bir hatΔ±rlatΔ±cΔ± bir sonraki adΔ±mda Γ§alar. Resim, dΓΌΔmeler, kendi sesiniz veya kilit ekranΔ± ΓΌzerinde uygulamayΔ± aΓ§mak iΓ§in scheduleNotificationEx kullanΔ±n. Uygulama iΓ§in tam alarmlar kapalΔ±ysa zaman dakikalarca kayabilir; denetleyin getAlarmPrecision().
scheduleNotificationEx köprü#
window.WebToApk.scheduleNotificationEx(id: String, optionsJson: String): Boolean
[scheduleNotification] iΓ§in tam biΓ§im: `notify()` iΓ§inde kabul edilen her Εey, uygulama kapalΔ±yken gelecekteki bir zamanda tetiklenir. WebToApk.scheduleNotificationEx('dose-1', JSON.stringify({ at: Date.now() + 3600000, // epoch millis (takma ad: triggerAt) repeat: 'daily', // none|minutely|hourly|daily|weekly|weekdays|monthly|yearly // days: [1, 3, 5], // 'weekdays' ile: ISO Pzt=1..Paz=7 (varsayΔ±lan Pzt-Cum) // alarm: true, // alarm saati gibi Γ§al (getAlarmSupport()) title: 'Time for your dose', body: 'Vitamin D - 1 tablet', sound: '/audio/chime.mp3', // SΔ°ZΔ°N paketinizdeki bir dosya; sessiz iΓ§in 'silent' openApp: true // uygulamanΔ±n kendisini kilit ekranΔ± ΓΌzerinde aΓ§ })); Paketlenen bir ses bu Γ§aΔrΔ± sΔ±rasΔ±nda yerine kopyalanΔ±r, bΓΆylece yanlΔ±Ε bir dosya adΔ± gΓΌnler sonra varsayΔ±lan sese dΓΆnΓΌΕmek yerine hemen (false) bildirilir.
Örnek
notify() iΓ§indeki tΓΌm seΓ§eneklerle (resim, dΓΌΔmeler, ses, kanal, uygulamayΔ± aΓ§ma) gelecekteki bir zaman iΓ§in hatΔ±rlatΔ±cΔ± zamanlar. Uygulama kapalΔ±yken de Γ§alar ve yeniden baΕlatmadan sonra korunur.
DΓΆner deΔer: zamanlandΔ±ysa true. Zaman verilmediyse (at, triggerAt, triggerAtMillis veya inSeconds), kimlik boΕsa, JSON bozuksa veya sound uygulamanΔ±zda olmayan bir dosyayΔ± adlandΔ±rΔ±yorsa false. Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) β° HatΔ±rlatΔ±cΔ±lar aΓ§Δ±n ve Android 13+ ΓΌzerinde kullanΔ±cΔ±nΔ±n bildirim izni.
Kendi sesinizle uygulamayΔ± aΓ§an gΓΌnlΓΌk bir hatΔ±rlatΔ±cΔ± (kilit ekranΔ± ΓΌzerinde):
function scheduleStandup(tomorrowAt9am) {
const b = window.WebToApk;
if (!(b && b.scheduleNotificationEx)) { showMessage('Reminders work in the installed app only.'); return; }
// Both are user settings: check, and ask if needed.
if (b.getAlarmPrecision() === 'inexact') b.requestExactAlarms();
if (b.canOpenAppAtTime() === 'denied') b.requestOpenAppPermission();
const ok = b.scheduleNotificationEx('standup', JSON.stringify({
at: tomorrowAt9am, // epoch ms (or triggerAt, or inSeconds: 3600)
repeat: 'daily', // none | minutely | hourly | daily | weekly | weekdays | monthly | yearly
title: 'Stand-up',
body: 'Daily sync starts now',
sound: '/audio/alarm.mp3', // a file in YOUR app; 'silent' for none
openApp: true // full-screen alert that puts the app on screen
}));
if (!ok) showMessage('Check the sound file path — nothing was scheduled.');
}
window.addEventListener('appmint:reminder', function (e) {
// e.detail = { id: 'standup', overLockScreen: true, action: 'open', ringing: false }
openMeetingScreen(e.detail.id);
});YalnΔ±zca spor gΓΌnleri β Pazartesi, Γarkamba ve Cuma saat 18:00 (days ISO'dur: Pazartesi = 1 β¦ Pazar = 7; days olmadan 'weekdays' Pazartesi-Cuma demektir):
WebToApk.scheduleNotificationEx('gym', JSON.stringify({
at: nextAt(18, 0), // epoch ms of the first time; moved to the next listed day if needed
repeat: 'weekdays',
days: [1, 3, 5],
title: 'Gym time',
body: 'Leg day'
}));
// Rent on the 31st: 'monthly' rings on the last day of shorter months (28/29/30) and on the 31st again when there is one.
WebToApk.scheduleNotificationEx('rent', JSON.stringify({ at: rentDueAt, repeat: 'monthly', title: 'Rent is due' }));
// A birthday: same date every year (29 February rings on the 28th in other years).
WebToApk.scheduleNotificationEx('bday-ana', JSON.stringify({ at: anaBirthdayAt9am, repeat: 'yearly', title: 'Ana\'s birthday' }));GerΓ§ek bir alarm saati (alarm: true): telefonun ALARM sesiyle Γ§alar β sessiz moddan ve kullanΔ±cΔ± alarmlara izin verdiΔinde RahatsΔ±z Etmeyin'den de geΓ§er β ve Kapat / Ertele veya ringSeconds olana kadar Γ§almaya devam eder. Durum Γ§ubuΔunda alarm simgesini gΓΆsterir ve kilit ekranΔ±nΔ±n ΓΌzerinde ekrana gelir:
function setWakeAlarm(atMs) {
const b = window.WebToApk;
if (!(b && b.getAlarmSupport)) { showMessage('Alarms work in the installed app only.'); return; }
const support = b.getAlarmSupport(); // 'ready' | 'not_enabled' | 'needs_exact_alarm' | 'needs_notification_permission'
if (support === 'needs_exact_alarm') { b.requestExactAlarms(); return; }
if (support !== 'ready') { showMessage('Alarms are not available: ' + support); return; }
const ok = b.scheduleNotificationEx('wake', JSON.stringify({
at: atMs,
repeat: 'weekdays', // daily/weekly/weekdays/monthly/yearly keep 07:00 across clock changes
title: 'Wake up',
body: 'Good morning',
alarm: true,
sound: '', // '' = the phone's alarm tone; or '/audio/rooster.mp3'; 'silent' = vibrate only
vibrate: true, // needs Vibration on in the build
ringSeconds: 300, // stop and count as missed after 5 minutes (default 600, max 3600)
snoozeMinutes: 9, // 0 hides the Snooze button (default 10)
snoozeLabel: 'Snooze', dismissLabel: 'Stop'
}));
if (!ok) showMessage('The alarm was not set.');
}
window.addEventListener('appmint:reminder', function (e) {
const d = e.detail;
// Opened by the ringing alarm: { id: 'wake', action: 'open', ringing: true, overLockScreen: true }
// How a ring ended (also delivered later if the app was closed):
// { id: 'wake', action: 'dismiss' | 'snooze' | 'missed' | 'error', alarm: true,
// source: 'notification' | 'page' | 'timeout' | 'replaced' | 'system',
// snoozeMinutes?, snoozedUntil?, error?, soundError? }
if (d.action === 'open' && d.ringing) showRingScreen(d.id); // your Stop / Snooze buttons call stopAlarm / snoozeAlarm
if (d.action === 'missed') logMissedAlarm(d.id);
});30 dakika iΓ§inde dΓΌΔmeli bir hatΔ±rlatΔ±cΔ±:
WebToApk.scheduleNotificationEx('dose-1', JSON.stringify({
inSeconds: 30 * 60,
title: 'Time for your dose',
body: 'Vitamin D — 1 tablet',
actions: [{ id: 'taken', label: 'Taken' }, { id: 'snooze', label: 'Snooze' }]
}));
window.addEventListener('appmint:notification-action', function (e) {
// e.detail = { actionId: 'taken', tag: 'dose-1' }
if (e.detail.actionId === 'snooze') {
WebToApk.scheduleNotificationEx(e.detail.tag, JSON.stringify({ inSeconds: 600, title: 'Time for your dose', body: 'Snoozed reminder' }));
}
});Bir satΔ±Ε baΕladΔ±ΔΔ±nda normal kanalda, resimli tek seferlik bir hatΔ±rlatΔ±cΔ±:
function remindSale(sale) { // sale.startsAt = epoch ms
if (!(window.WebToApk && window.WebToApk.scheduleNotificationEx)) return false;
return WebToApk.scheduleNotificationEx('sale-' + sale.id, JSON.stringify({
at: sale.startsAt,
title: 'The sale starts now',
body: sale.name,
image: 'https://example.com/banners/' + sale.id + '.jpg', // expanded picture
channel: 'default' // not the heads-up style reminders use by default
}));
}Notlar: aynΔ± kimlik eski bir hatΔ±rlatΔ±cΔ±nΔ±n yerini alΔ±r. VarsayΔ±lanlar: etiket = kimlik, kanal = urgent, bigText = gΓΆvde. Bir dΓΌΔme dokunuΕu sayfaya yalnΔ±zca uygulama Γ§alΔ±ΕΔ±rken ulaΕΔ±r. Ses dosyasΔ± zamanlarken kopyalanΔ±r, bΓΆylece yanlΔ±Ε bir yol gΓΌnler sonra deΔil Εimdi hata verir; mp3, wav, ogg, m4a, aac, flac ve opus Γ§alΔ±ΕΔ±r. openApp, bir uygulamanΔ±n belirli bir zamanda kendiliΔinden ekrana gelebilmesinin tek yoludur; Android 14+ ΓΌzerinde kullanΔ±cΔ±nΔ±n buna izin vermesi gerekir (canOpenAppAtTime). 1-7 dΕ±ΕΔ±nda days ile repeat: 'weekdays', false dΓΆndΓΌrΓΌr. alarm: true, EriΕim adΔ±mΔ±nda (AdΔ±m 4) π Alarm saati gerektirir ve getAlarmSupport() 'ready' olmadΔ±kΓ§a false dΓΆndΓΌrΓΌr; aynΔ± anda yalnΔ±zca bir alarm Γ§alar (yenisi ΓΆncekini missed olarak bitirir). Bir alarmΔ±n kendi ses dosyasΔ± Γ§alacaΔΔ± zamana kadar kaybolmuΕsa (bir Uzaktan GΓΌncelleme kaldΔ±rdΔ±ysa), telefonun alarm sesiyle Γ§alar ve olay Εunu taΕΔ±r soundError: true.
showNotification köprü#
window.WebToApk.showNotification(title: String, body: String, icon: String, tag: String): Boolean
ORΔ°JΔ°NAL dΓΆrt baΔΔ±msΔ±z deΔiΕkenli biΓ§im; zaten kullanΔ±mdaki her uygulama ve her rehber kod parΓ§asΔ± Γ§alΔ±Εmaya devam etsin diye adaptΓΆr olarak olduΔu gibi korunur. ArtΔ±k zengin oluΕturucuya iletir β bu da eski uygulamanΔ±n sessizce yok saydΔ±ΔΔ± `icon` baΔΔ±msΔ±z deΔiΕkeninin sonunda bir iΕe yaramasΔ± demektir.
Örnek
Orijinal dΓΆrt baΔΔ±msΔ±z deΔiΕkenli bildirim Γ§aΔrΔ±sΔ±. BaΕlΔ±k, metin, isteΔe baΔlΔ± bir bΓΌyΓΌk simge ve bir etiketle bildirim gΓΆsterir. Yeni kod, daha fazlasΔ±nΔ± yapan notify(optionsJson) veya new Notification(...) kullanmalΔ±dΔ±r.
DΓΆner deΔer: bildirim sisteme teslim edildiyse true. Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) Bildirimler aΓ§Δ±n ve Android 13+ ΓΌzerinde kullanΔ±cΔ±nΔ±n izni.
Standart web API'si (bu yΓΆntemi sizin iΓ§in Γ§aΔΔ±rΔ±r):
async function tellUser() {
if (!('Notification' in window)) return;
const p = Notification.permission === 'granted' ? 'granted' : await Notification.requestPermission();
if (p === 'granted') new Notification('Saved', { body: 'Your note was saved', tag: 'note' });
}Ham Γ§aΔrΔ±. BaΔΔ±msΔ±z deΔiΕkenler: baΕlΔ±k, gΓΆvde, simge, etiket. Simge veya etiket yoksa '' verin.
if (window.WebToApk && window.WebToApk.showNotification) {
WebToApk.showNotification(
'Saved', // title
'Your note was saved', // body
'https://example.com/avatar.png', // large icon (https://, data:, or 'img/x.png' in your app), or ''
'note' // tag: same tag replaces the old notification
);
}AynΔ± etiketi yeniden kullanarak bir durum bildirimini yerinde gΓΌncelleyin:
function showSyncStatus(done, total) {
const b = window.WebToApk;
if (!(b && b.showNotification)) return;
if (b.getNotificationPermission() !== 'granted') return;
b.showNotification(
'Syncing photos',
done + ' of ' + total + ' uploaded',
'', // no large icon
'sync' // same tag every time: the text updates, no new notification
);
}Notlar: varsayΔ±lan kanalda notify({title, body, largeIcon: icon, tag}) iΕlevine iletir. Etiket yoksa her Γ§aΔrΔ± yeni bir bildirim ekler. Resim, dΓΌΔme, ilerleme veya yapΔ±ΕkΔ±n bildirim iΓ§in Εunu kullanΔ±n notify.
snoozeAlarm köprü#
window.WebToApk.snoozeAlarm(id: String, minutes: Int): Boolean
Γalan [id] alarmΔ±nΔ± ("" = hangisi Γ§alΔ±yorsa) durdurur ve [minutes] dakika (1-1440; 0 = alarmΔ±n kendi snoozeMinutes deΔeri) sonra yeniden Γ§alar. Γalmiyorsa False.
Örnek
Γalan bir alarm saatini durdurur ve Ertele dΓΌΔmesi gibi birkaΓ§ dakika sonra yeniden Γ§alar. YalnΔ±zca bu Γ§alma kayar: gΓΌnlΓΌk bir alarm yarΔ±n yine her zamanki saatinde Γ§alar.
DΓΆner deΔer: alarm Γ§alΔ±yorsa ve ertelendiyse true; Γ§almΔ±yorsa false. id '' = hangisi Γ§alΔ±yorsa; minutes 1-1440 veya alarmΔ±n kendi snoozeMinutes deΔeri iΓ§in 0 (varsayΔ±lan 10). Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) π Alarm saati.
document.getElementById('snooze').onclick = function () {
if (!(window.WebToApk && window.WebToApk.snoozeAlarm)) return;
if (WebToApk.snoozeAlarm('', 5)) showMessage('Ringing again in 5 minutes');
hideRingScreen();
};
window.addEventListener('appmint:reminder', function (e) {
// { id: 'wake', action: 'snooze', alarm: true, source: 'page', snoozeMinutes: 5, snoozedUntil: 1767340800000 }
if (e.detail.action === 'snooze') updateNextAlarmLabel(e.detail.snoozedUntil);
});Bir alarm saati zamanlayΔ±n, sonra bir kapat dΓΌΔmesi baΔlayΔ±n:
const b = window.WebToApk;
if (b && b.snoozeAlarm && b.getAlarmSupport() === 'ready') {
b.scheduleNotificationEx('wake', JSON.stringify({
at: Date.now() + 8 * 3600000, repeat: 'daily', alarm: true,
title: 'Wake up', body: 'Good morning'
}));
}
document.getElementById('dismiss').onclick = () => {
if (WebToApk.isAlarmRinging()) WebToApk.stopAlarm('');
};AlarmΔ±n kendi sΓΌresi kadar erteleyin ve "hiΓ§bir Εey Γ§almΔ±yor" durumunu ele alΔ±n:
document.getElementById('snooze').onclick = () => {
if (!(window.WebToApk && WebToApk.snoozeAlarm)) return;
const ok = WebToApk.snoozeAlarm('', 0); // 0 = the alarm's own snoozeMinutes (default 10)
if (!ok) showMessage('No alarm is ringing right now.');
};Notlar: ertelenen Γ§alma getScheduledNotifications() tarafΔ±ndan <id>#snooze olarak listelenir; cancelNotification(id) onu da kaldΔ±rΔ±r.
stopAlarm köprü#
window.WebToApk.stopAlarm(id: String): Boolean
Γalan [id] alarmΔ±nΔ± ("" = hangisi Γ§alΔ±yorsa) Kapat dΓΌΔmesi gibi durdurur. TekrarlayΔ±cΔ± bir alarm bir sonraki zamanΔ± iΓ§in zamanlanmΔ±Ε kalΔ±r. Γalmiyorsa False.
Örnek
Γalan bir alarm saatini Kapat dΓΌΔmesi gibi durdurur. TekrarlayΔ±cΔ± bir alarm bir sonraki zamanΔ± iΓ§in kurulu kalΔ±r; kaldΔ±rmak iΓ§in cancelNotification(id) kullanΔ±n.
DΓΆner deΔer: o alarm Γ§alΔ±yorsa ve Εimdi durdurulduysa true; Γ§almΔ±yorsa false. Hangi alarm Γ§alΔ±yorsa onu durdurmak iΓ§in '' verin. Gerekenler: derleme yaparken EriΕim adΔ±mΔ±nda (AdΔ±m 4) π Alarm saati.
window.addEventListener('appmint:reminder', function (e) {
const d = e.detail; // { id, action: 'open', ringing: true, overLockScreen }
if (d.action === 'open' && d.ringing) showRingScreen(d.id);
});
document.getElementById('stop').onclick = function () {
if (window.WebToApk && window.WebToApk.stopAlarm) WebToApk.stopAlarm(currentAlarmId);
hideRingScreen();
};Durdur dΓΌΔmesini yalnΔ±zca kΓΆprΓΌnΓΌn bulunduΔu yerde sunun ve yanΔ±tΔ± okuyun:
const stopBtn = document.getElementById('stop');
if (window.WebToApk && typeof WebToApk.stopAlarm === 'function') {
stopBtn.onclick = function () {
const wasRinging = WebToApk.stopAlarm(''); // '' = whichever alarm is ringing
if (!wasRinging) showMessage('Nothing was ringing.');
};
} else {
stopBtn.hidden = true; // plain browser: no alarm clock
}SayfanΔ±n, o yokken baΕlayan bir Γ§alma iΓ§in Γ§alma ekranΔ±nΔ± gΓΆsterebilmesi iΓ§in isAlarmRinging() ile eΕleyin:
document.addEventListener('visibilitychange', function () {
if (document.hidden || !window.WebToApk) return;
if (WebToApk.isAlarmRinging && WebToApk.isAlarmRinging()) showRingScreen();
else hideRingScreen();
});Notlar: sayfa bu durumda ayrΔ±ca appmint:reminder olayΔ±nΔ± ΕunlarΔ± taΕΔ±yarak alΔ±r { id, action: 'dismiss', alarm: true, source: 'page' }.