JavaScript köprü API'si
KiΕiler
Okuma, arama, seΓ§me ve yazma. SeΓ§ici hiΓ§bir izin gerektirmez.
addContact köprü#
window.WebToApk.addContact(requestId: String, contactJson: String)
Sistem seΓ§icisi (izin gerekmez) ve yeni bir kiΕi yazma (WRITE_CONTACTS). Okuma tarafΔ± olan listeleme ve arama, yukarΔ±daki KiΕiler grubunun altΔ±ndadΔ±r.
Kendi baΕΔ±na deΔil, grubuyla birlikte anlatΔ±lΔ±r: KiΕiler: seΓ§me ve ekleme.
Örnek
Yeni bir kiΕiyi KiΕiler uygulamasΔ±nΔ± aΓ§madan doΔrudan telefonun rehberine kaydeder.
DΓΆner deΔer: Δ°Εlem artΔ±k hiΓ§bir Εey dΓΆndΓΌrmez. YanΔ±t, baΕarΔ±da detail = { requestId, ok: true, id: '123' } ile, kayΔ±t baΕarΔ±sΔ±z olduΔunda { requestId, ok: false, id: null } ile ya da { requestId, error } ile gelen appmint:contacts olayΔ±dΔ±r (ve window.onAppMintContacts). Gerekenler: derleme yaparken AdΔ±m 4'te (EriΕim) KiΕileri DΓΌzenle seΓ§eneΔini aΓ§Δ±n; ilk Γ§aΔrΔ±da kullanΔ±cΔ±dan izin istenir.
Bir mΓΌΕteriyi kaydedin. KiΕi bir JSON dizesi olarak iletilir.
function saveCustomer(name, phone, email) {
if (!(window.WebToApk && window.WebToApk.addContact)) return;
var id = 'add-' + Date.now();
window.addEventListener('appmint:contacts', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:contacts', handler);
if (e.detail.error === 'not_enabled') { showMessage('Turn on Edit Contacts when you build'); return; }
if (e.detail.error) { showMessage('Not saved: ' + e.detail.error); return; }
showMessage(e.detail.ok ? 'Saved to contacts' : 'Could not save the contact');
});
WebToApk.addContact(id, JSON.stringify({
displayName: name,
phones: [{ number: phone, type: 'mobile' }], // type: mobile | home | work
emails: [email]
}));
}KΔ±sa biΓ§im. Tek deΔerler de kabul edilir: { name: 'Ali', phone: '+911234567890', email: '[email protected]' }.
Bir kartvizit sayfasΔ±nda, kΔ±sa biΓ§imi ve bir Promise kullanan "KiΕilere kaydet" dΓΌΔmesi:
function addOne(contact) {
return new Promise(function (resolve, reject) {
var id = 'card-' + Date.now() + '-' + Math.random().toString(36).slice(2);
window.addEventListener('appmint:contacts', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:contacts', handler);
if (e.detail.error) reject(new Error(e.detail.error));
else if (!e.detail.ok) reject(new Error('save_failed'));
else resolve(e.detail.id);
});
WebToApk.addContact(id, JSON.stringify(contact));
});
}
document.getElementById('save-card').addEventListener('click', function () {
if (!(window.WebToApk && window.WebToApk.addContact)) return;
addOne({ name: 'Priya Sharma', phone: '+919876543210', email: '[email protected]' })
.then(function () { showMessage('Priya is in your contacts now'); })
.catch(function (err) {
showMessage(err.message === 'permission_denied' ? 'Allow Contacts to save this card.' : 'Not saved: ' + err.message);
});
});Bir ekip listesini kiΕi kiΕi, iΕ ve ev numaralarΔ±yla iΓ§e aktarΔ±n ve kaΓ§ kiΕinin kaydedildiΔini bildirin:
async function importTeam(team) { // [{ name, work, home, email }]
if (!(window.WebToApk && window.WebToApk.addContact)) return;
var saved = 0;
for (var i = 0; i < team.length; i++) {
var m = team[i];
try {
await addOne({ // addOne() from the example above
displayName: m.name,
phones: [{ number: m.work, type: 'work' }, { number: m.home, type: 'home' }],
emails: m.email ? [m.email] : []
});
saved++;
} catch (err) {
if (err.message === 'not_enabled' || err.message === 'permission_denied') break; // the rest would fail too
}
}
showMessage(saved + ' of ' + team.length + ' saved');
}Notlar: Hatalar: not_enabled, permission_denied. DΓΆnen id, yeni ham kiΕi kimliΔidir. home veya work dΔ±ΕΔ±ndaki bir telefon type deΔeri mobile olarak kaydedilir. KiΕi cihaza kaydedilir (hesap yok). KiΕi yazmak hassas bir izindir: Play Store sayfanΔ±z bunu Veri gΓΌvenliΔi formunda ve gizlilik politikasΔ±nda belirtmelidir.
getContact köprü#
window.WebToApk.getContact(requestId: String, contactId: String)
Hepsi asenkron: imleΓ§ okumalarΔ± binlerce satΔ±r olabilir ve engelleyici bir @JavascriptInterface dΓΆnΓΌΕΓΌ bunu JS iΕ parΓ§acΔ±ΔΔ±nda Γ§alΔ±ΕtΔ±rΔ±rdΔ±; bu da ANR demektir. SonuΓ§lar `appmint:contacts` / window.onAppMintContacts({requestId,...}) olarak gelir. requestId: bir STRING verin ('pick-' + Date.now()). Ham bir SAYI da Γ§alΔ±ΕΔ±r; kΓΆprΓΌ onu bir double ΓΌzerinden dΓΆnΓΌΕtΓΌrΓΌr ("1.787491234567E12") ve her yanΔ±t onu yeniden asΔ±l haline getirir (BridgeRequestId), bΓΆylece `res.requestId === Date.now()` katΔ± karΕΔ±laΕtΔ±rmasΔ± her iki durumda da doΔru Γ§Δ±kar. WebToApk.listContacts(id, limit, offset) WebToApk.searchContacts(id, query, limit) WebToApk.getContact(id, contactId) WebToApk.pickContact(id) <- Δ°zin GEREKMEZ (sistem seΓ§icisi) WebToApk.addContact(id, json) <- KiΕiler yazma izni gerekir
Kendi baΕΔ±na deΔil, grubuyla birlikte anlatΔ±lΔ±r: KiΕiler.
Örnek
Bir kiΕiyi id deΔeriyle yeniden okur (listContacts iΓ§inden gelen id veya searchContacts).
DΓΆner deΔer: Δ°Εlem artΔ±k hiΓ§bir Εey dΓΆndΓΌrmez. YanΔ±t, detail = { requestId, contact: { id, displayName, photoUri, phones: [{ number, type }], emails: [...] } } ile birlikte appmint:contacts olayΔ±dΔ±r (ve window.onAppMintContacts). Kiεi artΔ±k yoksa contact, null olur. Hata durumunda: { requestId, error }. Gerekenler: derleme yaparken AdΔ±m 4'te (EriΕim) KiΕiler seΓ§eneΔini aΓ§Δ±n.
Olay dinleyicisi yerine sayfa kancasΔ±nΔ± kullanarak kayΔ±tlΔ± bir kiΕiyi yenileyin.
var pendingId = '';
window.onAppMintContacts = function (detail) {
if (detail.requestId !== pendingId) return;
if (detail.error) { showMessage('Could not read the contact: ' + detail.error); return; }
if (!detail.contact) { showMessage('This contact was deleted.'); return; }
var c = detail.contact;
document.getElementById('name').textContent = c.displayName;
document.getElementById('phones').textContent =
c.phones.map(function (p) { return p.type + ': ' + p.number; }).join(', ');
document.getElementById('emails').textContent = c.emails.join(', ');
};
function openContact(contactId) {
if (!(window.WebToApk && window.WebToApk.getContact)) return;
pendingId = 'one-' + Date.now();
WebToApk.getContact(pendingId, String(contactId));
}KayΔ±tlΔ± bir favori kiΕi kimliΔi listesini yenileyin ve o zamandan beri telefondan silinenleri dΓΌΕΓΌrΓΌn:
function getOne(contactId) {
return new Promise(function (resolve, reject) {
var id = 'fav-' + contactId + '-' + Date.now();
window.addEventListener('appmint:contacts', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:contacts', handler);
if (e.detail.error) reject(new Error(e.detail.error)); else resolve(e.detail.contact);
});
WebToApk.getContact(id, String(contactId));
});
}
async function loadFavourites() {
if (!(window.WebToApk && window.WebToApk.getContact)) return;
var ids = JSON.parse(localStorage.getItem('favIds') || '[]');
var people = [];
for (var i = 0; i < ids.length; i++) {
var c = await getOne(ids[i]);
if (c) people.push(c); // null = deleted from the phone
}
localStorage.setItem('favIds', JSON.stringify(people.map(function (c) { return c.id; })));
renderFavourites(people);
}UygulamanΔ±zΔ±n bir mΓΌΕteri iΓ§in sakladΔ±ΔΔ± numaranΔ±n hΓ’lΓ’ kiΕi kartΔ±nda olup olmadΔ±ΔΔ±nΔ± kontrol edin:
function checkStoredNumber(customer) { // { contactId, phone }
if (!(window.WebToApk && window.WebToApk.getContact)) return;
var id = 'check-' + Date.now();
window.addEventListener('appmint:contacts', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:contacts', handler);
if (e.detail.error) { showMessage('Could not check: ' + e.detail.error); return; }
if (!e.detail.contact) { showMessage('This customer is no longer in your contacts.'); return; }
var digits = function (s) { return String(s).replace(/\D/g, ''); };
var still = e.detail.contact.phones.some(function (p) {
return digits(p.number).slice(-10) === digits(customer.phone).slice(-10);
});
if (!still) showMessage('The number for ' + e.detail.contact.displayName + ' has changed.');
});
WebToApk.getContact(id, String(customer.contactId));
}Notlar: window.onAppMintContacts her kiΕiler yanΔ±tΔ±nΔ± alΔ±r (liste, arama, seΓ§me, ekleme); bu yΓΌzden her zaman requestId deΔerini kontrol edin. Onu ya da addEventListener('appmint:contacts', ...) kullanabilirsiniz; ikisi de tetiklenir. Hatalar: not_enabled, permission_denied, foreign_origin. pickContact iΓ§inden gelen id, bir kiΕi kimliΔi deΔil telefon satΔ±rΔ± kimliΔidir; bu yΓΌzden burada iΕe yaramaz. KiΕiler kiΕisel veridir: Play Store sayfanΔ±z bunu Veri gΓΌvenliΔi formunda ve gizlilik politikasΔ±nda belirtmelidir.
listContacts köprü#
window.WebToApk.listContacts(requestId: String, limit: Int, offset: Int)
Hepsi asenkron: imleΓ§ okumalarΔ± binlerce satΔ±r olabilir ve engelleyici bir @JavascriptInterface dΓΆnΓΌΕΓΌ bunu JS iΕ parΓ§acΔ±ΔΔ±nda Γ§alΔ±ΕtΔ±rΔ±rdΔ±; bu da ANR demektir. SonuΓ§lar `appmint:contacts` / window.onAppMintContacts({requestId,...}) olarak gelir. requestId: bir STRING verin ('pick-' + Date.now()). Ham bir SAYI da Γ§alΔ±ΕΔ±r; kΓΆprΓΌ onu bir double ΓΌzerinden dΓΆnΓΌΕtΓΌrΓΌr ("1.787491234567E12") ve her yanΔ±t onu yeniden asΔ±l haline getirir (BridgeRequestId), bΓΆylece `res.requestId === Date.now()` katΔ± karΕΔ±laΕtΔ±rmasΔ± her iki durumda da doΔru Γ§Δ±kar. WebToApk.listContacts(id, limit, offset) WebToApk.searchContacts(id, query, limit) WebToApk.getContact(id, contactId) WebToApk.pickContact(id) <- Δ°zin GEREKMEZ (sistem seΓ§icisi) WebToApk.addContact(id, json) <- KiΕiler yazma izni gerekir
Kendi baΕΔ±na deΔil, grubuyla birlikte anlatΔ±lΔ±r: KiΕiler.
Örnek
Telefonun rehberini sayfa sayfa, ada gΓΆre A'dan Z'ye sΔ±ralΔ± okur.
DΓΆner deΔer: Δ°Εlem artΔ±k hiΓ§bir Εey dΓΆndΓΌrmez. YanΔ±t daha sonra detail = { requestId, contacts: [{ id, displayName, photoUri, phones: [{ number, type }], emails: ['[email protected]'] }] } ile birlikte appmint:contacts olayΔ± olarak (ve window.onAppMintContacts) ya da { requestId, error } olarak gelir. Gerekenler: derleme yaparken AdΔ±m 4'te (EriΕim) KiΕiler seΓ§eneΔini aΓ§Δ±n; ilk Γ§aΔrΔ±da kullanΔ±cΔ±dan izin istenir.
Δ°lk 100 kiΕiyi yΓΌkleyin. YanΔ±tΔ± kendi requestId.
function loadContacts() {
if (!(window.WebToApk && window.WebToApk.listContacts)) {
showMessage('Contacts work only inside the app.');
return;
}
var id = 'contacts-' + Date.now();
window.addEventListener('appmint:contacts', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return; // another call's answer
window.removeEventListener('appmint:contacts', handler);
if (e.detail.error) { showMessage('Could not read contacts: ' + e.detail.error); return; }
var list = document.getElementById('list');
list.innerHTML = '';
e.detail.contacts.forEach(function (c) {
var li = document.createElement('li');
var num = c.phones.length ? c.phones[0].number + ' (' + c.phones[0].type + ')' : '';
li.textContent = c.displayName + ' ' + num;
list.appendChild(li);
});
});
WebToApk.listContacts(id, 100, 0); // limit 100, start at 0
}Sonraki sayfa. Elinizdeki sayΔ±yΔ± Εu olarak verin: offset: WebToApk.listContacts(id, 100, 100).
KΔ±sa bir sayfa sonuna ulaΕtΔ±ΔΔ±nΔ±zΔ± sΓΆyleyene kadar tΓΌm rehberi 500'lΓΌk sayfalar halinde yΓΌkleyin:
function listPage(limit, offset) {
return new Promise(function (resolve, reject) {
var id = 'page-' + offset + '-' + Date.now();
window.addEventListener('appmint:contacts', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:contacts', handler);
if (e.detail.error) reject(new Error(e.detail.error));
else resolve(e.detail.contacts);
});
WebToApk.listContacts(id, limit, offset);
});
}
async function loadEveryContact() {
if (!(window.WebToApk && window.WebToApk.listContacts)) return [];
var all = [];
while (true) {
var page = await listPage(500, all.length);
all = all.concat(page);
if (page.length < 500) return all; // last page
}
}YalnΔ±zca cep numaralarΔ±ndan bir "ArkadaΕlarΔ± davet et" listesi oluΕturun ve okuma reddedildiΔinde kullanΔ±cΔ±ya ne yapacaΔΔ±nΔ± sΓΆyleyin:
function showInviteList() {
if (!(window.WebToApk && window.WebToApk.listContacts)) return;
var id = 'invite-' + Date.now();
window.addEventListener('appmint:contacts', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:contacts', handler);
if (e.detail.error === 'permission_denied') { showMessage('Allow Contacts to invite friends.'); return; }
if (e.detail.error) { showMessage('Contacts are not available: ' + e.detail.error); return; }
var mobiles = [];
e.detail.contacts.forEach(function (c) {
c.phones.forEach(function (p) {
if (p.type === 'mobile') mobiles.push({ name: c.displayName, number: p.number });
});
});
renderInviteList(mobiles); // your own list UI
});
WebToApk.listContacts(id, 500, 0);
}Notlar: limit deΔeri 1-2000 aralΔ±ΔΔ±na sΔ±nΔ±rlanΔ±r. Hatalar: not_enabled (derleme sΔ±rasΔ±nda KiΕiler kapalΔ±ydΔ±), permission_denied (kullanΔ±cΔ± HayΔ±r dedi), foreign_origin (uygulamanΔ±zΔ±n kendi sayfasΔ± olmayan bir sayfadan Γ§aΔrΔ±ldΔ±). Telefon type deΔeri home, mobile, work, main, work_fax, home_fax veya other olur. photoUri, bir content:// adresidir; sayfanΔ±n yΓΌkleyebileceΔi bir gΓΆrsel URL'si deΔildir. KullanΔ±cΔ±nΔ±n yalnΔ±zca bir kiΕi seΓ§mesini istiyorsanΔ±z bunun yerine pickContact kullanΔ±n; izin gerektirmez. KiΕiler kiΕisel veridir: Play Store sayfanΔ±z bunu Veri gΓΌvenliΔi formunda ve gizlilik politikasΔ±nda belirtmelidir.
pickContact köprü#
window.WebToApk.pickContact(requestId: String)
Sistem kişi seçici - İZİN GEREKTİRMEZ ve sayfanın yalnızca kullanıcının bir kişi seçmesini istediği her durumda doğru seçimdir. Kişi tablosundan değil TELEFON tablosundan seçer: seçici yalnızca döndürdüğü satıra okuma erişimi verir, bu yüzden bir telefon satırı seçmek numarayı READ_CONTACTS olmadan okunabilir kılar. Çıplak bir kişi seçmek adı olan ama numarası olmayan bir satır döndürür ve numarayı ondan okumak, bu yöntemin kaçındığı izni gerektirir.
Örnek
Android'in kendi kiΕi seΓ§icisini aΓ§ar; kullanΔ±cΔ± bir telefon numarasΔ± seΓ§er. Δ°zin gerekmez.
DΓΆner deΔer: Δ°Εlem artΔ±k hiΓ§bir Εey dΓΆndΓΌrmez. YanΔ±t, detail = { requestId, contact: { id, displayName, photoUri, phones: [{ number, type: 'picked' }], emails: [] } } ile birlikte appmint:contacts olayΔ±dΔ±r (ve window.onAppMintContacts). KullanΔ±cΔ± seΓ§iciyi kapatΔ±rsa: { requestId, error: 'cancelled' }. Gerekenler: hiΓ§bir Εey; derleme anahtarΔ± yok, izin isteΔi yok.
Bir formu seΓ§ilen kiΕiyle doldurun.
function chooseContact() {
if (!(window.WebToApk && window.WebToApk.pickContact)) {
showMessage('Open this page in the app to pick a contact.');
return;
}
var id = 'pick-' + Date.now();
window.addEventListener('appmint:contacts', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:contacts', handler);
if (e.detail.error === 'cancelled') return; // user closed the picker
if (e.detail.error) { showMessage('Could not open contacts'); return; }
if (!e.detail.contact) { showMessage('Could not read that contact'); return; }
var c = e.detail.contact;
document.getElementById('name').value = c.displayName;
document.getElementById('phone').value = c.phones.length ? c.phones[0].number : '';
});
WebToApk.pickContact(id);
}KΔ±sa bir acil durum kiΕileri listesi tutun. id deΔil, ad ve numarayΔ± kaydedin; bΓΆylece liste rehbere baΔlΔ± kalmaz:
function pickOne() {
return new Promise(function (resolve, reject) {
var id = 'sos-' + Date.now();
window.addEventListener('appmint:contacts', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:contacts', handler);
if (e.detail.error === 'cancelled') resolve(null);
else if (e.detail.error) reject(new Error(e.detail.error));
else resolve(e.detail.contact);
});
WebToApk.pickContact(id);
});
}
document.getElementById('add-sos').addEventListener('click', async function () {
if (!(window.WebToApk && window.WebToApk.pickContact)) return;
var c = await pickOne();
if (!c || !c.phones.length) return; // closed, or nothing readable
var list = JSON.parse(localStorage.getItem('sos') || '[]');
list.push({ name: c.displayName, number: c.phones[0].number });
localStorage.setItem('sos', JSON.stringify(list));
renderSosList(list);
});SeΓ§ici aΓ§Δ±kken dΓΌΔmeyi devre dΔ±ΕΔ± bΔ±rakΔ±n ve telefonda kiΕiler uygulamasΔ± yoksa yazΔ±m alanlarΔ±nΔ± gΓΆsterin:
var pickBtn = document.getElementById('pick');
pickBtn.addEventListener('click', function () {
if (!(window.WebToApk && window.WebToApk.pickContact)) { showManualEntry(); return; }
var id = 'recipient-' + Date.now();
pickBtn.disabled = true; // one picker at a time
window.addEventListener('appmint:contacts', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:contacts', handler);
pickBtn.disabled = false;
if (e.detail.error === 'no_picker') { showManualEntry(); return; }
if (e.detail.error) return; // 'cancelled'
if (e.detail.contact && e.detail.contact.phones.length) {
document.getElementById('to').value = e.detail.contact.phones[0].number;
}
});
WebToApk.pickContact(id);
});Notlar: AdΔ± ve kullanΔ±cΔ±nΔ±n dokunduΔu TEK numarayΔ± alΔ±rsΔ±nΔ±z; e-postalarΔ± ve rehberin geri kalanΔ±nΔ± asla. emails her zaman boΕtur. Hatalar: cancelled, no_picker (telefonda kiΕiler uygulamasΔ± yok). SeΓ§imden sonra okuma baΕarΔ±sΔ±z olursa contact deΔeri null olur. KullanΔ±cΔ±nΔ±n seΓ§imi olmadan hiΓ§bir Εey okunmadΔ±ΔΔ± iΓ§in bu, Play'e uygun biΓ§imde telefon numarasΔ± almanΔ±n yoludur; yalnΔ±zca bir kiΕiye ihtiyacΔ±nΔ±z olduΔunda listContacts yerine bunu tercih edin. Yapay zekΓ’yla oluΕturulan uygulamalarda ve Google AI Studio iΓ§e aktarmalarΔ±nda derleme kodunuzu tarar; pickContact( Γ§aΔrΔ±sΔ± KiΕiler seΓ§eneΔini iΕaretlemez, yalnΔ±zca listContacts, searchContacts ve getContact iΕaretler; bu yΓΌzden seΓ§ici kiΕi okuma izni eklemez.
searchContacts köprü#
window.WebToApk.searchContacts(requestId: String, query: String, limit: Int)
Hepsi asenkron: imleΓ§ okumalarΔ± binlerce satΔ±r olabilir ve engelleyici bir @JavascriptInterface dΓΆnΓΌΕΓΌ bunu JS iΕ parΓ§acΔ±ΔΔ±nda Γ§alΔ±ΕtΔ±rΔ±rdΔ±; bu da ANR demektir. SonuΓ§lar `appmint:contacts` / window.onAppMintContacts({requestId,...}) olarak gelir. requestId: bir STRING verin ('pick-' + Date.now()). Ham bir SAYI da Γ§alΔ±ΕΔ±r; kΓΆprΓΌ onu bir double ΓΌzerinden dΓΆnΓΌΕtΓΌrΓΌr ("1.787491234567E12") ve her yanΔ±t onu yeniden asΔ±l haline getirir (BridgeRequestId), bΓΆylece `res.requestId === Date.now()` katΔ± karΕΔ±laΕtΔ±rmasΔ± her iki durumda da doΔru Γ§Δ±kar. WebToApk.listContacts(id, limit, offset) WebToApk.searchContacts(id, query, limit) WebToApk.getContact(id, contactId) WebToApk.pickContact(id) <- Δ°zin GEREKMEZ (sistem seΓ§icisi) WebToApk.addContact(id, json) <- KiΕiler yazma izni gerekir
Kendi baΕΔ±na deΔil, grubuyla birlikte anlatΔ±lΔ±r: KiΕiler.
Örnek
TΓΌm rehberi yΓΌklemeden, adΔ± bir arama sΓΆzcΓΌΔΓΌyle eΕleΕen kiΕileri bulur.
DΓΆner deΔer: Δ°Εlem artΔ±k hiΓ§bir Εey dΓΆndΓΌrmez. YanΔ±t, detail = { requestId, contacts: [...] } ile birlikte appmint:contacts olayΔ±dΔ±r (ve window.onAppMintContacts); listContacts ile aynΔ± kiΕi yapΔ±sΔ± ya da { requestId, error }. Gerekenler: derleme yaparken AdΔ±m 4'te (EriΕim) KiΕiler seΓ§eneΔini aΓ§Δ±n; ilk Γ§aΔrΔ±da kullanΔ±cΔ±dan izin istenir.
KullanΔ±cΔ± yazdΔ±kΓ§a arayΔ±n. YalnΔ±zca en son aramanΔ±n yanΔ±tΔ± gΓΆsterilir.
var lastSearchId = '';
function searchPeople(word) {
if (!(window.WebToApk && window.WebToApk.searchContacts)) return;
lastSearchId = 'search-' + Date.now();
WebToApk.searchContacts(lastSearchId, word, 20); // at most 20 results
}
window.addEventListener('appmint:contacts', function (e) {
if (!e.detail || e.detail.requestId !== lastSearchId) return; // old or other request
if (e.detail.error) { showMessage('Search failed: ' + e.detail.error); return; }
var names = e.detail.contacts.map(function (c) {
return c.displayName + (c.phones.length ? ' - ' + c.phones[0].number : '');
});
document.getElementById('results').textContent = names.join('\n') || 'No match';
});
document.getElementById('q').addEventListener('input', function (e) {
searchPeople(e.target.value);
});AramayΔ± bir Promise iΓ§ine alΔ±n ve kullanΔ±cΔ± yazmayΔ± bΔ±rakana kadar bekleyin; bΓΆylece hΔ±zlΔ± yazΔ±m her tuΕ iΓ§in bir arama baΕlatmaz:
function searchOnce(word, limit) {
return new Promise(function (resolve, reject) {
var id = 'find-' + Date.now() + '-' + Math.random().toString(36).slice(2);
window.addEventListener('appmint:contacts', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:contacts', handler);
if (e.detail.error) reject(new Error(e.detail.error)); else resolve(e.detail.contacts);
});
WebToApk.searchContacts(id, word, limit);
});
}
var timer = null;
document.getElementById('q').addEventListener('input', function (e) {
clearTimeout(timer);
var word = e.target.value.trim();
timer = setTimeout(function () {
if (!(window.WebToApk && window.WebToApk.searchContacts) || !word) return;
searchOnce(word, 10)
.then(function (people) { renderSuggestions(people); })
.catch(function (err) { showMessage('Search failed: ' + err.message); });
}, 300);
});YazΔ±lan ad e-postasΔ± olan tek bir kiΕiyle eΕleΕtiΔinde e-posta kutusunu rehberden doldurun:
function suggestEmail(name) {
if (!(window.WebToApk && window.WebToApk.searchContacts) || name.length < 2) return;
var id = 'email-' + Date.now();
window.addEventListener('appmint:contacts', function handler(e) {
if (!e.detail || e.detail.requestId !== id) return;
window.removeEventListener('appmint:contacts', handler);
if (e.detail.error) return; // leave the box for the user to type
var withEmail = e.detail.contacts.filter(function (c) { return c.emails.length > 0; });
if (withEmail.length === 1) {
document.getElementById('email').value = withEmail[0].emails[0];
}
});
WebToApk.searchContacts(id, name, 5);
}
document.getElementById('name').addEventListener('change', function (e) {
suggestEmail(e.target.value.trim());
});Notlar: BoΕ bir arama sΓΆzcΓΌΔΓΌ, listenin baΕΔ±ndan kiΕileri dΓΆndΓΌrΓΌr (listContacts gibi). limit 1-2000 aralΔ±ΔΔ±na sΔ±nΔ±rlanΔ±r ve ofset yoktur. Hatalar: not_enabled, permission_denied, foreign_origin. KiΕiler kiΕisel veridir: Play Store sayfanΔ±z bunu Veri gΓΌvenliΔi formunda ve gizlilik politikasΔ±nda belirtmelidir.