JavaScript köprü API'si
BLE fitness sensörleri
Standart Bluetooth Low Energy profillerinden kalp atışı, hız, pedal çevirme hızı (kadans), güç ve pil.
AppMint.beacons yardımcı#
AppMint.beacons.startScan(options) / stopScan() / isScanning()
Örnek
Yakındaki Bluetooth beacon'larını - iBeacon ve Eddystone (UID, URL ve TLM) - bulur ve her birini yaklaşık saniyede bir appmint:beacon olayıyla, sinyal gücü ve yaklaşık mesafeyle sayfaya bildirir.
Döndürür: startScan() → {ok: true} veya {ok: false, code} (not_enabled, permission_denied, bluetooth_off, bluetooth_unavailable, scan_failed, blocked) değerinin Promise'i. stopScan() → {ok: true}. isScanning() → true/false. Gerekenler: işaretlenecek bir şey yok - kodu beacons.startScan çağıran bir derleme Bluetooth taraması ve hassas konum izinlerini bildirir (beacon sonuçları Android için konum verisidir, bu yüzden kullanıcıdan ikisi de istenir ve Play uygulamayı konum kullanan olarak listeler).
Bir mekânın beacon'larını arayın:
window.addEventListener('appmint:beacon', function (e) {
var b = e.detail;
if (b.type === 'ibeacon') {
showNearest(b.uuid, b.major, b.minor, b.distance); // metres, a rough estimate
} else if (b.type === 'eddystone-url') {
offerLink(b.url);
} else if (b.type === 'state') {
console.log('beacon scan ' + b.state); // 'scanning' | 'stopped'
} else if (b.type === 'error') {
console.warn('beacon scan error', b.error);
}
});
async function startRanging() {
if (!(window.AppMint && AppMint.beacons)) return;
var r = await AppMint.beacons.startScan({ uuids: ['e2c56db5-dffb-48d2-b060-d0f5a71096e0'] });
if (!r.ok) alert(r.code === 'bluetooth_off' ? 'Turn on Bluetooth' : 'Cannot scan: ' + r.code);
}Yalnızca Eddystone, pil telemetrisiyle:
AppMint.beacons.startScan({ ibeacon: false });
window.addEventListener('appmint:beacon', function (e) {
var b = e.detail;
if (b.type === 'eddystone-uid') console.log(b.namespace, b.instance, b.rssi, b.distance);
if (b.type === 'eddystone-tlm') console.log(b.address, b.batteryMilliVolts + ' mV', b.temperatureC + ' °C');
});Ekrandan ayrılırken durdurun:
document.addEventListener('visibilitychange', async function () {
if (document.visibilityState === 'hidden' && await AppMint.beacons.isScanning()) AppMint.beacons.stopScan();
});Olay alanları: her beacon'da type, rssi, address, timestamp vardır; iBeacon uuid, major, minor, txPower, distance ekler; Eddystone UID namespace, instance, txPower, distance ekler; URL url ekler; TLM batteryMilliVolts, temperatureC, advertCount, uptimeSeconds ekler. uuids iBeacon UUID'lerini ve Eddystone ad alanlarını (küçük harf onaltılık) filtreler.
Notlar: Mesafe sinyal gücünden hesaplanır ve yalnızca yakın / uzak için uygundur - duvarlar ve insan bedenleri onu metrelerce değiştirir. Tarama stopScan() çağrısına veya uygulama kapanana kadar sürer.
beaconIsScanning köprü#
window.WebToApk.beaconIsScanning(): Boolean
Bir beacon taramasının çalışıp çalışmadığı.
Örnek
AppMint.beacons ile birlikte belgelenmiştir - oradaki örnek bunu da gösterir.
Yakındaki Bluetooth beacon'larını - iBeacon ve Eddystone (UID, URL ve TLM) - bulur ve her birini yaklaşık saniyede bir appmint:beacon olayıyla, sinyal gücü ve yaklaşık mesafeyle sayfaya bildirir.
Döndürür: startScan() → {ok: true} veya {ok: false, code} (not_enabled, permission_denied, bluetooth_off, bluetooth_unavailable, scan_failed, blocked) değerinin Promise'i. stopScan() → {ok: true}. isScanning() → true/false. Gerekenler: işaretlenecek bir şey yok - kodu beacons.startScan çağıran bir derleme Bluetooth taraması ve hassas konum izinlerini bildirir (beacon sonuçları Android için konum verisidir, bu yüzden kullanıcıdan ikisi de istenir ve Play uygulamayı konum kullanan olarak listeler).
Bir mekânın beacon'larını arayın:
window.addEventListener('appmint:beacon', function (e) {
var b = e.detail;
if (b.type === 'ibeacon') {
showNearest(b.uuid, b.major, b.minor, b.distance); // metres, a rough estimate
} else if (b.type === 'eddystone-url') {
offerLink(b.url);
} else if (b.type === 'state') {
console.log('beacon scan ' + b.state); // 'scanning' | 'stopped'
} else if (b.type === 'error') {
console.warn('beacon scan error', b.error);
}
});
async function startRanging() {
if (!(window.AppMint && AppMint.beacons)) return;
var r = await AppMint.beacons.startScan({ uuids: ['e2c56db5-dffb-48d2-b060-d0f5a71096e0'] });
if (!r.ok) alert(r.code === 'bluetooth_off' ? 'Turn on Bluetooth' : 'Cannot scan: ' + r.code);
}Yalnızca Eddystone, pil telemetrisiyle:
AppMint.beacons.startScan({ ibeacon: false });
window.addEventListener('appmint:beacon', function (e) {
var b = e.detail;
if (b.type === 'eddystone-uid') console.log(b.namespace, b.instance, b.rssi, b.distance);
if (b.type === 'eddystone-tlm') console.log(b.address, b.batteryMilliVolts + ' mV', b.temperatureC + ' °C');
});Ekrandan ayrılırken durdurun:
document.addEventListener('visibilitychange', async function () {
if (document.visibilityState === 'hidden' && await AppMint.beacons.isScanning()) AppMint.beacons.stopScan();
});Olay alanları: her beacon'da type, rssi, address, timestamp vardır; iBeacon uuid, major, minor, txPower, distance ekler; Eddystone UID namespace, instance, txPower, distance ekler; URL url ekler; TLM batteryMilliVolts, temperatureC, advertCount, uptimeSeconds ekler. uuids iBeacon UUID'lerini ve Eddystone ad alanlarını (küçük harf onaltılık) filtreler.
Notlar: Mesafe sinyal gücünden hesaplanır ve yalnızca yakın / uzak için uygundur - duvarlar ve insan bedenleri onu metrelerce değiştirir. Tarama stopScan() çağrısına veya uygulama kapanana kadar sürer.
beaconStartScan köprü#
window.WebToApk.beaconStartScan(optionsJson: String, callbackId: String)
[optionsJson] `{uuids?, ibeacon?, eddystone?}` ile beacon aramasını başlatır; [callbackId] değerini `{ok}` veya `{ok:false, code}` ile çözer.
Örnek
AppMint.beacons ile birlikte belgelenmiştir - oradaki örnek bunu da gösterir.
Yakındaki Bluetooth beacon'larını - iBeacon ve Eddystone (UID, URL ve TLM) - bulur ve her birini yaklaşık saniyede bir appmint:beacon olayıyla, sinyal gücü ve yaklaşık mesafeyle sayfaya bildirir.
Döndürür: startScan() → {ok: true} veya {ok: false, code} (not_enabled, permission_denied, bluetooth_off, bluetooth_unavailable, scan_failed, blocked) değerinin Promise'i. stopScan() → {ok: true}. isScanning() → true/false. Gerekenler: işaretlenecek bir şey yok - kodu beacons.startScan çağıran bir derleme Bluetooth taraması ve hassas konum izinlerini bildirir (beacon sonuçları Android için konum verisidir, bu yüzden kullanıcıdan ikisi de istenir ve Play uygulamayı konum kullanan olarak listeler).
Bir mekânın beacon'larını arayın:
window.addEventListener('appmint:beacon', function (e) {
var b = e.detail;
if (b.type === 'ibeacon') {
showNearest(b.uuid, b.major, b.minor, b.distance); // metres, a rough estimate
} else if (b.type === 'eddystone-url') {
offerLink(b.url);
} else if (b.type === 'state') {
console.log('beacon scan ' + b.state); // 'scanning' | 'stopped'
} else if (b.type === 'error') {
console.warn('beacon scan error', b.error);
}
});
async function startRanging() {
if (!(window.AppMint && AppMint.beacons)) return;
var r = await AppMint.beacons.startScan({ uuids: ['e2c56db5-dffb-48d2-b060-d0f5a71096e0'] });
if (!r.ok) alert(r.code === 'bluetooth_off' ? 'Turn on Bluetooth' : 'Cannot scan: ' + r.code);
}Yalnızca Eddystone, pil telemetrisiyle:
AppMint.beacons.startScan({ ibeacon: false });
window.addEventListener('appmint:beacon', function (e) {
var b = e.detail;
if (b.type === 'eddystone-uid') console.log(b.namespace, b.instance, b.rssi, b.distance);
if (b.type === 'eddystone-tlm') console.log(b.address, b.batteryMilliVolts + ' mV', b.temperatureC + ' °C');
});Ekrandan ayrılırken durdurun:
document.addEventListener('visibilitychange', async function () {
if (document.visibilityState === 'hidden' && await AppMint.beacons.isScanning()) AppMint.beacons.stopScan();
});Olay alanları: her beacon'da type, rssi, address, timestamp vardır; iBeacon uuid, major, minor, txPower, distance ekler; Eddystone UID namespace, instance, txPower, distance ekler; URL url ekler; TLM batteryMilliVolts, temperatureC, advertCount, uptimeSeconds ekler. uuids iBeacon UUID'lerini ve Eddystone ad alanlarını (küçük harf onaltılık) filtreler.
Notlar: Mesafe sinyal gücünden hesaplanır ve yalnızca yakın / uzak için uygundur - duvarlar ve insan bedenleri onu metrelerce değiştirir. Tarama stopScan() çağrısına veya uygulama kapanana kadar sürer.
beaconStopScan köprü#
window.WebToApk.beaconStopScan(callbackId: String)
Beacon aramasını durdurur; [callbackId] değerini `{ok:true}` ile çözer.
Örnek
AppMint.beacons ile birlikte belgelenmiştir - oradaki örnek bunu da gösterir.
Yakındaki Bluetooth beacon'larını - iBeacon ve Eddystone (UID, URL ve TLM) - bulur ve her birini yaklaşık saniyede bir appmint:beacon olayıyla, sinyal gücü ve yaklaşık mesafeyle sayfaya bildirir.
Döndürür: startScan() → {ok: true} veya {ok: false, code} (not_enabled, permission_denied, bluetooth_off, bluetooth_unavailable, scan_failed, blocked) değerinin Promise'i. stopScan() → {ok: true}. isScanning() → true/false. Gerekenler: işaretlenecek bir şey yok - kodu beacons.startScan çağıran bir derleme Bluetooth taraması ve hassas konum izinlerini bildirir (beacon sonuçları Android için konum verisidir, bu yüzden kullanıcıdan ikisi de istenir ve Play uygulamayı konum kullanan olarak listeler).
Bir mekânın beacon'larını arayın:
window.addEventListener('appmint:beacon', function (e) {
var b = e.detail;
if (b.type === 'ibeacon') {
showNearest(b.uuid, b.major, b.minor, b.distance); // metres, a rough estimate
} else if (b.type === 'eddystone-url') {
offerLink(b.url);
} else if (b.type === 'state') {
console.log('beacon scan ' + b.state); // 'scanning' | 'stopped'
} else if (b.type === 'error') {
console.warn('beacon scan error', b.error);
}
});
async function startRanging() {
if (!(window.AppMint && AppMint.beacons)) return;
var r = await AppMint.beacons.startScan({ uuids: ['e2c56db5-dffb-48d2-b060-d0f5a71096e0'] });
if (!r.ok) alert(r.code === 'bluetooth_off' ? 'Turn on Bluetooth' : 'Cannot scan: ' + r.code);
}Yalnızca Eddystone, pil telemetrisiyle:
AppMint.beacons.startScan({ ibeacon: false });
window.addEventListener('appmint:beacon', function (e) {
var b = e.detail;
if (b.type === 'eddystone-uid') console.log(b.namespace, b.instance, b.rssi, b.distance);
if (b.type === 'eddystone-tlm') console.log(b.address, b.batteryMilliVolts + ' mV', b.temperatureC + ' °C');
});Ekrandan ayrılırken durdurun:
document.addEventListener('visibilitychange', async function () {
if (document.visibilityState === 'hidden' && await AppMint.beacons.isScanning()) AppMint.beacons.stopScan();
});Olay alanları: her beacon'da type, rssi, address, timestamp vardır; iBeacon uuid, major, minor, txPower, distance ekler; Eddystone UID namespace, instance, txPower, distance ekler; URL url ekler; TLM batteryMilliVolts, temperatureC, advertCount, uptimeSeconds ekler. uuids iBeacon UUID'lerini ve Eddystone ad alanlarını (küçük harf onaltılık) filtreler.
Notlar: Mesafe sinyal gücünden hesaplanır ve yalnızca yakın / uzak için uygundur - duvarlar ve insan bedenleri onu metrelerce değiştirir. Tarama stopScan() çağrısına veya uygulama kapanana kadar sürer.
bleConnect köprü#
window.WebToApk.bleConnect(address: String)
permBluetooth için çalışma zamanı. Hiçbir sihirbaz anahtarı bunu ayarlamaz: derleme, sayfanın kendi kodu bu yöntemleri (veya Web Bluetooth'u) çağırdığında bunu etkinleştirir. Bu çalışma zamanından önce izinler, çalışma zamanındaki hiçbir şey bir sensöre dokunmazken bildiriliyordu; SmsBridge'in belgelediği "bildirilmiş ama işlevsiz" örüntünün aynısı. Sonuçlar `appmint:ble` olayları / window.onAppMintBle({kind, ...}) olarak akar.
Kendi başına değil, grubuyla anlatılmıştır: BLE fitness sensörleri (kalp atışı / hız / kadans / güç / pil).
Örnek
bleStartScan() ile bulunan bir fitness sensörüne bağlanır ve okumalarını akıtmaya başlar.
Döndürür: hiçbir şey. İlerleme ve veriler appmint:ble olayları (ve window.onAppMintBle) olarak gelir: {kind:'state', state:'connecting', address}, {kind:'state', state:'connected', address}, {kind:'state', state:'ready', services:[...]}, sonra her okuma için {kind:'data', type, data}. Gerekenler: Bluetooth (kodunuz sensör köprüsünü kullandığında bir ZIP veya HTML derlemesi tarafından açılır) ve ilk kullanımda sorulan Yakındaki cihazlar izni.
Bir device olayından gelen address değerini kullanıcının dokunuşundan geçirin:
function connectSensor(address) {
if (!window.WebToApk || typeof window.WebToApk.bleConnect !== 'function') return;
window.WebToApk.bleConnect(address);
}
window.onAppMintBle = function (d) {
if (d.kind === 'state') {
// 'connecting' | 'connected' | 'ready' | 'disconnected' (also 'scanning' / 'scan_stopped')
showStatus(d.state);
} else if (d.kind === 'data') {
if (d.type === 'heart_rate') show('bpm', d.data.bpm);
if (d.type === 'speed_cadence') { // either key can be missing in one packet
if (d.data.speedKmh !== undefined) show('speed', d.data.speedKmh.toFixed(1) + ' km/h');
if (d.data.cadenceRpm !== undefined) show('cadence', Math.round(d.data.cadenceRpm) + ' rpm');
}
if (d.type === 'power') show('power', d.data.watts + ' W');
if (d.type === 'running') show('pace', d.data.speedKmh.toFixed(1) + ' km/h, ' + d.data.cadenceSpm + ' spm');
if (d.type === 'battery') show('battery', d.data.percent + '%');
} else if (d.kind === 'error') {
showStatus('Could not connect: ' + d.error);
}
};Bağlanan sensörü hatırlayın ve bir sonraki sefer tarama yapmadan ona yeniden bağlanın:
var SAVED_KEY = 'hrStrapAddress';
window.addEventListener('appmint:ble', function (e) {
var d = e.detail;
if (d.kind === 'state' && d.state === 'connected') localStorage.setItem(SAVED_KEY, d.address);
if (d.kind === 'error' && d.error === 'invalid_address') localStorage.removeItem(SAVED_KEY);
});
document.getElementById('start-workout').addEventListener('click', function () {
if (!window.WebToApk || typeof window.WebToApk.bleConnect !== 'function') return;
var address = localStorage.getItem(SAVED_KEY);
if (address) window.WebToApk.bleConnect(address);
else window.WebToApk.bleStartScan(); // first time: let the user pick a sensor
});Okumalardan bir kalp atışı oturumunu (ortalama, maksimum, kayış teması) takip edin:
var beats = 0, sum = 0, max = 0;
window.addEventListener('appmint:ble', function (e) {
var d = e.detail;
if (d.kind === 'state' && d.state === 'ready' && d.services.length === 0) {
showStatus('This sensor has no heart rate, speed, power or battery service.');
}
if (d.kind !== 'data' || d.type !== 'heart_rate') return;
if (d.data.contact === false) { // only sent by straps that report skin contact
showStatus('Wet the strap: no skin contact');
return;
}
beats++; sum += d.data.bpm; max = Math.max(max, d.data.bpm);
show('bpm', d.data.bpm);
show('avg', Math.round(sum / beats));
show('max', max);
});Notlar: Aynı anda tek sensör: bağlanmak her taramayı durdurur ve önceki sensörü önce bırakır (onun disconnected olayını alırsınız). ready.services, bu sensörün sahip olduğu desteklenen hizmetlerin tam UUID'lerini listeler. Bağlandıktan sonraki ilk hız/kadans paketi hiçbir şey göndermez - hız ve kadansın hesaplanması için iki paket gerekir. heart_rate ayrıca rrIntervalsMs (atımlar arası aralıklar, ms, kayış gönderiyorsa), kayış bildirirse energyKj ve contact taşır; power, ölçer pedal verisi gönderiyorsa ikinci paketten itibaren cadenceRpm taşır. Hatalar: not_enabled, permission_denied, bluetooth_unavailable, invalid_address. Sensör menzil dışına çıkarsa şunu alırsınız {kind:'state', state:'disconnected', address}.
bleDisconnect köprü#
window.WebToApk.bleDisconnect()
permBluetooth için çalışma zamanı. Hiçbir sihirbaz anahtarı bunu ayarlamaz: derleme, sayfanın kendi kodu bu yöntemleri (veya Web Bluetooth'u) çağırdığında bunu etkinleştirir. Bu çalışma zamanından önce izinler, çalışma zamanındaki hiçbir şey bir sensöre dokunmazken bildiriliyordu; SmsBridge'in belgelediği "bildirilmiş ama işlevsiz" örüntünün aynısı. Sonuçlar `appmint:ble` olayları / window.onAppMintBle({kind, ...}) olarak akar.
Kendi başına değil, grubuyla anlatılmıştır: BLE fitness sensörleri (kalp atışı / hız / kadans / güç / pil).
Örnek
Şununla bağlanan fitness sensörünün bağlantısını keser bleConnect().
Döndürür: hiçbir şey. Bir sensör bağlıysa ardından bir appmint:ble olayı {kind:'state', state:'disconnected'} gelir. Gerekenler: Bluetooth (kodunuz sensör köprüsünü kullandığında bir ZIP veya HTML derlemesi tarafından açılır); olmadan çağrı hiçbir şey yapmaz.
document.getElementById('end-workout').addEventListener('click', function () {
if (window.WebToApk && typeof window.WebToApk.bleDisconnect === 'function') {
window.WebToApk.bleDisconnect();
}
});
window.addEventListener('appmint:ble', function (e) {
if (e.detail.kind === 'state' && e.detail.state === 'disconnected') {
showStatus('Sensor disconnected');
}
});Sensör bağlantıyı kaybettiğinde kendiliğinden yeniden bağlanın, ancak kullanıcı antrenmanı bitirdiyse bağlanmayın:
var lastAddress = null, userEnded = false, retries = 0;
window.addEventListener('appmint:ble', function (e) {
var d = e.detail;
if (d.kind !== 'state') return;
if (d.state === 'connected') { lastAddress = d.address; userEnded = false; retries = 0; }
// Only a drop caused by the sensor carries an address.
if (d.state === 'disconnected' && d.address && !userEnded && lastAddress && retries < 3) {
retries++;
showStatus('Sensor lost, reconnecting (' + retries + '/3)...');
setTimeout(function () { window.WebToApk.bleConnect(lastAddress); }, 3000);
}
});
function endWorkout() {
userEnded = true;
if (window.WebToApk && typeof window.WebToApk.bleDisconnect === 'function') {
window.WebToApk.bleDisconnect();
}
}Bir ayarlar ekranından bağlantıyı kesin ve kaydedilen sensörü unutun:
document.getElementById('forget-sensor').addEventListener('click', function () {
localStorage.removeItem('hrStrapAddress'); // wherever your app saved the address
if (window.WebToApk && typeof window.WebToApk.bleDisconnect === 'function') {
window.WebToApk.bleDisconnect();
}
showStatus('Sensor forgotten. Tap Scan to pair a new one.');
});Notlar: Kendinizin neden olduğu disconnected olayında address yoktur; sensörün neden olduğu (menzil dışı, kapatılmış) olayda vardır. Uygulama kapandığında da bağlantı kesilir.
bleSetWheelCircumference köprü#
window.WebToApk.bleSetWheelCircumference(mm: Int)
permBluetooth için çalışma zamanı. Hiçbir sihirbaz anahtarı bunu ayarlamaz: derleme, sayfanın kendi kodu bu yöntemleri (veya Web Bluetooth'u) çağırdığında bunu etkinleştirir. Bu çalışma zamanından önce izinler, çalışma zamanındaki hiçbir şey bir sensöre dokunmazken bildiriliyordu; SmsBridge'in belgelediği "bildirilmiş ama işlevsiz" örüntünün aynısı. Sonuçlar `appmint:ble` olayları / window.onAppMintBle({kind, ...}) olarak akar.
Kendi başına değil, grubuyla anlatılmıştır: BLE fitness sensörleri (kalp atışı / hız / kadans / güç / pil).
Örnek
Bir hız sensörünün tekerlek dönüşlerini km/s'ye çevirmek için kullanılan bisiklet tekerlek boyutunu (milimetre cinsinden çevre) ayarlar.
Döndürür: hiçbir şey. Gerekenler: çağırmak için hiçbir şey; hız okumalarının kendisi bağlı bir bisiklet hız sensörü gerektirir (bkz. bleConnect).
// 2096 mm = 700x23c (the default). 2105 = 700x25c, 2136 = 700x28c, 2070 = 26x2.0 MTB.
function setWheel(mm) {
if (window.WebToApk && typeof window.WebToApk.bleSetWheelCircumference === 'function') {
window.WebToApk.bleSetWheelCircumference(mm);
}
}
document.getElementById('wheel').addEventListener('change', function (e) {
setWheel(parseInt(e.target.value, 10));
});Ayar yeniden başlatmada korunmadığı için, bağlandığınız her seferde sürücünün kayıtlı tekerlek boyutunu uygulayın:
function connectBike(address) {
if (!window.WebToApk || typeof window.WebToApk.bleConnect !== 'function') return;
var mm = parseInt(localStorage.getItem('wheelMm'), 10) || 2096;
window.WebToApk.bleSetWheelCircumference(mm);
window.WebToApk.bleConnect(address);
}Ölçülen bir yuvarlanmadan (bir tam tekerlek turu, cm cinsinden) kalibre edin ve aralığı kendiniz kontrol edin, çünkü aralık dışı bir değer hata verilmeden yok sayılır:
document.getElementById('save-rollout').addEventListener('click', function () {
var mm = Math.round(parseFloat(document.getElementById('rollout-cm').value) * 10);
if (!(mm >= 500 && mm <= 4000)) {
showStatus('Enter a roll-out between 50 and 400 cm.');
return;
}
localStorage.setItem('wheelMm', String(mm));
if (window.WebToApk && typeof window.WebToApk.bleSetWheelCircumference === 'function') {
window.WebToApk.bleSetWheelCircumference(mm); // applies to the next speed reading
}
showStatus('Wheel set to ' + mm + ' mm');
});Notlar: 500-4000 mm dışındaki değerler sessizce yok sayılır (eski değer kalır). Ayar uygulama kapanana kadar sürer, bu yüzden her açılıştan sonra tekrar ayarlayın, örneğin hemen bleConnect() öncesinde. appmint:ble içindeki speed_cadence verilerinde speedKmh değerini değiştirir; kadans etkilenmez.
bleStartScan köprü#
window.WebToApk.bleStartScan()
permBluetooth için çalışma zamanı. Hiçbir sihirbaz anahtarı bunu ayarlamaz: derleme, sayfanın kendi kodu bu yöntemleri (veya Web Bluetooth'u) çağırdığında bunu etkinleştirir. Bu çalışma zamanından önce izinler, çalışma zamanındaki hiçbir şey bir sensöre dokunmazken bildiriliyordu; SmsBridge'in belgelediği "bildirilmiş ama işlevsiz" örüntünün aynısı. Sonuçlar `appmint:ble` olayları / window.onAppMintBle({kind, ...}) olarak akar.
Kendi başına değil, grubuyla anlatılmıştır: BLE fitness sensörleri (kalp atışı / hız / kadans / güç / pil).
Örnek
15 saniye boyunca yakındaki Bluetooth fitness sensörlerini (kalp atışı, bisiklet hızı/kadansı, güç, koşu ayak sensörleri) tarar.
Döndürür: hiçbir şey. Sonuçlar appmint:ble olayları (ve window.onAppMintBle(detail)) olarak gelir: bulunan her sensör için bir {kind:'device', address, name, sensors, rssi}, ayrıca başlangıçta {kind:'state', state:'scanning'} ve sonunda {kind:'state', state:'scan_stopped'}. Gerekenler: Bluetooth. Bunun için bir anahtar yoktur: bir ZIP veya HTML sayfasından derlediğinizde, kodunuz bleStartScan / bleConnect çağırırsa veya navigator.bluetooth kullanırsa derleme Bluetooth'u kendiliğinden açar. Bir web sitesi (URL) derlemesi bunu açamaz. İlk tarama kullanıcıdan Yakındaki cihazlar iznini ister (Android 11 ve eskisinde Konum).
Önce dinleyin, sonra bir düğme dokunuşundan tarayın:
var found = {};
window.addEventListener('appmint:ble', function (e) {
var d = e.detail;
if (d.kind === 'device') {
found[d.address] = d;
// d.sensors: any of 'heart_rate', 'speed_cadence', 'power', 'running'
addRow(d.address, (d.name || 'Unnamed sensor') + ' ' + d.sensors.join(', ') + ' (' + d.rssi + ' dBm)');
} else if (d.kind === 'state' && d.state === 'scanning') {
showStatus('Looking for sensors...');
} else if (d.kind === 'state' && d.state === 'scan_stopped') {
showStatus(Object.keys(found).length ? 'Pick a sensor' : 'No sensors found. Wake the sensor and try again.');
} else if (d.kind === 'error') {
showStatus('Bluetooth error: ' + d.error);
}
});
document.getElementById('scan').addEventListener('click', function () {
if (window.WebToApk && typeof window.WebToApk.bleStartScan === 'function') {
found = {};
window.WebToApk.bleStartScan();
} else {
showStatus('Sensors work in the installed app only.');
}
});Tarama bittiğinde en güçlü kalp atışı kayışını otomatik olarak eşleştirin:
var best = null, pairing = false;
window.addEventListener('appmint:ble', function (e) {
var d = e.detail;
if (!pairing) return;
if (d.kind === 'device' && d.sensors.indexOf('heart_rate') !== -1) {
if (!best || d.rssi > best.rssi) best = d; // closer strap = higher (less negative) rssi
} else if (d.kind === 'state' && d.state === 'scan_stopped') {
pairing = false;
if (best) window.WebToApk.bleConnect(best.address);
else showStatus('No heart-rate strap found. Put it on and try again.');
}
});
document.getElementById('pair-hr').addEventListener('click', function () {
if (!window.WebToApk || typeof window.WebToApk.bleStartScan !== 'function') return;
best = null;
pairing = true;
window.WebToApk.bleStartScan();
});Her tarama hatasını kullanıcının harekete geçebileceği bir mesaja çevirin:
var SCAN_HELP = {
not_enabled: 'This app was built without Bluetooth.',
permission_denied: 'Allow Nearby devices for this app in Settings to find sensors.',
bluetooth_unavailable: 'This phone has no Bluetooth.',
bluetooth_off: 'Turn Bluetooth on, then tap Scan again.',
scan_failed: 'The scan could not start. Wait a moment and try again.'
};
window.addEventListener('appmint:ble', function (e) {
var d = e.detail;
if (d.kind !== 'error') return;
var text = SCAN_HELP[d.error] || ('Bluetooth error: ' + d.error);
if (d.code !== undefined) text += ' (code ' + d.code + ')';
showStatus(text);
document.getElementById('scan').disabled = false;
});Notlar: {kind:'error', error} içindeki hata kodları: not_enabled (derlemede Bluetooth yok), permission_denied, bluetooth_unavailable (adaptör yok), bluetooth_off, scan_failed (Android code taşıyabilir). Tarama yalnızca dört fitness hizmetinden birini yayınlayan cihazları bildirir ve her cihazı tarama başına yalnızca bir kez. Yeni bir tarama başlatmak eskisini durdurur. appmint:ble dinleyicisini veya window.onAppMintBle işlevini kullanın, ikisini birden değil - her mesaj için ikisi de çağrılır.
bleStopScan köprü#
window.WebToApk.bleStopScan()
permBluetooth için çalışma zamanı. Hiçbir sihirbaz anahtarı bunu ayarlamaz: derleme, sayfanın kendi kodu bu yöntemleri (veya Web Bluetooth'u) çağırdığında bunu etkinleştirir. Bu çalışma zamanından önce izinler, çalışma zamanındaki hiçbir şey bir sensöre dokunmazken bildiriliyordu; SmsBridge'in belgelediği "bildirilmiş ama işlevsiz" örüntünün aynısı. Sonuçlar `appmint:ble` olayları / window.onAppMintBle({kind, ...}) olarak akar.
Kendi başına değil, grubuyla anlatılmıştır: BLE fitness sensörleri (kalp atışı / hız / kadans / güç / pil).
Örnek
bleStartScan() ile başlatılan sensör taramasını 15 saniye dolmadan durdurur.
Döndürür: hiçbir şey. Bir tarama çalışıyorsa ardından bir appmint:ble olayı {kind:'state', state:'scan_stopped'} gelir. Gerekenler: Bluetooth (kodunuz sensör köprüsünü kullandığında bir ZIP veya HTML derlemesi tarafından açılır); olmadan çağrı hiçbir şey yapmaz.
window.addEventListener('appmint:ble', function (e) {
if (e.detail.kind === 'state' && e.detail.state === 'scan_stopped') {
document.getElementById('scan').disabled = false;
}
});
document.getElementById('stop-scan').addEventListener('click', function () {
if (window.WebToApk && typeof window.WebToApk.bleStopScan === 'function') {
window.WebToApk.bleStopScan();
}
});İhtiyacınız olan sensör türü görünür görünmez erken durdurun:
window.addEventListener('appmint:ble', function (e) {
var d = e.detail;
if (d.kind === 'device' && d.sensors.indexOf('power') !== -1) {
if (window.WebToApk && typeof window.WebToApk.bleStopScan === 'function') {
window.WebToApk.bleStopScan(); // no need to wait the full 15 seconds
}
showPowerMeter(d.address, d.name || 'Power meter');
}
});Kullanıcı eşleştirme sayfasını kapattığında veya uygulamadan ayrıldığında taramayı durdurun:
function stopLooking() {
if (window.WebToApk && typeof window.WebToApk.bleStopScan === 'function') {
window.WebToApk.bleStopScan(); // safe even if the scan already ended
}
}
document.getElementById('close-pairing').addEventListener('click', function () {
stopLooking();
document.getElementById('pairing-sheet').hidden = true;
});
document.addEventListener('visibilitychange', function () {
if (document.hidden) stopLooking();
});Notlar: Buna nadiren ihtiyaç duyarsınız: tarama 15 saniye sonra kendiliğinden durur ve bleConnect() da onu durdurur. Hiç tarama çalışmıyorken çağırmak güvenlidir ve olay göndermez.