JavaScript köprü API'si
Telefon, SMS ve arama kaydı
Arama yapma, mesaj gönderme veya taslak hazırlama ve geçmişi okuma. Bunların her biri izne bağlıdır ve Play bunlar hakkında sorular sorar.
composeSms köprü#
window.WebToApk.composeSms(phoneNumber: String, message: String): Boolean
Kullanıcının SMS uygulamasını mesaj önceden doldurulmuş olarak açar. İzin gerektirmez ve Play tarafından reddedilemez - otomatik olmayan her şey için doğru varsayılan. Telefonda SMS uygulaması yoksa (veya açılamadıysa) false döndürür.
Örnek
Kullanıcının SMS uygulamasını numara ve metin önceden doldurulmuş olarak açar. Kullanıcı gönder'e basar.
Döndürür: SMS uygulaması açıldıysa true, telefonda SMS uygulaması yoksa veya açılamadıysa false (eşzamanlı). Gerekir: hiçbir şey - derleme anahtarı yok, izin yok.
Bir "Bize yazın" düğmesi.
document.getElementById('textUs').addEventListener('click', function () {
if (window.WebToApk && window.WebToApk.composeSms) {
var ok = WebToApk.composeSms('+911234567890', 'Hello, I need help with my order');
if (!ok) showMessage('Could not open the SMS app.');
} else {
// In a normal browser the standard sms: link does the same job.
location.href = 'sms:+911234567890?body=' + encodeURIComponent('Hello, I need help with my order');
}
});Her randevu satırında, o müşterinin numarasına bir hatırlatma ön dolduran "Hatırlat" düğmesi:
document.getElementById('appointments').addEventListener('click', function (e) {
var row = e.target.closest('[data-phone]');
if (!row || !(window.WebToApk && typeof window.WebToApk.composeSms === 'function')) return;
var when = new Date(Number(row.getAttribute('data-time')));
var text = 'Hi ' + row.getAttribute('data-name') + ', a reminder of your appointment on ' +
when.toLocaleDateString() + ' at ' +
when.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) + '.';
if (!WebToApk.composeSms(row.getAttribute('data-phone'), text)) {
showMessage('This phone has no SMS app.');
}
});Bir "SMS ile gönder" formu: telefonda SMS uygulaması yoksa (false), kullanıcı başka yere yapıştırabilsin diye metni kopyalayın:
document.getElementById('smsForm').addEventListener('submit', function (e) {
e.preventDefault();
var number = document.getElementById('to').value.trim();
var text = document.getElementById('message').value;
if (!number || !text) return;
var opened = window.WebToApk && typeof window.WebToApk.composeSms === 'function' &&
WebToApk.composeSms(number, text);
if (!opened && navigator.clipboard) {
navigator.clipboard.writeText(text).then(function () {
showMessage('No SMS app here. The message was copied instead.');
});
}
});Notlar: Kullanıcı kendi SMS uygulamasında gönder'e dokunana kadar hiçbir şey gönderilmez, bu yüzden bu yöntemin kendisi SMS izni gerektirmez. Kullanıcının yazdığı veya onayladığı her mesaj için bunu kullanın; sendSms yalnızca uygulamanın gerçekten kendi başına göndermesi gerektiğinde kullanın. Yapay zekayla oluşturulan uygulamalar ve Google AI Studio içe aktarmaları için derleme kodunuzu tarar; bir composeSms( çağrısı SMS (okuma ve gönderme) seçeneğini işaretlemez - yalnızca sendSms ve listSms işaretler - bu yüzden bir "Bize yazın" düğmesi Play'de kısıtlı bir izin eklemez.
listCallLog köprü#
window.WebToApk.listCallLog(requestId: String, limit: Int, offset: Int, sinceMillis: String)
WebToApk.listCallLog(id, limit, offset, sinceMillis) `appmint:calllog` / window.onAppMintCallLog olarak iletilir.
Kendi başına değil, grubu Arama kaydı tarafından açıklanır.
Örnek
Telefonun arama geçmişini, en yeni arama ilk olacak şekilde okur.
Döndürür: şimdilik hiçbir şey. Yanıt appmint:calllog olayıdır (ve window.onAppMintCallLog), detail = { requestId, calls: [{ number, name, type, date, duration }] } veya { requestId, error } ile. date 1970'ten beri geçen milisaniyedir; duration saniyedir. Gerekir: derlerken 4. Adım'da (Erişim) Arama kaydı (okuma) seçeneğini açın; kullanıcıdan ilk çağrıda izin istenir.
Son 50 aramayı gösterin.
function loadCalls() {
if (!(window.WebToApk && window.WebToApk.listCallLog)) return;
var id = 'calls-' + Date.now();
window.addEventListener('appmint:calllog', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:calllog', handler);
if (e.detail.error) { showMessage('Call log: ' + e.detail.error); return; }
e.detail.calls.forEach(function (c) {
// c.type: incoming | outgoing | missed | voicemail | rejected | blocked | other
addRow((c.name || c.number) + ' - ' + c.type + ' - ' +
new Date(c.date).toLocaleString() + ' - ' + c.duration + 's');
});
});
WebToApk.listCallLog(id, 50, 0, '0'); // limit, offset, since (string)
}Yalnızca son 24 saatin aramaları, sayfa kancasını kullanarak. sinceMillis bir DİZEDİR, çünkü sayı köprünün int değeri için çok büyüktür.
window.onAppMintCallLog = function (detail) {
if (detail.requestId !== 'today') return;
if (detail.error) return;
document.getElementById('count').textContent = detail.calls.length + ' calls today';
};
if (window.WebToApk && window.WebToApk.listCallLog) {
WebToApk.listCallLog('today', 500, 0, String(Date.now() - 24 * 60 * 60 * 1000));
}Her seferinde 25 arama getiren bir "Daha fazla yükle" düğmesiyle arama geçmişi ekranı, offset:
var PAGE = 25, loaded = 0;
function loadMoreCalls() {
if (!(window.WebToApk && typeof window.WebToApk.listCallLog === 'function')) return;
var id = 'page-' + loaded;
window.addEventListener('appmint:calllog', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:calllog', handler);
if (e.detail.error) { showMessage('Call log: ' + e.detail.error); return; }
e.detail.calls.forEach(function (c) { addRow(c.name || c.number, c.type, c.date); });
loaded += e.detail.calls.length;
document.getElementById('more').hidden = e.detail.calls.length < PAGE; // last page
});
WebToApk.listCallLog(id, PAGE, loaded, '0'); // skip the calls already shown
}
document.getElementById('more').addEventListener('click', loadMoreCalls);
loadMoreCalls();Notlar: limit 1-2000 aralığına sıkıştırılır. Hatalar: not_enabled, permission_denied, foreign_origin. Arama kaydı, Google Play'in kısıtlı bir iznidir: Play Console'da onaylanmış bir İzin Bildirimi vermeniz gerekir, yoksa uygulama reddedilir.
listSms köprü#
window.WebToApk.listSms(requestId: String, box: String, limit: Int, offset: Int)
WebToApk.composeSms(number, message) <- İzin GEREKMEZ, SMS uygulamasını açar WebToApk.sendSms(id, number, message, wantDelivery) WebToApk.listSms(id, "inbox"|"sent"|"draft", limit, offset) Gönderim sonuçları: `appmint:sms` / window.onAppMintSms {requestId, status:"sent"|"delivered"|"failed", ok, reason?} Gelen mesajlar: `appmint:sms-received` / window.onAppMintSmsReceived.
Kendi başına değil, grubu SMS tarafından açıklanır.
Örnek
Telefonun gelen kutusundan, gönderilenlerinden veya taslaklarından SMS mesajlarını, en yeni önce olacak şekilde okur. Bu dosya ayrıca yeni mesajların geldikçe nasıl alınacağını da gösterir.
Döndürür: şimdilik hiçbir şey. Yanıt appmint:sms olayıdır (ve window.onAppMintSms), detail = { requestId, messages: [{ id, address, body, date, read, box }] } ile. Başarısızlıkta: { requestId, status: 'failed', ok: false, reason }. Gerekir: derlerken 4. Adım'da (Erişim) SMS (okuma ve gönderme) seçeneğini açın; kullanıcıdan ilk çağrıda izin istenir.
Gelen kutusundaki son 30 mesajı okuyun.
function loadInbox() {
if (!(window.WebToApk && window.WebToApk.listSms)) return;
var id = 'inbox-' + Date.now();
window.addEventListener('appmint:sms', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:sms', handler);
if (e.detail.status === 'failed') { showMessage('Cannot read SMS: ' + e.detail.reason); return; }
e.detail.messages.forEach(function (m) {
addRow(m.address + ': ' + m.body + (m.read ? '' : ' (new)') +
' - ' + new Date(m.date).toLocaleString());
});
});
WebToApk.listSms(id, 'inbox', 30, 0); // box: 'inbox' | 'sent' | 'draft'
}Gelen yeni mesajlar (appmint:sms-received, ayrıca window.onAppMintSmsReceived). Uygulama kapalıyken gelen mesajlar saklanır (son 50) ve uygulama yeniden açıldığında sayfanıza verilir.
window.addEventListener('appmint:sms-received', function (e) {
// e.detail = { address: '+91...', body: 'Your OTP is 4821', date: 1737000000000 }
var code = (e.detail.body.match(/\b\d{4,6}\b/) || [])[0];
if (code) document.getElementById('otp').value = code;
});
// or, as a page hook:
window.onAppMintSmsReceived = function (sms) {
console.log('SMS from ' + sms.address);
};Gelen kutusundaki son 200 mesajı banka borçları için tarayan ve tutarları toplayan bir harcama takipçisi:
function scanSpending() {
if (!(window.WebToApk && typeof window.WebToApk.listSms === 'function')) return;
var id = 'spend-' + Date.now();
window.addEventListener('appmint:sms', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:sms', handler);
if (e.detail.status === 'failed') { showMessage('Cannot read SMS: ' + e.detail.reason); return; }
var total = 0;
e.detail.messages.forEach(function (m) {
if (!/debited/i.test(m.body)) return;
var amount = m.body.match(/(?:Rs\.?|INR)\s*([\d,]+(?:\.\d{1,2})?)/i);
if (amount) total += parseFloat(amount[1].replace(/,/g, ''));
});
document.getElementById('spent').textContent = 'Spent: Rs ' + total.toFixed(2);
});
WebToApk.listSms(id, 'inbox', 200, 0);
}Notlar: limit 1-500 aralığına sıkıştırılır. Bilinmeyen herhangi bir kutu adı gelen kutusunu okur. reason değerleri: not_enabled, permission_denied, foreign_origin. Alınan mesajlar kullanıcının normal SMS uygulamasına da ulaşır. SMS, Google Play'in kısıtlı bir iznidir: Play Console'da onaylanmış bir İzin Bildirimi vermeniz gerekir (genellikle yalnızca varsayılan SMS uygulamaları uygundur), yoksa uygulama reddedilir.
makePhoneCall köprü#
window.WebToApk.makePhoneCall(phoneNumber: String)
[phoneNumber] numarasını arar. - Derlemede Telefon izni AÇIKSA: aramayı doğrudan yapar. İlk seferde Android kullanıcıdan Telefon izni ister; reddederse numara girilmiş olarak çevirici açılır ve kullanıcı yine de kendisi arayabilir. - Telefon izni KAPALIYSA: numara girilmiş olarak çeviriciyi açar (çevirici izin gerektirmez) ve kullanıcı Ara'ya dokunur. - Uygulamanın kendisine ait olmayan bir sayfa (uygulamada açılan harici bir site) doğrudan arama değil, her zaman çeviriciyi alır. HTML'inizdeki düz bir `tel:` bağlantısı da çeviriciyi açar ve çoğu zaman yeterlidir.
Örnek
Bir numaraya telefon araması başlatır veya numara girilmiş olarak çeviriciyi açar.
Döndürür: hiçbir şey. Gerekir: çeviriciyi açmak için hiçbir şey. Arama doğrudan başlasın istiyorsanız derlerken 4. Adım'da (Erişim) Telefon seçeneğini açın.
Bir "Dükkanı arayın" düğmesi.
document.getElementById('callShop').addEventListener('click', function () {
if (window.WebToApk && window.WebToApk.makePhoneCall) {
WebToApk.makePhoneCall('+911234567890');
}
});Anahtar gerekmez: düz bir tel: bağlantısı çeviriciyi numarayla açar, hem uygulamada hem tarayıcıda. Çoğu zaman ihtiyacınız olan tek şey budur.
<a href="tel:+911234567890">Call the shop</a>Her satırın numarasını bir data-phone özniteliğinde taşıdığı bütün bir personel rehberi için tek bir işleyici:
document.getElementById('staffList').addEventListener('click', function (e) {
var btn = e.target.closest('[data-phone]');
if (!btn) return;
var number = btn.getAttribute('data-phone').replace(/[^\d+]/g, ''); // keep digits and +
if (!number) return;
if (window.WebToApk && typeof window.WebToApk.makePhoneCall === 'function') {
WebToApk.makePhoneCall(number);
} else {
location.href = 'tel:' + number; // a normal browser
}
});Notlar: Telefon kapalıyken çevirici numarayla açılır ve kullanıcı arama tuşuna basar. Telefon açıkken arama doğrudan başlar; ilk seferde Android kullanıcıdan telefon araması izni ister ve reddederse çevirici açılır, böylece aramayı yine de kendisi yapabilir. Uygulamanın kendisine ait olmayan bir sayfa (uygulamada açılan harici bir site) her zaman çeviriciyi alır. Numarayı düz bir dize olarak iletin. Geriye hiçbir şey bildirilmez - aramanın yapılıp yapılmadığını bilemezsiniz. Telefon anahtarı Play listenize CALL_PHONE iznini ekler; bunu Veri güvenliği formunda bildirin ve yalnızca gerekiyorsa açın.
sendSms köprü#
window.WebToApk.sendSms(
WebToApk.composeSms(number, message) <- İzin GEREKMEZ, SMS uygulamasını açar WebToApk.sendSms(id, number, message, wantDelivery) WebToApk.listSms(id, "inbox"|"sent"|"draft", limit, offset) Gönderim sonuçları: `appmint:sms` / window.onAppMintSms {requestId, status:"sent"|"delivered"|"failed", ok, reason?} Gelen mesajlar: `appmint:sms-received` / window.onAppMintSmsReceived.
Kendi başına değil, grubu SMS tarafından açıklanır.
Örnek
SMS uygulamasını açmadan doğrudan uygulamadan SMS gönderir ve gerçekte ne olduğunu bildirir.
Döndürür: şimdilik hiçbir şey. Yanıt appmint:sms olayıdır (ve window.onAppMintSms), detail = { requestId, status: 'sent' | 'delivered' | 'failed', ok, reason? } ile. Teslimat raporuyla başarıda İKİ yanıt alırsınız: sent, sonra delivered. Gerekir: derlerken 4. Adım'da (Erişim) SMS (okuma ve gönderme) seçeneğini açın; kullanıcıdan ilk çağrıda izin istenir.
Bir kod gönderin ve durumunu izleyin. Teslimat raporu istediyseniz ilk yanıttan sonra dinleyiciyi kaldırmayın.
function sendCode(phone, code) {
if (!(window.WebToApk && window.WebToApk.sendSms)) {
showMessage('Sending SMS works only inside the app.');
return;
}
var id = 'sms-' + Date.now();
function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
var d = e.detail;
if (d.status === 'sent' && d.reason === 'no_delivery_report') {
showStatus('Sent (the network gave no delivery report)');
window.removeEventListener('appmint:sms', handler);
} else if (d.status === 'sent') {
showStatus('Sent');
} else if (d.status === 'delivered') {
showStatus('Delivered');
window.removeEventListener('appmint:sms', handler);
} else { // 'failed'
showStatus('Failed: ' + d.reason);
window.removeEventListener('appmint:sms', handler);
}
}
window.addEventListener('appmint:sms', handler);
WebToApk.sendSms(id, phone, 'Your code is ' + code, true); // true = delivery report
}Teslimat raporu yok. Son değer olarak false iletin: tam olarak bir yanıt alırsınız, sent veya failed.
window.onAppMintSms = function (d) {
if (d.requestId === 'alert-1') showStatus(d.ok ? 'Alert sent' : 'Failed: ' + d.reason);
};
if (window.WebToApk && window.WebToApk.sendSms) {
WebToApk.sendSms('alert-1', '+911234567890', 'Gate opened at ' + new Date().toLocaleTimeString(), false);
}Aynı bildirim kısa bir numara listesine sırayla gönderilir ve her sonuç toplanır (SMS kapalıysa veya reddedildiyse durur, çünkü diğer her numara aynı şekilde başarısız olur):
function sendToAll(numbers, text, done) {
if (!(window.WebToApk && typeof window.WebToApk.sendSms === 'function')) { done(null); return; }
var results = [], i = 0;
function next() {
if (i >= numbers.length) { done(results); return; }
var number = numbers[i++];
var id = 'notice-' + Date.now() + '-' + i;
window.addEventListener('appmint:sms', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:sms', handler);
results.push({ number: number, ok: e.detail.ok, reason: e.detail.reason });
var r = e.detail.reason;
if (r === 'not_enabled' || r === 'permission_denied' || r === 'foreign_origin') done(results);
else next();
});
WebToApk.sendSms(id, number, text, false); // one answer per number
}
next();
}
sendToAll(['+911234567890', '+919876543210'], 'Practice moved to 6 pm today.', function (results) {
if (!results) return showMessage('Sending SMS works only inside the app.');
showStatus(results.filter(function (r) { return r.ok; }).length + ' of ' + results.length + ' sent');
});Notlar: Uzun metin parçalara bölünür ve tek mesaj olarak gönderilir. 60 saniye içinde teslimat raporu gelmezse reason: 'no_delivery_report' ile status: 'sent' alırsınız - mesaj yine de gönderilmiştir. reason değerleri: not_enabled, permission_denied, foreign_origin, invalid_arguments (boş numara veya metin), no_service, radio_off, generic_failure, null_pdu, not_delivered ve diğerleri. Dize türünde bir requestId kullanın. Her SMS kullanıcıya para kazandırabilir veya maliyet çıkarabilir. SMS, Google Play'in kısıtlı bir iznidir: Play Console'da onaylanmış bir İzin Bildirimi vermeniz gerekir (genellikle yalnızca varsayılan SMS uygulamaları uygundur), bu yüzden kullanıcı gönder'e basabiliyorsa composeSms tercih edin.