API du pont JavaScript
Vibration et son
Retour haptique, le clic sonore propre à l'application déclenché sur vos événements sémantiques plutôt que sur chaque appui parasite, et la piste de musique de fond choisie par le créateur lors de la compilation - getMusicVolume renvoie -1 quand l'application n'en contient aucune, de sorte qu'un écran de paramètres peut masquer le curseur au lieu d'en montrer un inactif.
cancelVibrate pont#
window.WebToApk.cancelVibrate()
Retour haptique simple pour la page (navigator.vibrate et une forme à motif). Les deux sont ignorés sauf si la compilation a activé l'autorisation Vibration.
Décrit par son groupe, Vibration, plutôt que seul.
Exemple
Arrête une vibration encore en cours. La plupart des pages utilisent le standard navigator.vibrate(0), qui l'appelle pour vous.
Renvoie : rien. Nécessite : activez Vibration à l'étape 4 (Accès) lors de la compilation.
La méthode standard :
if ('vibrate' in navigator) navigator.vibrate(0); // or navigator.vibrate([])L'appel brut, par exemple pour arrêter un long motif d'alarme lorsque l'utilisateur appuie sur « Ignorer » :
if (window.WebToApk && window.WebToApk.vibratePattern) {
window.WebToApk.vibratePattern(JSON.stringify([1000, 500, 1000, 500, 1000]));
}
document.getElementById('dismiss').addEventListener('click', function () {
if (window.WebToApk && typeof window.WebToApk.cancelVibrate === 'function') {
window.WebToApk.cancelVibrate();
}
});Arrêtez une vibration en cours lorsque l'utilisateur quitte l'écran, pour que le téléphone ne continue pas de vibrer dans sa poche :
document.addEventListener('visibilitychange', function () {
if (!document.hidden) return;
if (window.WebToApk && typeof window.WebToApk.cancelVibrate === 'function') {
window.WebToApk.cancelVibrate();
}
});Remarques : Peut être appelé sans risque lorsque rien ne vibre.
getMusicVolume pont#
window.WebToApk.getMusicVolume(): Int
Niveau actuel de 0 à 100, ou -1 lorsque cette application ne contient pas de musique de fond.
Exemple
Lit le niveau de la musique de fond en boucle de l'application, de 0 à 100.
Renvoie : un nombre, de façon synchrone : 0-100, ou -1 quand cette application a été compilée sans fichier musical. Nécessite : un fichier choisi sous Background Music à l'étape 3 (Integrate), sous Display Options, lors de la compilation.
Afficher un curseur de musique uniquement lorsqu'il y a de la musique :
var slider = document.getElementById('music-slider');
var level = -1;
if (window.WebToApk && typeof window.WebToApk.getMusicVolume === 'function') {
level = window.WebToApk.getMusicVolume();
}
if (level < 0) {
slider.parentNode.hidden = true; // no music in this app: hide the setting
} else {
slider.value = level;
slider.addEventListener('input', function () {
window.WebToApk.setMusicVolume(parseInt(slider.value, 10));
});
}Un bouton muet qui revient au niveau propre de l'utilisateur quand on réactive le son (l'application mémorise aussi 0, gardez donc l'ancien niveau vous-même) :
function musicLevel() {
return window.WebToApk && typeof window.WebToApk.getMusicVolume === 'function'
? window.WebToApk.getMusicVolume() : -1;
}
var muteBtn = document.getElementById('mute');
function paint() {
var v = musicLevel();
muteBtn.hidden = v < 0;
muteBtn.textContent = v === 0 ? 'Unmute' : 'Mute';
}
muteBtn.addEventListener('click', function () {
var v = musicLevel();
if (v < 0) return;
if (v > 0) {
try { localStorage.setItem('musicBefore', String(v)); } catch (e) {}
window.WebToApk.setMusicVolume(0);
} else {
var back = 40;
try { back = parseInt(localStorage.getItem('musicBefore') || '40', 10); } catch (e) {}
window.WebToApk.setMusicVolume(back);
}
paint();
});
paint();Faire un fondu de la musique de son niveau actuel vers un nouveau, par exemple sous une scène de dialogue :
function fadeMusicTo(target, ms) {
if (!window.WebToApk || typeof window.WebToApk.getMusicVolume !== 'function') return;
var start = window.WebToApk.getMusicVolume();
if (start < 0 || start === target) return;
var steps = 10, i = 0;
var t = setInterval(function () {
i++;
window.WebToApk.setMusicVolume(Math.round(start + (target - start) * i / steps));
if (i === steps) clearInterval(t);
}, ms / steps);
}
fadeMusicTo(10, 800); // dim under the dialogue
// later: fadeMusicTo(60, 800); the last level set is the one kept for the next launchRemarques : Renvoie le niveau défini par le curseur de compilation ou par votre dernier appel à setMusicVolume. Lorsqu'une autre application ou un appel prend la main sur l'audio, la musique baisse ou se met en pause d'elle-même ; le nombre que vous lisez ne change pas.
getVolume pont#
window.WebToApk.getVolume(stream: String): String
Le niveau d'un flux : `{stream, current, max, percent, muted}` sous forme de chaîne JSON. stream : 'media' | 'alarm' | 'ring' | 'notification' | 'call'.
Exemple
Lit l'un des niveaux de volume propres au téléphone.
Renvoie : une chaîne JSON, de façon synchrone : {"stream":"alarm","current":5,"max":7,"percent":71,"muted":false} - current/max sont les crans propres au téléphone (ils diffèrent d'un téléphone à l'autre), percent va de 0 à 100. stream vaut 'media', 'alarm', 'ring', 'notification' ou 'call' ; tout autre nom donne {"error":"unknown_stream"}. Nécessite : rien.
function warnIfAlarmSilent() {
if (!(window.WebToApk && window.WebToApk.getVolume)) return;
const v = JSON.parse(WebToApk.getVolume('alarm'));
if (!v.error && v.percent === 0) {
showMessage('Your alarm volume is off, so the alarm will not be heard.');
}
}
warnIfAlarmSilent();Afficher tous les niveaux dans un écran de paramètres :
['media', 'alarm', 'ring', 'notification'].forEach(function (s) {
const v = JSON.parse(WebToApk.getVolume(s));
document.getElementById('vol-' + s).value = v.percent;
});Régler un volume et lire le résultat. setVolume(stream, percent, showUi) répond avec une chaîne JSON.
function setAlarmVolume(percent) {
if (!(window.WebToApk && WebToApk.setVolume)) return;
const r = JSON.parse(WebToApk.setVolume('alarm', percent, true));
if (!r.ok) showMessage('Could not change the volume: ' + r.error); // fixed_volume, muted, ...
else document.getElementById('vol-alarm').value = r.percent;
}playClick pont#
window.WebToApk.playClick()
Joue le son des touches de l'application à la demande, pour qu'une page puisse le déclencher sur ses PROPRES événements sémantiques (un appui sur un bouton) plutôt qu'à chaque toucher parasite - ce que fait réellement une application native, et la raison pour laquelle clickSoundMode peut être « off » alors que ceci fonctionne toujours. Sans effet uniquement lorsque l'application a été compilée SANS son des touches (enableClickSound désactivé). En clickSoundMode « off » - pas de son automatique à chaque toucher - un appel explicite joue quand même : ce mode existe pour les applications qui émettent un son sur leurs propres événements. Sinon, il joue le retour configuré par le créateur.
Exemple
Joue une fois le son des touches de l'application, pour que vos propres boutons puissent cliquer comme dans une application native.
Renvoie : rien. Nécessite : l'interrupteur Tap Sound à l'étape 3 (Integrate), sous Display Options, lors de la compilation (activé par défaut). Avec l'interrupteur désactivé, cela ne fait rien.
function clickSound() {
if (window.WebToApk && typeof window.WebToApk.playClick === 'function') {
window.WebToApk.playClick();
}
}
document.querySelectorAll('button, .tab').forEach(function (el) {
el.addEventListener('click', clickSound);
});Un seul écouteur pour tout un plateau de jeu, qui ne clique que sur un appui qui fait quelque chose :
document.getElementById('board').addEventListener('click', function (e) {
var cell = e.target.closest('.cell');
if (!cell || cell.classList.contains('taken')) return; // a dead tap stays silent
if (window.WebToApk && typeof window.WebToApk.playClick === 'function') {
window.WebToApk.playClick();
}
placeMark(cell);
});Donnez à vos utilisateurs leur propre interrupteur « Sons » en plus du réglage de compilation :
var toggle = document.getElementById('sounds-toggle');
var soundsOn = true;
try { soundsOn = localStorage.getItem('sounds') !== 'off'; } catch (e) {}
toggle.checked = soundsOn;
toggle.addEventListener('change', function () {
soundsOn = toggle.checked;
try { localStorage.setItem('sounds', soundsOn ? 'on' : 'off'); } catch (e) {}
});
function tapSound() {
if (soundsOn && window.WebToApk && typeof window.WebToApk.playClick === 'function') {
window.WebToApk.playClick();
}
}Remarques : Ce que vous entendez dépend du choix Son des touches :
- Suivre le réglage du téléphone (recommandé) : le clic du système. Il est silencieux si l'utilisateur a désactivé « Sons tactiles » dans les paramètres du téléphone. C'est voulu.
- Toujours jouer à chaque appui : le clic propre à l'application, toujours audible. Chaque appui sur la page produit aussi un clic, donc vous n'avez généralement pas besoin de
playClick()dans ce mode.
Appelez-le à partir d'un véritable appui sur un bouton, pas depuis un minuteur.
requestDndAccess pont#
window.WebToApk.requestDndAccess(): String
Accès Ne pas déranger, nécessaire pour changer le niveau de sonnerie / notification quand DND est actif. "granted" | "opened" (l'écran des paramètres a été ouvert) | "not_declared".
Exemple
Demande l'accès à Ne pas déranger, qu'Android exige avant qu'une application puisse modifier le volume de la sonnerie ou des notifications lorsque Ne pas déranger est activé (setVolume répond alors dnd_access_required).
Renvoie : une chaîne : 'granted' (déjà autorisé), 'opened' (l'écran système où l'utilisateur l'autorise a été ouvert - revérifiez à son retour), ou 'not_declared' (cette compilation ne contient pas l'autorisation, donc Android ne listerait pas l'application à cet endroit). Nécessite : d'appeler requestDndAccess dans le code de votre application : la compilation déclare alors ACCESS_NOTIFICATION_POLICY automatiquement.
function allowRingVolume() {
if (!(window.WebToApk && window.WebToApk.requestDndAccess)) return;
const r = WebToApk.requestDndAccess();
if (r === 'opened') showMessage('Allow Do Not Disturb access for this app, then come back.');
if (r === 'not_declared') showMessage('Turn off Do Not Disturb to change the ring volume.');
}Réessayer le changement de volume une fois que l'utilisateur a autorisé l'accès :
function setRing(percent) {
const r = JSON.parse(WebToApk.setVolume('ring', percent, true));
if (r.ok || r.error !== 'dnd_access_required') return r;
const a = WebToApk.requestDndAccess(); // 'granted' | 'opened' | 'not_declared'
if (a === 'granted') return JSON.parse(WebToApk.setVolume('ring', percent, true));
showMessage(a === 'opened' ? 'Allow access, then press the button again.' : 'Turn off Do Not Disturb first.');
return r;
}Coupez la sonnerie depuis un interrupteur « mode réunion » et expliquez pourquoi lorsque cela ne peut pas fonctionner :
function meetingMode(on) {
if (!(window.WebToApk && WebToApk.setVolume)) return;
const r = JSON.parse(WebToApk.setVolume('ring', on ? 0 : 70, false));
if (!r.ok && r.error === 'dnd_access_required') {
const a = WebToApk.requestDndAccess();
if (a === 'not_declared') showMessage('This build cannot change the ring volume while Do Not Disturb is on.');
}
}setMusicVolume pont#
window.WebToApk.setMusicVolume(percent: Int)
Règle le niveau de la musique de fond depuis la page, de 0 à 100. Le curseur de l'assistant décide du niveau au DÉMARRAGE de l'application ; ceci permet à une application de donner à ses propres utilisateurs un contrôle de la musique, que tout jeu doté d'un écran de paramètres doit avoir. Borné dans [BackgroundMusic.setVolume], de sorte qu'une page passant 500 ou -1 ne puisse pas donner à MediaPlayer un gain hors de la plage acceptée. Le niveau est MÉMORISÉ : le prochain lancement démarre à ce niveau, et non à celui de l'assistant. Sans effet lorsque l'application a été compilée sans piste - il n'y a rien à régler, et la réponse honnête est [getMusicVolume] qui renvoie -1, pour que la page puisse masquer son curseur plutôt que d'en montrer un qui ne fait rien.
Exemple
Modifie le niveau de la musique de fond en boucle de l'application, de 0 à 100, par exemple depuis l'écran des paramètres de votre jeu.
Renvoie : rien. Nécessite : un fichier choisi sous Musique de fond à l'étape 3 (Intégration), sous Options d'affichage, lors de la compilation. Sans musique, cela ne fait rien (vérifiez avec getMusicVolume() pour -1).
Un bouton muet - l'application mémorise le niveau pour le prochain lancement :
function hasMusic() {
return !!(window.WebToApk && window.WebToApk.getMusicVolume) && window.WebToApk.getMusicVolume() >= 0;
}
if (!hasMusic()) document.getElementById('mute').hidden = true;
document.getElementById('mute').addEventListener('click', function () {
if (!hasMusic()) return;
// clamped to 0..100 by the app, and kept for the next launch
window.WebToApk.setMusicVolume(window.WebToApk.getMusicVolume() > 0 ? 0 : 40);
});Boutons Désactivé / Faible / Fort dans un écran de paramètres :
var LEVELS = { off: 0, low: 25, high: 70 };
document.querySelectorAll('[data-music]').forEach(function (btn) {
btn.addEventListener('click', function () {
if (!window.WebToApk || typeof window.WebToApk.setMusicVolume !== 'function') return;
if (window.WebToApk.getMusicVolume() < 0) return; // built without music
window.WebToApk.setMusicVolume(LEVELS[btn.dataset.music]);
markSelected(btn);
});
});Baissez la musique pendant la lecture de votre propre vidéo, puis remettez-la (le niveau est mémorisé, donc restaurez-le toujours) :
var video = document.getElementById('intro-video');
var before = -1;
video.addEventListener('play', function () {
if (!window.WebToApk || typeof window.WebToApk.getMusicVolume !== 'function') return;
before = window.WebToApk.getMusicVolume();
if (before > 0) window.WebToApk.setMusicVolume(Math.round(before / 4));
});
function restoreMusic() {
if (before > 0) window.WebToApk.setMusicVolume(before);
before = -1;
}
video.addEventListener('pause', restoreMusic);
video.addEventListener('ended', restoreMusic);Remarques : Le niveau que vous définissez est enregistré : le prochain lancement démarre à ce niveau plutôt qu'à celui du curseur de compilation (jusqu'à ce que l'utilisateur efface les données de l'application). 0 rend la musique silencieuse, mais elle continue de jouer.
setVolume pont#
window.WebToApk.setVolume(stream: String, percent: Double, showUi: Boolean): String
Règle un flux à [percent] (0-100) ; [showUi] affiche le curseur de volume du téléphone. `{ok:true, stream, current, max, percent}` ou `{ok:false, error}` - error vaut unknown_stream | bad_percent | fixed_volume | dnd_access_required | muted | not_applied | failed | foreign_origin (une page hors du site propre à l'application).
Exemple
Règle l'un des niveaux de volume du téléphone, de 0 à 100 - par exemple monter le flux d'alarme pour un réveil, ou un curseur média dans une application de musique.
Renvoie : une chaîne JSON : {"ok":true,"stream":"alarm","current":6,"max":7,"percent":86}, ou {"ok":false,"error":"…"} où error vaut unknown_stream, bad_percent, fixed_volume (cet appareil n'a pas de volume réglable), dnd_access_required (Ne pas déranger est activé et bloque le niveau de la sonnerie / des notifications - voir requestDndAccess()), foreign_origin (une page extérieure au site de votre application) ou failed. showUi: true affiche le curseur de volume propre au téléphone pendant qu'il bouge. Nécessite : rien pour le média, l'alarme et les appels ; la sonnerie et les notifications peuvent nécessiter l'accès à Ne pas déranger lorsque ce mode est activé.
function setAlarmLoud() {
if (!(window.WebToApk && window.WebToApk.setVolume)) return;
const r = JSON.parse(WebToApk.setVolume('alarm', 80, true));
if (!r.ok) showMessage('Could not change the alarm volume: ' + r.error);
}
document.getElementById('ring-slider').oninput = function (e) {
const r = JSON.parse(WebToApk.setVolume('ring', Number(e.target.value), false));
if (r.error === 'dnd_access_required' && WebToApk.requestDndAccess() === 'not_declared') {
showMessage('Turn off Do Not Disturb to change the ring volume.');
}
};Lire un niveau, puis régler un curseur média :
if (window.WebToApk && WebToApk.setVolume) {
const now = JSON.parse(WebToApk.getVolume('media')); // {stream, current, max, percent, muted}
slider.value = now.percent;
slider.oninput = () => {
const r = JSON.parse(WebToApk.setVolume('media', Number(slider.value), false));
if (r.ok) label.textContent = r.percent + '%';
else if (r.error === 'fixed_volume') slider.disabled = true; // this phone has no adjustable volume
};
}Afficher le niveau actuel de la sonnerie et réagir quand il change :
if (window.WebToApk && WebToApk.getVolume) {
const ring = JSON.parse(WebToApk.getVolume('ring')); // {stream, current, max, percent, muted}
document.getElementById('ring-slider').value = ring.percent;
WebToApk.watchVolume(true);
window.addEventListener('appmint:volume', (e) => {
if (e.detail.stream === 'ring') document.getElementById('ring-slider').value = e.detail.percent;
});
}Remarques : la valeur est arrondie au cran le plus proche du téléphone, et la réponse indique le niveau réellement appliqué. Le flux d'appel ne descend jamais sous son minimum (généralement 1).
vibrate pont#
window.WebToApk.vibrate(durationMs: Long)
Retour haptique simple pour la page (navigator.vibrate et une forme à motif). Les deux sont ignorés sauf si la compilation a activé l'autorisation Vibration.
Décrit par son groupe, Vibration, plutôt que seul.
Exemple
Fait vibrer le téléphone une fois pendant le nombre de millisecondes indiqué. La plupart des pages utilisent navigator.vibrate(ms) standard, qui appelle cette méthode pour vous.
Renvoie : rien. Nécessite : activez Vibration à l'étape 4 (Accès) lors de la compilation. Sans cela, l'appel ne fait rien.
La méthode standard (fonctionne de la même façon dans un navigateur) :
if ('vibrate' in navigator) navigator.vibrate(50);L'appel brut :
document.getElementById('like').addEventListener('click', function () {
if (window.WebToApk && typeof window.WebToApk.vibrate === 'function') {
window.WebToApk.vibrate(40); // 40 ms
}
});
// 0 (or any value <= 0) stops a running vibration
if (window.WebToApk && window.WebToApk.vibrate) window.WebToApk.vibrate(0);Un minuscule tic à chaque fois qu'un curseur passe à un nouveau cran, comme un sélecteur natif :
var slider = document.getElementById('size');
var last = slider.value;
slider.addEventListener('input', function () {
if (slider.value === last) return; // same step, no tick
last = slider.value;
if (window.WebToApk && typeof window.WebToApk.vibrate === 'function') {
window.WebToApk.vibrate(10); // 10 ms: a light tick
}
});Une vibration plus longue lorsqu'un formulaire ne peut pas être envoyé, pour que l'utilisateur ressente l'erreur :
document.getElementById('signup').addEventListener('submit', function (e) {
if (this.checkValidity()) return;
e.preventDefault();
if (window.WebToApk && typeof window.WebToApk.vibrate === 'function') {
window.WebToApk.vibrate(250);
}
this.reportValidity();
});Remarques : Passez un nombre entier. L'intensité est celle par défaut du téléphone ; pour des vibrations plus fortes ou plus faibles, utilisez Capacitor.Plugins.Haptics.impact ou Capacitor.Plugins.AppwrightHaptics.play. Pour un motif vibration-pause-vibration, utilisez vibratePattern.
vibratePattern pont#
window.WebToApk.vibratePattern(patternJson: String)
Fait vibrer selon un motif marche/arrêt, par ex. "[100,50,100]" = vibre 100 ms, pause 50, vibre 100. Sert de base à navigator.vibrate(array) ; préférez l'API standard. Sans effet sauf si le créateur a activé l'autorisation Vibrate.
Exemple
Fait vibrer selon un motif marche/arrêt, donné sous forme de chaîne JSON. La plupart des pages utilisent navigator.vibrate([...]) standard, qui appelle cette méthode pour vous.
Renvoie : rien. Nécessite : activez Vibration à l'étape 4 (Accès) lors de la compilation. Sans cela, l'appel ne fait rien.
La méthode standard :
if ('vibrate' in navigator) navigator.vibrate([100, 50, 100]); // buzz, pause, buzzL'appel brut prend le même motif de style web sous forme de chaîne JSON:
function pattern(list) {
if (window.WebToApk && typeof window.WebToApk.vibratePattern === 'function') {
window.WebToApk.vibratePattern(JSON.stringify(list));
}
}
pattern([200]); // one 200 ms buzz
pattern([100, 50, 100, 50, 300]); // short, short, long
pattern([]); // empty list stops a running vibrationLe motif ne joue qu'une fois, donc une alarme le répète elle-même jusqu'à ce que l'utilisateur l'arrête :
var alarm = null;
var ALARM = JSON.stringify([500, 300, 500, 300, 500]); // about 2.1 s
function startAlarm() {
if (!window.WebToApk || typeof window.WebToApk.vibratePattern !== 'function') return;
window.WebToApk.vibratePattern(ALARM);
alarm = setInterval(function () { window.WebToApk.vibratePattern(ALARM); }, 3000);
}
function stopAlarm() {
if (alarm === null) return;
clearInterval(alarm);
alarm = null;
window.WebToApk.vibratePattern('[]'); // stop the buzz that is still running
}Remarques : Le premier nombre est une vibration, puis pause, vibration, pause… (ordre du web). L'application ajoute pour vous l'« attente » initiale d'Android, donc ne mettez pas de 0 en premier : [0, 100] signifie « vibrer 0 ms, pause de 100 ms » et vous ne sentez rien. Les nombres négatifs comptent pour 0. Le motif n'est joué qu'une fois.
watchVolume pont#
window.WebToApk.watchVolume(on: Boolean): Boolean
Active (true) ou désactive (false) les événements `appmint:volume`.
Exemple
Active ou désactive les événements de changement de volume en direct : lorsqu'ils sont activés, chaque changement d'un niveau de volume (touches physiques, curseur système, autre application) parvient à la page sous forme de appmint:volume.
Renvoie : true quand le changement a pris effet. Nécessite : rien.
if (window.WebToApk && window.WebToApk.watchVolume) {
window.addEventListener('appmint:volume', function (e) {
// e.detail = { stream: 'media', current: 9, max: 15, percent: 60, muted: false }
document.getElementById('vol-' + e.detail.stream).value = e.detail.percent;
});
WebToApk.watchVolume(true);
window.addEventListener('pagehide', function () { WebToApk.watchVolume(false); });
}Le même objet est aussi accessible via un hook de page, si vous préférez :
window.onAppMintVolume = function (level) {
if (level.stream === 'alarm' && level.percent === 0) showMessage('Alarm volume is now off.');
};
WebToApk.watchVolume(true);Afficher le niveau une fois avec getVolume, puis le garder à jour uniquement tant que l'écran est visible :
if (window.WebToApk && WebToApk.watchVolume && WebToApk.getVolume) {
const meter = document.getElementById('media-meter');
meter.value = JSON.parse(WebToApk.getVolume('media')).percent;
const onVol = function (e) { if (e.detail.stream === 'media') meter.value = e.detail.percent; };
document.addEventListener('visibilitychange', function () {
if (document.hidden) { WebToApk.watchVolume(false); window.removeEventListener('appmint:volume', onVol); }
else { window.addEventListener('appmint:volume', onVol); WebToApk.watchVolume(true); }
});
}Remarques : un événement par flux modifié (media, alarm, ring, notification, call). Désactivez-le lorsque l'écran qui affiche les niveaux se ferme.