Créer un APK gratuit

API du pont JavaScript

Plugins Capacitor

Les plugins Capacitor hébergés par l'application. Une page écrite à la main y accède via window.Capacitor.Plugins.<Name> ; une application créée par IA utilise le wrapper @/lib/appmintNative nommé dans chaque exemple.

Capacitor.ActionSheet Capacitor#

Capacitor.Plugins.ActionSheet — showActions({ title, message, options })

Exemple

Affiche une feuille native en bas de l'écran avec une liste de choix et indique lequel a été touché (@capacitor/action-sheet 8.1.1).

Retourne : Promise { index, canceled } - index est l'option touchée ; quand la feuille est fermée, canceled vaut true et index est hors de la liste (-1). Nécessite : rien à activer - chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

Chaque option est { title, style? } avec style 'DEFAULT', 'DESTRUCTIVE' ou 'CANCEL'.

var ActionSheet = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.ActionSheet;

async function photoMenu() {
  if (!ActionSheet) return;
  var opts = [
    { title: 'Share', style: 'DEFAULT' },
    { title: 'Edit', style: 'DEFAULT' },
    { title: 'Delete', style: 'DESTRUCTIVE' }
  ];
  var r = await ActionSheet.showActions({ title: 'Photo', message: 'Choose an action', options: opts });
  if (r.canceled || r.index < 0 || r.index >= opts.length) return;   // dismissed
  if (opts[r.index].title === 'Delete') deletePhoto();
}

Dans une application créée par IA, le wrapper au format Capacitor retourne { index: -1 } à la fermeture ; la forme courte actionSheet() retourne null:

import { ActionSheet, actionSheet } from '@/lib/appmintNative';

const { index } = await ActionSheet.showActions({
  title: 'Photo',
  options: [{ title: 'Share' }, { title: 'Delete', destructive: true }],
});
if (index === 1) deletePhoto();

const i = await actionSheet('Sort by', [{ title: 'Name' }, { title: 'Date' }]);   // number | null

Confirmation de suppression qui fonctionne aussi dans un navigateur ordinaire :

async function confirmDelete(name) {
  const AS = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.ActionSheet;
  if (!AS) return window.confirm('Delete ' + name + '?');
  const r = await AS.showActions({
    title: 'Delete ' + name + '?',
    options: [{ title: 'Delete', style: 'DESTRUCTIVE' }, { title: 'Keep it', style: 'CANCEL' }]
  });
  return !r.canceled && r.index === 0;
}

Remarques : Vérifiez toujours les bornes de l'index - ne traitez jamais un index comme un vrai choix. La forme d'option du wrapper est { title, destructive? } ; il associe destructive au style 'DESTRUCTIVE' du plugin.

Capacitor.App Capacitor#

Capacitor.Plugins.App — getInfo(), getState(), exitApp(), minimizeApp(), addListener(...)

Exemple

Identité et cycle de vie de l'application : nom, identifiant du package, version, si l'application est au premier plan, et événements de pause/reprise (@capacitor/app 8.1.0).

Retourne : getInfo() → { name, id, build, version } ; getState() → { isActive } ; getLaunchUrl() → { url } ou rien ; getAppLanguage() → { value } ; exitApp() / minimizeApp() → void. addListener() → une Promise d'un handle avec remove(), comme dans l'API propre à Capacitor : utilisez await ou chaînez .then() ; la valeur retournée a aussi remove() elle-même. Nécessite : rien à activer : chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines), jamais sur les autres sites que l'application ouvre. Détectez la disponibilité.

var App = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.App;
if (App) {
  App.getInfo().then(function (i) {
    document.getElementById('about').textContent = i.name + ' ' + i.version + ' (' + i.build + ')';
  });
}

Pause et reprise - enregistrer un brouillon quand l'utilisateur part, actualiser quand il revient :

if (App) {
  App.addListener('appStateChange', function (s) {
    if (!s.isActive) saveDraft();      // went to the background
    else refreshInbox();               // back in front
  });
  App.addListener('pause', function () { console.log('paused'); });
  App.addListener('resume', function () { console.log('resumed'); });
}

Dans une application créée par IA :

import { App } from '@/lib/appmintNative';

const info = await App.getInfo();   // { name, id, build, version }
App.exitApp();                      // closes the app on Android

Remarques : L'événement backButton ne se déclenche jamais : l'enveloppe garde le bouton retour (le plugin s'exécute avec disableBackButtonHandler). Gérez le retour avec AppMint.setBackHandler(fn) ou le wrapper onBackGesture. Pour les liens profonds, utilisez WebToApk.getLaunchUrl() / l'événement appmint:deep-link (ou launchUrl() / onDeepLink() dans les applications créées par IA). minimizeApp() est réservé à Android. Ne faites jamais d'un bouton Quitter le seul moyen d'avancer.

Capacitor.AppLauncher Capacitor#

Capacitor.Plugins.AppLauncher — canOpenUrl({ url }), openUrl({ url })

Exemple

Ouvre une autre application par lien (whatsapp://send?text=…, tel:, geo:, un lien https) et demande si l'une peut le gérer (@capacitor/app-launcher 8.0.1).

Retourne : canOpenUrl() → Promise { value: boolean }. openUrl() → Promise { completed: boolean } (false quand aucune application n'a pris le lien). Nécessite : rien à activer - chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var AL = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppLauncher;

async function chatOnWhatsApp(text) {
  if (!AL) return;
  var url = 'whatsapp://send?text=' + encodeURIComponent(text);
  var can = await AL.canOpenUrl({ url: url });
  if (!can.value) { alert('WhatsApp is not installed'); return; }
  var r = await AL.openUrl({ url: url });
  if (!r.completed) alert('Could not open WhatsApp');
}

Dans une application créée par IA :

import { appLauncher } from '@/lib/appmintNative';

if (await appLauncher.canOpen('tel:+15551234567')) await appLauncher.open('tel:+15551234567');

Ouvrez un lien de carte sans demander d'abord :

async function openMap(query) {
  const AL = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppLauncher;
  if (!AL) { window.open('https://maps.google.com/?q=' + encodeURIComponent(query)); return; }
  const r = await AL.openUrl({ url: 'geo:0,0?q=' + encodeURIComponent(query) });
  if (!r.completed) alert('No maps app could open this');
}

Remarques : Sur Android 11+, une application ne peut « voir » que les autres applications qu'elle déclare. Les applications générées déclarent les liens https, geo, google.navigation, tel, mailto, sms, whatsapp, intent et upi, donc canOpenUrl répond false pour les autres schémas (par exemple spotify:) même quand l'application est installée. openUrl fonctionne quand même pour eux - appelez-la et vérifiez completed. Sur Android, canOpenUrl accepte aussi un nom de package ('com.whatsapp'), avec la même limite de visibilité.

Capacitor.AppUpdate Capacitor#

Capacitor.Plugins.AppUpdate — getAppUpdateInfo(), performImmediateUpdate(), startFlexibleUpdate(), completeFlexibleUpdate(), openAppStore()

Exemple

Vérifie sur Google Play si une version plus récente de l'application existe et lance la mise à jour intégrée de Play. Intégré @capawesome/capacitor-app-update (template/plugins/app-update).

Retourne : getAppUpdateInfo() → { currentVersionName, currentVersionCode, availableVersionCode, updateAvailability, updatePriority, immediateUpdateAllowed, flexibleUpdateAllowed, clientVersionStalenessDays?, installStatus } (les codes de version sont des chaînes ; updateAvailability 2 = une mise à jour est disponible). performImmediateUpdate() / startFlexibleUpdate() → { code } : 0 OK, 1 annulé, 2 échec, 3 non disponible, 4 non autorisé, 5 appelez d'abord getAppUpdateInfo(). openAppStore() → void. Nécessite : rien à activer ; l'application doit être installée depuis Google Play. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var AU = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppUpdate;

async function checkForUpdate() {
  if (!AU) return;
  try {
    var info = await AU.getAppUpdateInfo();          // must come first
    if (info.updateAvailability !== 2) return;       // up to date
    if (info.immediateUpdateAllowed) {
      var r = await AU.performImmediateUpdate();     // Play's full-screen update
      if (r.code === 1) console.log('user said not now');
    } else {
      await AU.openAppStore();                       // the Play listing
    }
  } catch (e) {
    console.log('Play update check failed:', e.message);  // e.g. no Play services
  }
}

Mise à jour flexible - télécharger en arrière-plan, puis redémarrer quand l'utilisateur est d'accord :

async function flexibleUpdate() {
  if (!AU) return;
  var info = await AU.getAppUpdateInfo();
  if (info.updateAvailability !== 2 || !info.flexibleUpdateAllowed) return;
  await AU.addListener('onFlexibleUpdateStateChange', function (s) {
    if (s.installStatus === 2) console.log(s.bytesDownloaded + ' / ' + s.totalBytesToDownload);
    if (s.installStatus === 11) showRestartButton();   // 11 = DOWNLOADED
  });
  await AU.startFlexibleUpdate();
}
function restartNow() { if (AU) AU.completeFlexibleUpdate(); }

Dans une application créée par IA :

import { appUpdate } from '@/lib/appmintNative';

const info = await appUpdate.check();          // null on the web / without Play
if (info?.inPlace) await appUpdate.start();    // Android: immediate update

Remarques : Utilisez updateAvailability === 2 comme seul test de « mise à jour disponible ». La méthode check() du wrapper compare currentVersionName avec availableVersionCode, qui ne sont jamais égaux sur Android ; son updateAvailable n'y est donc pas fiable - testez plutôt inPlace. start() se résout avec true même quand l'utilisateur annule.

Capacitor.AppwrightDocScanner Capacitor#

Capacitor.Plugins.AppwrightDocScanner — scan({ pageLimit, pdf, quality }), isSupported()

Exemple

Ouvre le scanner de documents Google ML Kit : l'utilisateur photographie une ou plusieurs pages (ou les importe), les bords sont détectés et redressés, et les pages reviennent sous forme d'images JPEG. Plugin propre à Appwright (AppwrightDocScannerPlugin.kt).

Retourne : scan() → Promise qui est toujours RÉSOLUE : { ok: true, pages: string[] (JPEG data URLs), pdfDataUrl?, pdfPath?, pdfError? } en cas de succès, { ok: false, cancelled: true } quand l'utilisateur revient en arrière, { ok: false, error } quand le scanner ne peut pas démarrer. isSupported() → { value: boolean } (Google Play services présent). Nécessite : rien à activer et aucune autorisation de caméra (le scanner s'exécute dans Play services, qui télécharge son modèle à la première utilisation).

var Scanner = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppwrightDocScanner;

async function scanReceipt() {
  if (!Scanner) { alert('Scanning is not available here'); return; }
  var s = await Scanner.isSupported();
  if (!s.value) { alert('This phone has no Google Play services'); return; }
  var r = await Scanner.scan({ pageLimit: 1, pdf: false, quality: 0.8 });
  if (r.cancelled) return;
  if (!r.ok) { alert('Scanner error: ' + r.error); return; }
  document.getElementById('preview').src = r.pages[0];
}

pageLimit 0 = aucune limite. quality va de 0,1 à 1 pour le JPEG. Avec pdf: true, le scanner écrit aussi un PDF : pdfDataUrl est ce PDF sous forme d'URL data:application/pdf;base64,… que la page peut télécharger, envoyer ou afficher, et pdfPath est sa copie dans le dossier de cache de l'application. Si le PDF n'a pas pu être lu, les pages sont quand même retournées et pdfError en donne la raison.

Dans une application créée par IA (null en cas d'annulation, d'erreur, ou sur le web) :

import { docScanner, can } from '@/lib/appmintNative';

if (can('docScanner') !== 'none') {
  const res = await docScanner.scan({ pageLimit: 5, pdf: true });
  if (res) setPages(res.pages);          // res.pdfPath when pdf: true
}

Scanner plusieurs pages et proposer le PDF :

async function scanContract() {
  const Scanner = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppwrightDocScanner;
  if (!Scanner) return;
  const r = await Scanner.scan({ pageLimit: 0, pdf: true, quality: 0.9 });
  if (!r.ok) { if (!r.cancelled) alert('Scanner error: ' + r.error); return; }
  if (r.pdfDataUrl) {
    const a = document.createElement('a');
    a.href = r.pdfDataUrl; a.download = 'contract.pdf'; a.click();
  } else if (r.pdfError) console.warn('PDF not made:', r.pdfError);
  console.log(r.pages.length + ' pages scanned');
}

Remarques : Les pages sont des URL de données complètes et peuvent être volumineuses - réduisez-les avant d'en enregistrer beaucoup dans localStorage. Utilisez pdfDataUrl, pas pdfPath - un chemin de fichier de l'appareil n'est pas une URL que la page peut charger. Une page illisible est ignorée ; les autres sont quand même retournées.

Capacitor.AppwrightGallery Capacitor#

Capacitor.Plugins.AppwrightGallery — save({ source, fileName, album, kind })

Exemple

Enregistre une photo ou une vidéo dans la galerie du téléphone (Pictures/<album> ou Movies/<album>). Plugin propre à l'enveloppe de l'application (AppwrightGalleryPlugin.kt).

Retourne : Promise de { uri } de l'élément enregistré. Rejette avec un code : bad-source, download-failed, permission-denied (Android 7-9, stockage refusé) ou failed. Nécessite : rien à activer ; aucune autorisation sur Android 10+ (Android 7-9 demande le stockage la première fois).

const Gallery = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppwrightGallery;

async function saveCard(canvas) {
  const dataUrl = canvas.toDataURL('image/png');
  if (!Gallery) { const a = document.createElement('a'); a.href = dataUrl; a.download = 'card.png'; a.click(); return; }
  try {
    await Gallery.save({ source: dataUrl, fileName: 'birthday-card.png', album: 'Cards' });
    toast('Saved to your gallery');
  } catch (e) {
    toast('Could not save: ' + e.message);
  }
}

Enregistrer une vidéo de votre serveur dans son propre album, avec un message pour chaque code d'échec :

const Gallery = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppwrightGallery;

async function saveClip(url) {
  if (!Gallery) { window.open(url, '_blank'); return; }
  try {
    await Gallery.save({ source: url, fileName: 'highlight.mp4', album: 'Highlights', kind: 'video' });
    toast('Video saved to Movies/Highlights');
  } catch (e) {
    if (e.code === 'download-failed') toast('Could not download the video. Check your connection.');
    else if (e.code === 'permission-denied') toast('Allow storage access to save videos.');
    else toast('Could not save: ' + e.message);
  }
}

Enregistrer une photo modifiée par l'utilisateur sous forme de Blob (par exemple issue de canvas.toBlob) en la transformant d'abord en URL data: :

const Gallery = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppwrightGallery;

function blobToDataUrl(blob) {
  return new Promise((resolve, reject) => {
    const r = new FileReader();
    r.onload = () => resolve(r.result);
    r.onerror = () => reject(r.error);
    r.readAsDataURL(blob);
  });
}

async function saveEditedPhoto(canvas) {
  if (!Gallery) return;
  const blob = await new Promise((res) => canvas.toBlob(res, 'image/jpeg', 0.92));
  const { uri } = await Gallery.save({ source: await blobToDataUrl(blob), fileName: 'edit-' + Date.now() + '.jpg', album: 'My Edits' });
  console.log('saved as', uri);
}

Remarques : source est une URL data:, une URL http(s) ou une URI content:///file:// ; kind ('image'/'video') est déduit du type MIME quand il est omis. Les applications créées par IA utilisent saveToGallery() de @/lib/appmintNative.

Capacitor.AppwrightHaptics Capacitor#

Capacitor.Plugins.AppwrightHaptics

Exemple

Le plugin propre à AppMint pour des motifs de vibration riches : une liste de temps, chacun avec son propre début, sa durée et son intensité.

Retourne : play({ events }) se résout avec { ok: true } ou { ok: false, error } ('unsupported' = pas de vibreur, 'empty' = aucun événement, ou le message du système). Il ne rejette jamais. isSupported() se résout avec { value: true/false }. Nécessite : rien à activer - chaque application déclare l'autorisation de vibration, que Vibration soit coché ou non à l'étape 4 (Accès). window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

Chaque événement est { at, duration, intensity, sharpness } : at = début en ms, duration = durée en ms (moins de 20 devient un tapotement de 30 ms), intensity = 0-1 (0,8 par défaut). sharpness est accepté mais ignoré sur Android.

var AH = window.Capacitor && window.Capacitor.Plugins ? window.Capacitor.Plugins.AppwrightHaptics : null;

async function heartbeat() {
  if (!AH) return false;
  var r = await AH.play({
    events: [
      { at: 0,   intensity: 0.8 },
      { at: 140, intensity: 0.5 },
      { at: 700, intensity: 0.8 },
      { at: 840, intensity: 0.5 }
    ]
  });
  if (!r.ok) console.log('pattern not played:', r.error);
  return r.ok;
}

document.getElementById('like').addEventListener('click', heartbeat);

Masquer le bouton sur les téléphones sans vibreur :

(async function () {
  var btn = document.getElementById('feel-it');
  var ok = false;
  if (AH) { try { ok = (await AH.isSupported()).value; } catch (e) {} }
  btn.hidden = !ok;
})();

Jouer un double tapotement rapide après une action réussie, et signaler quand il ne peut pas être joué :

async function successBuzz() {
  const AH = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppwrightHaptics;
  if (!AH) return;
  const r = await AH.play({ events: [{ at: 0, duration: 40, intensity: 1 }, { at: 120, duration: 40, intensity: 0.6 }] });
  if (!r.ok && r.error === 'unsupported') console.log('this phone has no vibrator');
}

Remarques : L'intensité ne fonctionne que sur les téléphones avec contrôle de l'amplitude ; les autres gardent le rythme à une intensité fixe. Si le système refuse la vibration, play répond { ok: false, error: '<the system message>' }. Dans les applications créées par IA, utilisez hapticPlay de @/lib/appmintNative, qui propose aussi des motifs nommés.

Capacitor.AppwrightLiveProgress Capacitor#

Capacitor.Plugins.AppwrightLiveProgress — start / update / end

Exemple

Le plugin Android propre à AppMint (son nom JS est AppwrightLiveProgress) pour une notification d'état persistante, silencieuse et mise à jour en direct (barre de progression, indicateur de chargement ou chronomètre) qui ouvre une route au toucher.

Retourne : start(opts) / update(opts) → Promise<{ ok: true, id }>, ou { ok: false, error } sans rien publier - 'permission' quand les notifications ne sont pas autorisées (Android 13+ : pas encore accordé, ou désactivé pour l'application), 'channel_disabled' quand l'utilisateur a désactivé la catégorie « Live status » ; end({ id }) → Promise<void>. Nécessite : l'application Android et l'autorisation de notification (Android 13+). Non disponible sur le web.

Dans une application créée par IA, utilisez le wrapper liveProgress de @/lib/appmintNative:

import { liveProgress } from '@/lib/appmintNative';
await liveProgress.start({ id: 'order', title: 'Order #42', text: 'Being prepared', indeterminate: true });
await liveProgress.update({ id: 'order', title: 'Order #42', text: 'On the way', progress: 0.6, route: '/orders/42' });
await liveProgress.end('order');

Dans une page écrite à la main :

async function showDelivery(step, total) {
  const P = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppwrightLiveProgress;
  if (!P) return;                                   // not in the Android app
  if (window.Notification && Notification.permission !== 'granted') {
    if (await Notification.requestPermission() !== 'granted') return;
  }
  const r = await P.update({
    id: 'delivery',
    title: 'Your delivery',
    text: 'Stop ' + step + ' of ' + total,
    progress: step / total,                         // 0–1; or indeterminate: true
    route: '/track'                                 // opened when the card is tapped
  });
  if (!r.ok) console.warn('live card not posted:', r.error);
}

async function deliveryDone() {
  const P = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppwrightLiveProgress;
  if (P) await P.end({ id: 'delivery' });
}

Un minuteur d'entraînement : startedAt fait compter la carte toute seule ; elle est donc publiée une fois et terminée à l'arrêt de l'entraînement :

const Live = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppwrightLiveProgress;
let workoutStart = 0;

async function startWorkout(name) {
  workoutStart = Date.now();
  if (!Live) return;
  const r = await Live.start({ id: 'workout', title: name, text: 'Workout in progress', startedAt: workoutStart, route: '/workout' });
  if (!r.ok && r.error === 'channel_disabled') {
    showHint('Turn on "Live status" in this app\'s notification settings to see the timer.');
  }
}

async function stopWorkout() {
  if (Live) await Live.end({ id: 'workout' });
  saveWorkout({ durationMs: Date.now() - workoutStart });
}

Options : id (par défaut 'live'), title, text, progress (0-1, à omettre pour aucune barre), indeterminate, startedAt (epoch ms, affiche un chronomètre qui tourne), route.

Remarques : start et update font la même chose (publier ou remplacer la carte portant cet identifiant). La carte ne peut pas être balayée - appelez toujours end. Demandez d'abord l'autorisation : sur Android 13+, sans elle, start répond error: 'permission' et ne publie rien.

Capacitor.AppwrightSystemPalette Capacitor#

Capacitor.Plugins.AppwrightSystemPalette — get()

Exemple

Retourne les couleurs Material You du téléphone (la palette qu'Android 12+ construit à partir du fond d'écran), pour que l'application s'accorde aux applications système. Plugin propre à AppMint (AppwrightSystemPalettePlugin.kt).

Retourne : Promise { available: false } avant Android 12, sinon { available: true, accent1, accent2, accent3, neutral1, neutral2 } - chacun un objet de ton vers couleur hexadécimale, avec les tons '0', '10', '50', '100' … '900', '1000' (par ex. accent1['600'] === '#3F5F90'). Nécessite : rien à activer - chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var Palette = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppwrightSystemPalette;

async function useWallpaperColours() {
  if (!Palette) return;
  var p = await Palette.get();
  if (!p.available) return;                 // keep the app's own colours
  var root = document.documentElement.style;
  root.setProperty('--accent', p.accent1['600']);
  root.setProperty('--surface', p.neutral1['50']);
}
useWallpaperColours();

Dans une application créée par IA :

import { systemPalette } from '@/lib/appmintNative';

const p = await systemPalette();
if (p.available && p.accent1) document.documentElement.style.setProperty('--accent', p.accent1['600']);

Choisir des tons clairs ou sombres pour s'accorder au thème du système, et relire la palette quand l'utilisateur revient après avoir changé de fond d'écran :

var Palette = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppwrightSystemPalette;
var darkQuery = window.matchMedia('(prefers-color-scheme: dark)');

async function applyPalette() {
  if (!Palette) return;
  var p = await Palette.get();
  if (!p.available) return;
  var dark = darkQuery.matches;
  var s = document.documentElement.style;
  s.setProperty('--accent', p.accent1[dark ? '200' : '600']);
  s.setProperty('--on-accent', p.accent1[dark ? '800' : '0']);
  s.setProperty('--bg', p.neutral1[dark ? '900' : '10']);
  s.setProperty('--text', p.neutral1[dark ? '100' : '900']);
}

darkQuery.addEventListener('change', applyPalette);
document.addEventListener('visibilitychange', function () {
  if (document.visibilityState === 'visible') applyPalette();
});
applyPalette();

Remarques : Vérifiez le contraste du texte avant d'appliquer les couleurs de la palette - une teinte du fond d'écran n'est pas garantie d'être lisible sur votre arrière-plan. Les navigateurs n'exposent aucune couleur de fond d'écran : sur le web, le wrapper répond { available: false }. Les couleurs changent quand l'utilisateur change de fond d'écran ; rappelez get() à la reprise.

Capacitor.AppwrightWidget Capacitor#

Capacitor.Plugins.AppwrightWidget — set(card), clear(), placedCount(), requestPin()

Exemple

Alimente le widget de l'écran d'accueil de l'application : une carte avec un titre, une grande valeur, jusqu'à douze lignes, vos couleurs et une route au toucher - la même carte que prend AppMint.widget.set(), toutes les clés comprises. La carte est enregistrée sur le téléphone et affichée même après un redémarrage. Plugin propre à AppMint (AppwrightWidgetPlugin.kt).

Retourne : set({ title?, value?, caption?, lines?, route?, bg?, ink?, accent?, textSize?, align?, wrap?, … }) → Promise { ok: true, placed }, rejetée avec la raison pour une carte invalide (placed = widgets actuellement sur l'écran d'accueil). clear() → void. placedCount() → { value }. requestPin() → { value: boolean } (true quand la feuille « ajouter un widget » du lanceur a été ouverte). Nécessite : rien à activer - chaque application déclare le widget. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var Widget = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.AppwrightWidget;

async function updateWidget(tasks) {
  if (!Widget) return;
  await Widget.set({
    title: 'Today',
    value: tasks.length + ' tasks',
    lines: tasks.slice(0, 6).map(function (t) { return t.title; }),
    route: '/today',                 // opened when the widget is tapped
    bg: '#0B0F1A', ink: '#FFFFFF', accent: '#22D3EE'
  });
}

Proposer de le placer (seulement quand aucun n'est encore placé) :

async function offerWidget() {
  if (!Widget) return;
  var n = (await Widget.placedCount()).value;
  if (n > 0) return;
  var r = await Widget.requestPin();
  if (!r.value) alert('Long-press the home screen, tap Widgets and pick this app.');
}

Dans une application créée par IA :

import { widget } from '@/lib/appmintNative';

await widget.set({ title: 'Today', value: '3 tasks', lines: ['Gym', 'Call mum'], route: '/today' });
if ((await widget.placedCount()) === 0) await widget.requestPin();

Remarques : Les couleurs sont #RRGGBB, #AARRGGBB (alpha d'abord) ou rgba() ; celles laissées vides utilisent une carte sombre avec une valeur cyan. Voir AppMint.widget pour les lignes stylées, caption, textSize, align, wrap et font (votre propre fichier .ttf/.otf, indiqué par un chemin dans votre application). Le toucher ouvre l'application sur route comme lien profond (lisez-le avec WebToApk.getLaunchUrl() ou l'événement appmint:deep-link). Avant tout set(), le widget affiche « Nothing to show yet » ; clear() le remet dans cet état. Dans un navigateur, can('widget') vaut 'none'.

Capacitor.Badge Capacitor#

Capacitor.Plugins.Badge — the launcher-icon count

Exemple

Le plugin Badge (capawesome) qui définit le nombre affiché sur l'icône de l'application dans le lanceur.

Retourne : Promises : set({ count }), clear(), increase(), decrease() → void ; get() → { count } ; isSupported() → { isSupported }. Le plugin Android n'a pas de méthodes d'autorisation. Nécessite : rien sur Android. Non disponible sur le web.

Dans une application créée par IA, utilisez le wrapper badge de @/lib/appmintNative:

import { badge } from '@/lib/appmintNative';
await badge.set(3);
await badge.clear();

Dans une page écrite à la main :

async function setUnread(count) {
  const B = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Badge;
  if (!B) return false;                       // not inside the app
  try {
    const s = await B.isSupported();
    if (!s.isSupported) return false;         // this launcher shows no badges
    if (count > 0) await B.set({ count: count });
    else await B.clear();
    return true;
  } catch (e) {
    return false;
  }
}

window.addEventListener('appmint:push', function () {
  const inbox = JSON.parse(window.WebToApk ? WebToApk.getPushInbox() : '[]');
  setUnread(inbox.filter(function (m) { return !m.read; }).length);
});

Compter et décompter à mesure que des éléments arrivent et sont lus :

const B = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Badge;
async function onNewMessage() { if (B) await B.increase(); }
async function onMessageRead() { if (B) await B.decrease(); }
async function showCurrent() {
  if (!B) return;
  const { count } = await B.get();
  console.log('badge shows', count);
}

Remarques : sur Android, l'apparence dépend du lanceur (un nombre, un point, ou rien). navigator.setAppBadge(n) dans l'application écrit dans le même badge (il n'existe que sur les lanceurs capables d'afficher un compteur).

Capacitor.BarcodeScanner Capacitor#

Capacitor.Plugins.BarcodeScanner — scan, startScan, readBarcodesFromImage, isSupported

Exemple

Scan de code QR et de code-barres avec l'API @capacitor-mlkit/barcode-scanning - le plugin propre à l'enveloppe de l'application (BarcodeScannerPlugin.kt) au-dessus du même scanner de codes Google que AppMint.scanCode(). Les anciens appels @capacitor-community/barcode-scanner (startScan() qui retourne { hasContent, content }, checkPermission, prepare, hideBackground) partagent ce nom et fonctionnent aussi.

Retourne : scan({ formats?, autoZoom? }) → { barcodes: [{ rawValue, displayValue, format, valueType, bytes?, cornerPoints?, urlBookmark?, wifi?, email?, phone?, sms?, geoPoint?, contactInfo?, calendarEvent?, driverLicense? }] } (rejette "scan canceled." quand l'utilisateur revient en arrière) ; readBarcodesFromImage({ path, formats? }) → { barcodes } ; isSupported() → { supported } ; isGoogleBarcodeScannerModuleAvailable() → { available } ; installGoogleBarcodeScannerModule() (progression via googleBarcodeScannerModuleInstallProgress) ; checkPermissions() / requestPermissions() → { camera } ; openSettings(). format vaut 'QR_CODE', 'EAN_13', 'CODE_128'… Nécessite : rien à activer et aucune autorisation de caméra - le scanner de Google affiche son propre écran (Play services le télécharge à la première utilisation). window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

const Scanner = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.BarcodeScanner;

scanBtn.onclick = async () => {
  if (!Scanner) return;
  try {
    const { barcodes } = await Scanner.scan({ formats: ['QR_CODE'] });
    const code = barcodes[0];
    if (code.valueType === 'URL') location.href = code.urlBookmark.url;
    else resultBox.textContent = code.displayValue;
  } catch (e) {
    if (e.message !== 'scan canceled.') alert(e.message);
  }
};

Recherche de prix à partir d'un code-barres de produit, avec le style à écouteur (startScan + barcodesScanned) que les applications ML Kit utilisent déjà :

const Scanner = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.BarcodeScanner;

async function scanProduct() {
  const listener = await Scanner.addListener('barcodesScanned', async ({ barcodes }) => {
    await listener.remove();
    await Scanner.stopScan();
    const ean = barcodes[0].rawValue;
    const res = await fetch('https://api.example.com/products/' + encodeURIComponent(ean));
    priceBox.textContent = res.ok ? (await res.json()).price : 'Not found';
  });
  await Scanner.startScan({ formats: ['EAN_13', 'EAN_8', 'UPC_A', 'UPC_E'] });
}

Lire un code QR à partir d'une photo que l'utilisateur a déjà :

const Scanner = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.BarcodeScanner;
const Camera = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Camera;

async function qrFromGallery() {
  const photo = await Camera.getPhoto({ source: 'PHOTOS', resultType: 'uri', quality: 90 });
  const { barcodes } = await Scanner.readBarcodesFromImage({ path: photo.path, formats: ['QR_CODE'] });
  return barcodes.length ? barcodes[0].rawValue : null;
}

Remarques : Le startScan() d'origine affiche un aperçu caméra en direct derrière une page transparente et continue d'analyser jusqu'à stopScan() ; ici il ouvre l'écran du scanner, le premier code déclenche barcodeScanned / barcodesScanned, et la session se termine (l'appel se résout alors { hasContent, content, format } pour le code communautaire ; un scanner fermé se résout { hasContent: false }). La torche et le zoom appartiennent à cet aperçu, donc isTorchAvailable() vaut false et les réglages de torche/zoom sont rejetés : l'écran du scanner a son propre bouton de lampe de poche. checkPermissions() répond granted quand l'application n'a aucune autorisation de caméra (le scanner n'en a pas besoin) ; une application qui utilise aussi la caméra obtient son vrai état. Les applications créées par IA utilisent scanCode() depuis @/lib/appmintNative.

Capacitor.Browser Capacitor#

Capacitor.Plugins.Browser — open({ url, toolbarColor }), close(), addListener('browserFinished')

Exemple

Ouvre une page web dans un onglet de navigateur intégré (Chrome Custom Tabs), afin que l'utilisateur lise des conditions, une documentation ou une page de connexion et revienne d'un seul geste (@capacitor/browser 8.0.3).

Retourne : open() / close() → Promise void. Événements : browserFinished (l'utilisateur a fermé l'onglet) et browserPageLoaded. Nécessite : rien - chaque application héberge le plugin (un navigateur compatible Custom Tabs, comme Chrome, doit être installé). window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var Browser = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Browser;

async function openTerms() {
  if (!Browser) return;
  var h = await Browser.addListener('browserFinished', function () {
    console.log('user closed the terms');
    h.remove();
  });
  await Browser.open({ url: 'https://example.com/terms', toolbarColor: '#0B0F1A' });
}

Dans une application créée par IA (un nouvel onglet sur le web) :

import { browser } from '@/lib/appmintNative';

const off = browser.onClosed(() => refreshAccount());
await browser.open('https://example.com/terms', { toolbarColor: '#0B0F1A' });
// call off() when you no longer care

Ouvrir un lien, et fermer l'onglet quand un retour de connexion atteint la page :

var Browser = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Browser;

async function openHelp() {
  if (!Browser) { window.open('https://example.com/help', '_blank'); return; }
  try {
    await Browser.open({ url: 'https://example.com/help' });
  } catch (e) {
    alert('Could not open the page: ' + e.message);
  }
}

window.addEventListener('appmint:deep-link', function () {
  if (Browser) Browser.close().catch(function () {});
});

Remarques : url ne doit pas être vide. toolbarColor est une couleur hexadécimale ; une couleur invalide est ignorée. close() fonctionne aussi sur Android dans cette version du plugin (il termine l'activité hôte de l'onglet) - utile après qu'un lien de connexion revient dans l'application. L'onglet est un navigateur séparé : il ne partage pas les cookies de l'application ni localStorage.

Capacitor.Calendar Capacitor#

Capacitor.Plugins.Calendar — createEvent, findEvents, deleteEvent, listCalendars, openCalendar

Exemple

Ajoute, recherche et supprime des événements dans l'agenda du téléphone (Android CalendarContract), et ouvre l'application agenda à une date. Intégré @capacitor/calendar (template/plugins/calendar).

Retourne : createEvent() → { id } ; findEvents() → { events: [{ id, title, location?, notes?, startDate, endDate, isAllDay, calendarId, calendarName?, attendees? }] } ; listCalendars() → { calendars: [{ id, name, displayName?, isPrimary }] } ; deleteEvent(), openCalendar() → void. Les dates sont en millisecondes epoch. Nécessite : cochez Agenda à l'étape 4 (Accès) lors de la compilation. Pour les applications HTML, ZIP et créées par IA, le build ajoute aussi l'autorisation d'agenda de lui-même quand vos fichiers contiennent un appel Calendar.<method>( écrit exactement ainsi (comme ci-dessous) ou le calendar.createEvent( du wrapper. Le plugin demande à l'utilisateur l'accès à l'agenda à la première utilisation. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var Calendar = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Calendar;

async function addDentist() {
  if (!Calendar) return;
  var start = new Date('2026-10-02T10:00:00').getTime();
  try {
    var r = await Calendar.createEvent({
      title: 'Dentist', startDate: start, endDate: start + 60 * 60 * 1000,
      location: 'Main St 5', notes: 'Bring the card', isAllDay: false,
      firstReminderMinutes: 30
    });
    console.log('event id', r.id);
  } catch (e) {
    // e.code: OS-PLUG-CLDR-0020 permission denied, -0001 bad arguments
    alert('Could not add the event: ' + e.message);
  }
}

Lire cette semaine, en supprimer un, ouvrir l'agenda :

async function thisWeek() {
  if (!Calendar) return;
  var now = Date.now();
  var found = await Calendar.findEvents({ startDate: now, endDate: now + 7 * 864e5 });
  found.events.forEach(function (ev) { console.log(ev.title, new Date(ev.startDate)); });
  if (found.events.length) await Calendar.deleteEvent({ id: found.events[0].id });
  await Calendar.openCalendar({ date: now });
}

Dans une application créée par IA (sur le web, createEvent télécharge un fichier .ics ; la lecture retourne []):

import { calendar } from '@/lib/appmintNative';

if ((await calendar.requestPermission()) === 'granted') {
  const id = await calendar.createEvent({ title: 'Dentist', start: new Date('2026-10-02T10:00'), end: new Date('2026-10-02T11:00') });
  const week = await calendar.listEvents({ from: Date.now(), to: Date.now() + 7 * 864e5 });
  if (id) await calendar.deleteEvent(id);
  await calendar.openCalendar(new Date());
}

Remarques : Sans l'autorisation d'agenda dans l'application, aucune boîte de dialogue n'apparaît et chaque appel d'événement est rejeté (autorisation manquante) ; un utilisateur qui refuse obtient OS-PLUG-CLDR-0020. recurrence: { frequency: 'daily' | 'weekly' | 'monthly' | 'yearly', interval?, count?, endDate? } crée un événement récurrent. createEventInteractively({ title, startDate, endDate }) ouvre à la place l'éditeur propre à l'application agenda : il se résout avec { id } de l'événement enregistré, et rejette OS-PLUG-CLDR-0006 quand l'utilisateur ferme l'éditeur sans enregistrer (il faut l'accès en lecture et en écriture pour distinguer les deux). deleteEvent({ id, fromDate }) termine un événement récurrent avant fromDate et conserve les occurrences précédentes. Le wrapper retourne null / [] / false au lieu de lever une erreur.

Capacitor.Camera Capacitor#

Capacitor.Plugins.Camera

Exemple

Le plugin officiel Capacitor Camera, intégré à l'application : prendre une photo avec l'appareil photo ou choisir des photos dans la galerie.

Retourne : des Promises. getPhoto(opts) → { dataUrl | base64String | webPath, format, saved } (le champ dépend de resultType), et est REJETÉE quand l'utilisateur annule ; pickImages(opts) → { photos: [{ webPath, format }] } ; checkPermissions() / requestPermissions({ permissions }) → { camera, photos }. Nécessite : cochez Caméra à l'étape 4 (Accès). Pour les applications HTML, ZIP et créées par IA, le build ajoute aussi l'autorisation de caméra de lui-même quand vos fichiers contiennent Camera.getPhoto( écrit exactement ainsi (comme ci-dessous), getUserMedia avec vidéo, ou <input capture>. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

Prenez une photo et affichez-la.

async function takePhoto() {
  var Camera = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Camera;
  if (!Camera) { showMessage('Open the app to use the camera.'); return; }
  try {
    var perm = await Camera.requestPermissions({ permissions: ['camera'] });
    if (perm.camera !== 'granted') { showMessage('Camera permission was refused.'); return; }

    var photo = await Camera.getPhoto({
      source: 'CAMERA',          // 'CAMERA' | 'PHOTOS' | 'PROMPT'
      resultType: 'dataUrl',     // 'dataUrl' | 'base64' | 'uri'
      quality: 80,
      direction: 'REAR',         // 'REAR' | 'FRONT'
      correctOrientation: true,
      saveToGallery: false
    });
    document.getElementById('photo').src = photo.dataUrl;
  } catch (err) {
    // The user closed the camera (or no camera app). Nothing to do.
  }
}

Choisir jusqu'à 5 photos dans la galerie.

async function choosePhotos() {
  var Camera = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Camera;
  if (!Camera) return;
  try {
    var result = await Camera.pickImages({ quality: 80, limit: 5 });
    result.photos.forEach(function (p) {
      var img = document.createElement('img');
      img.src = p.webPath;       // a URL the page can load
      document.getElementById('gallery').appendChild(img);
    });
  } catch (err) { /* cancelled */ }
}

Dans une application créée par IA, utilisez le wrapper, qui fonctionne aussi sur le web (et retourne null au lieu de lever une erreur en cas d'annulation) :

import { camera } from '@/lib/appmintNative';
const photo = await camera.take({ source: 'camera' });

Remarques : pickImages ne demande aucune autorisation de caméra. Si l'autorisation de caméra n'est pas dans l'application (la case était décochée et le build n'a trouvé aucun appel à la caméra), elle est refusée sans demande. Un <input type="file" accept="image/*" capture> ouvre aussi la caméra. La caméra est sensible : déclarez-la dans votre formulaire Play Sécurité des données.

Capacitor.CapacitorBarcodeScanner Capacitor#

Capacitor.Plugins.CapacitorBarcodeScanner — scanBarcode({ hint })

Exemple

Scan de code QR / code-barres en un appel avec l'API officielle @capacitor/barcode-scanner - le plugin propre à l'enveloppe de l'application (CapacitorBarcodeScannerPlugin.kt) au-dessus du même scanner de codes Google que AppMint.scanCode(). Le code écrit pour le paquet npm (CapacitorBarcodeScanner.scanBarcode({ hint: CapacitorBarcodeScannerTypeHint.ALL })) fonctionne sans changement.

Retourne : scanBarcode({ hint, scanInstructions?, cameraDirection?, scanOrientation? }) → { ScanResult, format }. hint / format sont les nombres du package : 0 QR_CODE, 1 AZTEC, 2 CODABAR, 3 CODE_39, 4 CODE_93, 5 CODE_128, 6 DATA_MATRIX, 8 ITF, 9 EAN_13, 10 EAN_8, 11 PDF_417, 14 UPC_A, 15 UPC_E, 17 ALL. Rejette avec le code OS-PLUG-BARC-0006 quand l'utilisateur ferme le scanner. Nécessite : rien à activer et aucune autorisation de caméra - le scanner de Google affiche son propre écran (Play services le télécharge à la première utilisation). window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

const Scanner = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.CapacitorBarcodeScanner;

ticketBtn.onclick = async () => {
  if (!Scanner) return;
  try {
    const { ScanResult } = await Scanner.scanBarcode({ hint: 0 });   // QR codes only
    const ok = await fetch('/api/tickets/check?code=' + encodeURIComponent(ScanResult)).then((r) => r.ok);
    statusBox.textContent = ok ? 'Valid ticket' : 'Unknown ticket';
  } catch (e) {
    if (e.code !== 'OS-PLUG-BARC-0006') alert(e.message);
  }
};

Accepter n'importe quel code, et indiquer à l'utilisateur de quel type il s'agissait :

const Scanner = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.CapacitorBarcodeScanner;
const NAMES = { 0: 'QR code', 5: 'Code 128', 9: 'EAN-13', 10: 'EAN-8', 14: 'UPC-A', 15: 'UPC-E' };

async function scanAnything() {
  const { ScanResult, format } = await Scanner.scanBarcode({ hint: 17 });
  return (NAMES[format] || 'Barcode') + ': ' + ScanResult;
}

Gérer un rejet qui ne correspond pas à la fermeture du scanner par l'utilisateur :

const Scanner = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.CapacitorBarcodeScanner;

async function scanProduct() {
  if (!Scanner) { alert('Scanning works only inside the app'); return null; }
  try {
    const { ScanResult } = await Scanner.scanBarcode({ hint: 9 });   // EAN-13
    return ScanResult;
  } catch (e) {
    if (e.code === 'OS-PLUG-BARC-0006') return null;                 // user closed the scanner
    alert('Scan failed: ' + e.message);
    return null;
  }
}

Remarques : scanInstructions, scanButton, cameraDirection et scanOrientation servent à styliser l'écran de caméra du projet d'origine et n'ont aucun effet sur le scanner de Google (toujours la caméra arrière). MAXICODE, RSS_14, RSS_EXPANDED et UPC_EAN_EXTENSION ne sont pas pris en charge comme hint (rejette OS-PLUG-BARC-0008) ; 17 (ALL) scanne tous les types pris en charge. Les applications créées par IA utilisent scanCode() de @/lib/appmintNative.

Capacitor.CapacitorCookies Capacitor#

Capacitor.Plugins.CapacitorCookies — getCookies / setCookie / deleteCookie / clearCookies / clearAllCookies

Exemple

Lit et écrit les cookies de l'application, y compris ceux d'un autre hôte avec lequel votre page communique (le noyau de Capacitor CapacitorCookies).

Retourne : getCookies({ url? }) → { [name]: value } : avec une url, les cookies que cette URL (hôte et chemin) enverrait ; sans elle, le document.cookie propre à la page. Elle rejette une url qui n'est pas http(s). setCookie({ key, value, url?, path?, expires? }), deleteCookie({ key, url? }), clearCookies({ url? }), clearAllCookies() → Promise void ; setCookie / deleteCookie sont rejetées sans une key de type chaîne (et value) et n'écrivent alors rien. Nécessite : rien à activer : chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines), jamais sur les autres sites que l'application ouvre. Détectez la disponibilité.

var Cookies = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.CapacitorCookies;

// Read the session cookie your API host set — not the page's own cookies.
async function apiSession() {
  if (!Cookies) return null;          // not inside the app
  var jar = await Cookies.getCookies({ url: 'https://api.example.com/' });
  return jar.session || null;
}

// Remember a choice for the API host, for 30 days, on one path only.
async function rememberRegion(region) {
  if (!Cookies) return;
  var expires = new Date(Date.now() + 30 * 864e5).toUTCString();
  await Cookies.setCookie({ url: 'https://api.example.com', path: '/v2', key: 'region', value: region, expires: expires });
}

Se déconnecter : supprimer les cookies de cet hôte, ou tous les cookies que l'application détient.

async function signOut(everything) {
  if (!Cookies) return;
  if (everything) await Cookies.clearAllCookies();
  else await Cookies.clearCookies({ url: 'https://api.example.com' });
}

Remarques : Un cookie défini avec un path n'est renvoyé que pour une url sous ce chemin. Les valeurs sont décodées (URL) à la lecture. Les cookies sont partagés par toutes les pages que l'application affiche ; ne gardez donc jamais de secrets dans un cookie qu'une page étrangère pourrait lire - ils ont leur place dans Preferences ou le stockage sécurisé de l'application.

Capacitor.CapacitorSQLite Capacitor#

Capacitor.Plugins.CapacitorSQLite — createConnection, open, execute, query, run, executeSet, close

Exemple

Une vraie base de données SQLite sur le téléphone, avec l'API @capacitor-community/sqlite. @capacitor-community/sqlite intégré (template/plugins/sqlite), s'exécutant sur le SQLite d'Android. Le code écrit pour le paquet npm (new SQLiteConnection(CapacitorSQLite)) fonctionne sans changement ; une page écrite à la main appelle directement l'objet plugin, comme ci-dessous.

Retourne : createConnection({ database, version, encrypted: false, mode: 'no-encryption', readonly: false }), open({ database }), close({ database }), closeConnection({ database }) → void ; execute({ database, statements }) → { changes: { changes } } ; run({ database, statement, values }) → { changes: { changes, lastId } } ; query({ database, statement, values }) → { values: [rows] } ; executeSet({ database, set: [{ statement, values }] }) → { changes } ; isDBExists({ database }) / isDBOpen({ database }) → { result } ; beginTransaction, commitTransaction, rollbackTransaction, isTransactionActive({ database }) ; deleteDatabase({ database }) ; exportToJson / importFromJson pour les sauvegardes. Nécessite : rien à activer et aucune autorisation. La base de données vit dans le stockage privé de l'application et survit aux mises à jour. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

const DB = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.CapacitorSQLite;
const database = 'notes';

async function openNotes() {
  if (!DB) return false;
  await DB.createConnection({ database, version: 1, encrypted: false, mode: 'no-encryption', readonly: false });
  await DB.open({ database, readonly: false });
  await DB.execute({ database, statements:
    'CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY AUTOINCREMENT, text TEXT NOT NULL, at INTEGER);' });
  return true;
}

async function addNote(text) {
  const r = await DB.run({ database, statement: 'INSERT INTO notes (text, at) VALUES (?, ?);', values: [text, Date.now()] });
  return r.changes.lastId;
}

async function listNotes() {
  const r = await DB.query({ database, statement: 'SELECT id, text, at FROM notes ORDER BY at DESC;', values: [] });
  return r.values || [];
}

Plusieurs écritures qui doivent toutes aboutir ou aucune - une seule transaction avec executeSet:

const DB = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.CapacitorSQLite;

async function moveMoney(database, fromId, toId, amount) {
  await DB.executeSet({ database, transaction: true, set: [
    { statement: 'UPDATE accounts SET balance = balance - ? WHERE id = ?;', values: [amount, fromId] },
    { statement: 'UPDATE accounts SET balance = balance + ? WHERE id = ?;', values: [amount, toId] },
    { statement: 'INSERT INTO ledger (from_id, to_id, amount, at) VALUES (?, ?, ?, ?);', values: [fromId, toId, amount, Date.now()] },
  ] });
}

Ouvrir la base de données une seule fois par démarrage de l'application, même quand deux écrans la demandent en même temps :

const DB = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.CapacitorSQLite;
let ready = null;

function db(database) {
  if (!ready) ready = (async () => {
    try {
      await DB.createConnection({ database, version: 1, encrypted: false, mode: 'no-encryption', readonly: false });
    } catch (e) {
      if (!/already exists/i.test(e.message)) throw e;   // a page reload keeps the native connection
    }
    if (!(await DB.isDBOpen({ database, readonly: false })).result) await DB.open({ database, readonly: false });
    return database;
  })();
  return ready;
}

Remarques : L'application est compilée sans SQLCipher, donc les bases de données ne sont pas chiffrées : encrypted: true, setEncryptionSecret, changeEncryptionSecret, isSecretStored et les autres appels de chiffrement sont rejetés avec « Encryption is not available in this app ». isInConfigEncryption() répond false. Tout le reste (requêtes, valeurs liées, transactions, mises à niveau versionnées avec addUpgradeStatement, import/export JSON) est le code propre du plugin. Les rejets contiennent le texte d'erreur de SQLite.

Capacitor.Clipboard Capacitor#

Capacitor.Plugins.Clipboard — write(options), read()

Exemple

Copie du texte (ou un lien) dans le presse-papiers du système et le relit (@capacitor/clipboard 8.0.1).

Retourne : write({ string?, url?, image?, label? }) → Promise void. read() → Promise { value, type } (type vaut 'text/plain' pour du texte). Nécessite : rien à activer : chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines), jamais sur les autres sites que l'application ouvre. Détectez la disponibilité.

async function copyCode(code) {
  var Clipboard = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Clipboard;
  if (!Clipboard) { alert('Copy is not available here'); return; }
  await Clipboard.write({ string: code, label: 'Invite code' });
}

async function pasteCode(input) {
  var Clipboard = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Clipboard;
  if (!Clipboard) return;
  try {
    var r = await Clipboard.read();
    input.value = r.value;
  } catch (e) {
    // An EMPTY clipboard is a rejection: "There is no data on the clipboard".
    if (/no data/i.test(e.message)) input.value = '';
    else alert('Could not read the clipboard: ' + e.message);
  }
}

Dans une application créée par IA, le wrapper au format Capacitor transforme un presse-papiers vide en '':

import { Clipboard } from '@/lib/appmintNative';

await Clipboard.write({ string: 'ABC-123' });
const { value } = await Clipboard.read();   // '' when the clipboard is empty

Copier un lien et le confirmer par un retour haptique :

async function copyLink(url) {
  var P = window.Capacitor && window.Capacitor.Plugins;
  if (!P || !P.Clipboard) { alert('Copy is not available here'); return; }
  await P.Clipboard.write({ url: url });
  if (P.Haptics) P.Haptics.impact({ style: 'LIGHT' });
  copiedToast.hidden = false;
}

Remarques : write a besoin de l'un de string, url ou image (une URL de données), sinon il rejette « No data provided ». Android 12+ affiche sa propre notification « collé depuis… » à la lecture - c'est le système, pas l'application. Le write du wrapper envoie seulement string || url.

Capacitor.Contacts Capacitor#

Capacitor.Plugins.Contacts — getContacts, getContact, pickContact, createContact, deleteContact

Exemple

Le carnet d'adresses du téléphone avec l'API @capacitor-community/contacts. @capacitor-community/contacts intégré (template/plugins/contacts). Le code écrit pour le paquet npm fonctionne sans changement.

Retourne : checkPermissions() / requestPermissions() → { contacts, contactsWrite } (chaque 'granted' | 'denied' | 'prompt' ; contacts correspond à la lecture, contactsWrite à l'ajout et à la suppression) ; getContacts({ projection }) → { contacts: [ContactPayload] } ; getContact({ contactId, projection }) et pickContact({ projection }) → { contact } ; createContact({ contact }) → { contactId } ; deleteContact({ contactId }) → void. projection choisit les champs : { name, phones, emails, organization, birthday, note, urls, postalAddresses, image } (chaque true). Nécessite : cochez Contacts à l'étape 4 (Accès) pour lire, et aussi Modifier les contacts pour ajouter ou supprimer. Les builds HTML, ZIP et AI-Studio les cochent d'eux-mêmes quand le code appelle Contacts.getContacts( / getContact( / pickContact( (lecture) ou Contacts.createContact( / deleteContact( (les deux). Le plugin demande l'autorisation à l'utilisateur à la première utilisation ; sans la case cochée, l'appel est rejeté avec « Permission is required to access contacts. » - et dans une application où ni Contacts, ni SMS, ni Journal d'appels ne sont cochés, le plugin n'est pas du tout dans l'application (Capacitor rejette avec « not implemented »). window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

const Contacts = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Contacts;

async function friendsWithPhones() {
  if (!Contacts) return [];
  const { contacts } = await Contacts.requestPermissions();
  if (contacts !== 'granted') return [];
  const res = await Contacts.getContacts({ projection: { name: true, phones: true } });
  return res.contacts
    .filter((c) => c.phones && c.phones.length)
    .map((c) => ({ id: c.contactId, name: (c.name && c.name.display) || '', phone: c.phones[0].number }));
}

Laissez l'utilisateur choisir une personne dans le sélecteur du système :

const Contacts = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Contacts;

inviteBtn.onclick = async () => {
  if (!Contacts) return;
  try {
    const { contact } = await Contacts.pickContact({ projection: { name: true, phones: true, emails: true } });
    inviteField.value = (contact.emails && contact.emails[0] && contact.emails[0].address) || '';
  } catch (e) {
    // The user closed the picker, or refused access.
  }
};

Enregistrer une carte de visite de l'application dans le carnet d'adresses :

const Contacts = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Contacts;

async function saveCard(card) {
  const perm = await Contacts.requestPermissions();
  if (perm.contactsWrite !== 'granted') return null;
  const { contactId } = await Contacts.createContact({ contact: {
    name: { given: card.first, family: card.last },
    organization: { company: card.company, jobTitle: card.title },
    phones: [{ type: 'work', label: 'work', number: card.phone }],
    emails: [{ type: 'work', label: 'work', address: card.email }],
  } });
  return contactId;
}

Remarques : pickContact() est rejetée avec le code CANCELLED quand l'utilisateur quitte le sélecteur. Android ne remplit contactId, name, phones, emails, organization, birthday, note, urls, postalAddresses et image que si la projection les demande : ne demandez que ce que vous affichez. Lire les contacts est une autorisation sensible sur Google Play : expliquez pourquoi dans le formulaire de sécurité des données de la fiche. Les applications créées par IA utilisent listContacts(), pickContact() et addContact() depuis @/lib/appmintNative.

Capacitor.Device Capacitor#

Capacitor.Plugins.Device

Exemple

Le plugin officiel Capacitor Device, intégré à l'application : modèle du téléphone, version du système, batterie, un identifiant stable et la langue.

Retourne : des Promises. getInfo() → { model, platform, operatingSystem, osVersion, androidSDKVersion, manufacturer, isVirtual, webViewVersion, … } ; getId() → { identifier } ; getBatteryInfo() → { batteryLevel (0–1), isCharging } ; getLanguageCode() → { value }. Nécessite : rien à activer. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

Afficher le téléphone et la batterie.

async function showDevice() {
  var cap = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Device;
  if (!cap) { document.getElementById('out').textContent = navigator.userAgent; return; }
  try {
    var info = await cap.getInfo();
    var battery = await cap.getBatteryInfo();
    document.getElementById('out').textContent =
      info.manufacturer + ' ' + info.model + ' - ' + info.operatingSystem + ' ' + info.osVersion +
      ' - battery ' + Math.round(battery.batteryLevel * 100) + '%' + (battery.isCharging ? ' (charging)' : '');
  } catch (err) {
    document.getElementById('out').textContent = 'Could not read device info';
  }
}

Un identifiant stable et la langue.

async function helloServer() {
  var cap = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Device;
  if (!cap) return;
  var id = (await cap.getId()).identifier;
  var lang = (await cap.getLanguageCode()).value;     // e.g. "en"
  await fetch('https://api.example.com/hello?lang=' + encodeURIComponent(lang), {
    method: 'POST', body: JSON.stringify({ device: id })
  });
}

Dans une application créée par IA, utilisez le wrapper, qui fonctionne aussi sur le web :

import { Device } from '@/lib/appmintNative';
const info = await Device.getInfo();

Remarques : Pour l'identifiant de build Android, le correctif de sécurité, l'écran, la mémoire et le réseau, le WebToApk.getDeviceInfo() de l'enveloppe donne plus de détails. Les identifiants du plugin ne sont pas des identifiants matériels ; ils peuvent changer après une réinitialisation d'usine.

Capacitor.Dialog Capacitor#

Capacitor.Plugins.Dialog — alert, confirm, prompt

Exemple

Affiche une vraie boîte de dialogue système Android : un message, une question oui/non, ou une question à réponse texte d'une ligne (@capacitor/dialog 8.0.1).

Retourne : alert({ title?, message, buttonTitle? }) → Promise void. confirm({ title?, message, okButtonTitle?, cancelButtonTitle? }) → { value: boolean }. prompt({ title?, message, okButtonTitle?, cancelButtonTitle?, inputPlaceholder?, inputText? }) → { value: string, cancelled: boolean }. Nécessite : rien à activer - chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var Dialog = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Dialog;

async function deleteNote(id) {
  if (!Dialog) return;
  var r = await Dialog.confirm({
    title: 'Delete note?',
    message: 'This cannot be undone.',
    okButtonTitle: 'Delete',
    cancelButtonTitle: 'Keep'
  });
  if (r.value) removeNote(id);
}

Alerte et saisie :

async function renameFlow() {
  if (!Dialog) return;
  await Dialog.alert({ title: 'Saved', message: 'Your changes are stored.', buttonTitle: 'OK' });

  var p = await Dialog.prompt({ title: 'Rename', message: 'New name', inputText: 'Groceries', inputPlaceholder: 'List name' });
  if (!p.cancelled && p.value.trim()) renameList(p.value.trim());
}

Dans une application créée par IA, le wrapper ne rejette jamais : la fermeture donne { value: false } / { cancelled: true }, et sur le web il utilise les boîtes de dialogue propres du navigateur :

import { Dialog } from '@/lib/appmintNative';

const { value } = await Dialog.confirm({ title: 'Delete note?', message: 'This cannot be undone.' });
if (value) removeNote(id);

Remarques : message est obligatoire - sans lui, le plugin rejette « Please provide a message for the dialog ». Les boîtes de dialogue sont modales ; n'en utilisez que pour les décisions qui doivent bloquer.

Capacitor.Filesystem Capacitor#

Capacitor.Plugins.Filesystem

Exemple

Le plugin Capacitor Filesystem standard : lire et écrire des fichiers dans le stockage PROPRE de l'application (pas un dossier choisi par l'utilisateur - pour cela, utilisez WebToApkFS).

Retourne : chaque méthode retourne une Promise et rejette en cas d'échec (par exemple la lecture d'un fichier inexistant). readFile → { data }, writeFile → { uri }, readdir → { files: [{ name, type, size, mtime, uri }] }, mkdir / deleteFile → rien. Nécessite : rien à activer ; 'DATA' et 'CACHE' ne demandent aucune autorisation.

Une page n'a pas d'imports Directory / Encoding, passez donc les chaînes simples 'DATA' (fichiers privés de l'application, conservés jusqu'à la désinstallation) ou 'CACHE' (le système peut le vider), et 'utf8' pour le texte :

async function saveAndReadBack() {
  var Fs = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Filesystem;
  if (!Fs) { console.log('Filesystem plugin not available (not inside the app)'); return; }

  try {
    await Fs.mkdir({ path: 'notes', directory: 'DATA', recursive: true });
    await Fs.writeFile({ path: 'notes/today.txt', data: 'Hello', directory: 'DATA', encoding: 'utf8', recursive: true });

    var r = await Fs.readFile({ path: 'notes/today.txt', directory: 'DATA', encoding: 'utf8' });
    console.log('text:', r.data);

    var dir = await Fs.readdir({ path: 'notes', directory: 'DATA' });
    dir.files.forEach(function (f) { console.log(f.type, f.name, f.size); });   // type: 'file' | 'directory'

    await Fs.deleteFile({ path: 'notes/today.txt', directory: 'DATA' });
  } catch (e) {
    console.log('File error:', e.message);   // e.g. the file does not exist
  }
}

Omettez encoding pour écrire ou lire des données binaires en base64 :

var Fs = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Filesystem;
var base64Data = btoa('raw bytes here');   // any base64 string, e.g. from a canvas or FileReader
if (Fs) {
  Fs.writeFile({ path: 'blobs/data.bin', data: base64Data, directory: 'CACHE', recursive: true })
    .then(function (w) { console.log('written to', w.uri); })
    .catch(function (e) { console.log('write failed:', e.message); });
}

Dans les applications créées par IA, le wrapper @/lib/appmintNative qui utilise ce plugin est fileTransfer (il prépare les téléchargements et les envois dans 'CACHE'):

import { fileTransfer } from '@/lib/appmintNative';

const r = await fileTransfer.download('https://example.com/report.pdf', 'report.pdf', {
  onProgress: (p) => console.log(Math.round(p.fraction * 100) + '%'),
});
if (r.path) console.log('saved in the app at', r.path);   // on the web the browser saves it instead

Remarques : window.Capacitor n'existe que dans l'application : détectez toujours la disponibilité. Les fichiers dans 'DATA' sont privés à l'application et supprimés à la désinstallation ; pour placer des fichiers là où l'utilisateur peut les voir, utilisez WebToApkFS (un dossier que l'utilisateur autorise) ou un téléchargement.

Capacitor.FileTransfer Capacitor#

Capacitor.Plugins.FileTransfer

Exemple

Le plugin officiel Capacitor File Transfer : télécharge une URL vers un fichier sur le téléphone, ou envoie un fichier du téléphone, de façon native, avec des événements de progression.

Retourne : downloadFile({url, path, headers?, progress?}) → Promise<{path}> ; uploadFile({url, path, fileKey?, mimeType?, method?, headers?, progress?}) → Promise<{bytesSent, responseCode, response, headers}>. La progression arrive via les événements d'écouteur 'progress' {type, url, bytes, contentLength, lengthComputable}. Les échecs sont rejetés avec {message, code}. Nécessite : rien à activer. window.Capacitor existe sur les pages que l'application sert elle-même et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites. Détectez toujours la fonctionnalité.

Télécharger dans le cache de l'application avec progression :

async function download(url, name, onPct) {
  const P = window.Capacitor && window.Capacitor.Plugins;
  if (!P || !P.FileTransfer || !P.Filesystem) return null;          // not in the app
  const target = await P.Filesystem.getUri({ path: name, directory: 'CACHE' });
  const listener = await P.FileTransfer.addListener('progress', function (p) {
    if (p.url === url && p.lengthComputable) onPct(Math.round(p.bytes / p.contentLength * 100));
  });
  try {
    const r = await P.FileTransfer.downloadFile({ url: url, path: target.uri, progress: true });
    return r.path;
  } catch (e) {
    alert('Download failed: ' + e.message);
    return null;
  } finally {
    listener.remove();
  }
}

Envoyer un fichier qui se trouve déjà sur le téléphone :

const P = window.Capacitor && window.Capacitor.Plugins;
if (P && P.FileTransfer) {
  P.FileTransfer.uploadFile({
    url: 'https://example.com/api/upload', path: localFileUri,
    fileKey: 'file', mimeType: 'image/jpeg', headers: { Authorization: 'Bearer ' + token }
  }).then(function (r) { console.log('server said', r.responseCode, r.response); })
    .catch(function (e) { alert('Upload failed: ' + e.message); });
}

Signaler un transfert échoué grâce à son code :

async function safeDownload(url, target) {
  const P = window.Capacitor && window.Capacitor.Plugins;
  if (!P || !P.FileTransfer) { alert('Downloads need the app'); return null; }
  try {
    const r = await P.FileTransfer.downloadFile({ url: url, path: target });
    return r.path;
  } catch (e) {
    console.log('transfer failed', e.code, e.message);
    alert('Could not download the file.');
    return null;
  }
}

Remarques : Le chemin doit être un chemin de fichier ou une URI file://, pas un Blob - écrivez d'abord un Blob dans le cache avec Filesystem.writeFile. Sur Android 10 et antérieur, un chemin dans le stockage public demande l'autorisation de stockage. Dans les applications créées par IA, préférez fileTransfer de @/lib/appmintNative, qui fait tout cela et fonctionne aussi sur le web.

Capacitor.FileViewer Capacitor#

Capacitor.Plugins.FileViewer

Exemple

Le plugin officiel Capacitor File Viewer : ouvre un document ou un fichier multimédia dans l'application de visualisation du téléphone, à partir d'une adresse web, d'un chemin de fichier local ou d'un fichier intégré à l'application.

Retourne : chaque méthode retourne une Promise<void> qui est rejetée avec {message, code} quand rien ne peut ouvrir le fichier. Nécessite : rien à activer. window.Capacitor existe sur les pages que l'application sert elle-même et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites. Détectez toujours la fonctionnalité.

async function openPdf(url) {
  const FV = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.FileViewer;
  if (!FV) { window.open(url, '_blank'); return; }          // a normal browser: open a tab
  try {
    await FV.openDocumentFromUrl({ url: url });
  } catch (e) {
    alert('No app on this phone can open this file.');
  }
}

Un fichier sur le téléphone, par exemple un fichier écrit avec Capacitor.Plugins.Filesystem:

async function openSaved(name) {
  const P = window.Capacitor && window.Capacitor.Plugins;
  if (!P || !P.FileViewer || !P.Filesystem) return;
  const f = await P.Filesystem.getUri({ path: name, directory: 'CACHE' });
  try {
    await P.FileViewer.openDocumentFromLocalPath({ path: f.uri.replace(/^file:\/\//, '') });
  } catch (e) {
    alert('Cannot open ' + name + ': ' + e.message);
  }
}

openDocumentFromResources({path}) ouvre un fichier intégré au dossier assets de l'APK. Les trois mêmes méthodes existent aussi sous les noms previewMediaContentFromUrl, previewMediaContentFromLocalPath et previewMediaContentFromResources pour la vidéo et l'audio.

Télécharger un fichier et l'ouvrir à son arrivée :

async function downloadAndOpen(url, name) {
  const P = window.Capacitor && window.Capacitor.Plugins;
  if (!P || !P.FileTransfer || !P.Filesystem || !P.FileViewer) return;
  const f = await P.Filesystem.getUri({ path: name, directory: 'CACHE' });
  const r = await P.FileTransfer.downloadFile({ url: url, path: f.uri });
  await P.FileViewer.openDocumentFromLocalPath({ path: r.path.replace(/^file:\/\//, '') });
}

Remarques : Dans les applications créées par IA, préférez fileViewer.open(target) de @/lib/appmintNative, qui choisit la bonne méthode et fonctionne aussi sur le web. Un chemin local est un chemin simple (sans file://).

Capacitor.Geolocation Capacitor#

Capacitor.Plugins.Geolocation

Exemple

Le plugin officiel Capacitor Geolocation, intégré à l'application : la position du téléphone une fois, ou des mises à jour continues.

Retourne : des Promises. getCurrentPosition(opts) → { timestamp, coords: { latitude, longitude, accuracy, altitude, speed, heading, … } } ; watchPosition(opts, callback) → l'identifiant de suivi (une chaîne) ; clearWatch({ id }) ; checkPermissions() / requestPermissions() → { location, coarseLocation } ('granted' | 'denied' | 'prompt' | …). Nécessite : GPS et/ou Localisation à l'étape 4 (Accès) - pour les applications HTML, ZIP et créées par IA, le build les active aussi de lui-même quand vos fichiers appellent getCurrentPosition ou watchPosition. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

Position unique, en demandant d'abord.

async function whereAmI() {
  var geo = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Geolocation;
  if (!geo) { showMessage('Open the app to use location.'); return; }
  try {
    var perm = await geo.checkPermissions();
    if (perm.location !== 'granted' && perm.coarseLocation !== 'granted') {
      perm = await geo.requestPermissions();
      if (perm.location !== 'granted' && perm.coarseLocation !== 'granted') {
        showMessage('Location is off for this app.');
        return;
      }
    }
    var pos = await geo.getCurrentPosition({ enableHighAccuracy: true, timeout: 15000 });
    showMessage(pos.coords.latitude.toFixed(5) + ', ' + pos.coords.longitude.toFixed(5));
  } catch (err) {
    showMessage('No location: ' + err.message);   // location off in settings, timeout, …
  }
}

Mises à jour continues. Le callback reçoit (position, error).

var watchId = null;

async function startTracking() {
  var geo = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Geolocation;
  if (!geo) return;
  watchId = await geo.watchPosition({ enableHighAccuracy: true }, function (pos, err) {
    if (err || !pos) return;
    addPointToMap(pos.coords.latitude, pos.coords.longitude);
  });
}

async function stopTracking() {
  var geo = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Geolocation;
  if (geo && watchId) { await geo.clearWatch({ id: watchId }); watchId = null; }
}

Dans une application créée par IA, utilisez le wrapper, qui fonctionne aussi sur le web :

import { Geolocation } from '@/lib/appmintNative';
const pos = await Geolocation.getCurrentPosition({ enableHighAccuracy: true });

Remarques : Un simple navigator.geolocation fonctionne aussi dans l'application. Si les interrupteurs de localisation étaient désactivés lors de la compilation, l'autorisation est refusée sans demande. Sur Android 12+, l'utilisateur peut n'autoriser que la position approximative (coarseLocation accordée). La position est une donnée personnelle : déclarez-la dans votre formulaire Play Sécurité des données.

Capacitor.Haptics Capacitor#

Capacitor.Plugins.Haptics

Exemple

Le plugin officiel Capacitor Haptics (@capacitor/haptics), intégré à l'application : tapotements légers/moyens/forts, retours succès/avertissement/erreur, crans de sélection et vibration simple.

Retourne : chaque méthode retourne une Promise qui se résout sans valeur. Nécessite : rien à activer : chaque application déclare l'autorisation de vibration, que Vibrer soit coché ou non à l'étape 4 (Accès). window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines), jamais sur les autres sites que l'application ouvre. Détectez la disponibilité.

function haptics() {
  return window.Capacitor && window.Capacitor.Plugins ? window.Capacitor.Plugins.Haptics : null;
}

async function tap(style) {            // 'LIGHT' | 'MEDIUM' | 'HEAVY'
  var h = haptics();
  if (!h) return;
  try { await h.impact({ style: style }); } catch (e) { console.log('haptics failed', e); }
}

async function result(type) {          // 'SUCCESS' | 'WARNING' | 'ERROR'
  var h = haptics();
  if (h) { try { await h.notification({ type: type }); } catch (e) {} }
}

document.getElementById('add').addEventListener('click', function () { tap('LIGHT'); });
document.getElementById('pay').addEventListener('click', function () { result('SUCCESS'); });

Crans de sélection pour un sélecteur ou un curseur, et une vibration simple :

var h = window.Capacitor && window.Capacitor.Plugins ? window.Capacitor.Plugins.Haptics : null;
var wheel = document.getElementById('wheel');

wheel.addEventListener('pointerdown', function () { if (h) h.selectionStart(); });
wheel.addEventListener('change', function () { if (h) h.selectionChanged(); });
wheel.addEventListener('pointerup', function () { if (h) h.selectionEnd(); });

document.getElementById('buzz').addEventListener('click', function () {
  if (h) h.vibrate({ duration: 300 });   // milliseconds
});

Faire vibrer en cas d'erreur et l'associer à un message visible :

var h = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Haptics;

function rejectInput(field) {
  field.classList.add('invalid');
  if (h) h.notification({ type: 'ERROR' }).catch(function () {});
}

Remarques : Les chaînes sont en majuscules ('HEAVY', pas 'heavy'). Dans les applications créées par IA, import { Haptics } from '@/lib/appmintNative' donne les mêmes noms. Pour des rythmes personnalisés avec une intensité par temps, utilisez Capacitor.Plugins.AppwrightHaptics.

Capacitor.InAppReview Capacitor#

Capacitor.Plugins.InAppReview — requestReview()

Exemple

Demande à Google Play d'afficher sa propre fenêtre « Évaluer cette application » dans l'application. Intégré @capacitor-community/in-app-review (template/plugins/in-app-review).

Retourne : Promise void - elle se résout quand le flux de Play se termine, et Play ne dit jamais si la feuille a été affichée ni ce que l'utilisateur a fait. Elle est rejetée quand Play n'a pas pu lancer le flux. Nécessite : rien à activer ; l'application doit être installée depuis Google Play pour que la feuille apparaisse. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var Review = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.InAppReview;

async function afterThirdOrder() {
  if (!Review) return;
  try {
    await Review.requestReview();
  } catch (e) {
    console.log('review flow not available:', e.message);
  }
  // continue the app flow either way — you cannot know if the user rated
}

Dans une application créée par IA :

import { requestReview } from '@/lib/appmintNative';

// after a success moment, not on launch
const asked = await requestReview();   // false where nothing could be asked (web)

Demander une seule fois, après un moment de réussite, et mémoriser qu'on a demandé :

var Review = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.InAppReview;

async function maybeAskForReview() {
  if (!Review || localStorage.getItem('review_asked')) return;
  localStorage.setItem('review_asked', '1');
  try { await Review.requestReview(); } catch (e) { console.log('review not shown:', e.message); }
}

Remarques : Play limite la fréquence d'affichage de la feuille et ne l'affiche pas pour chaque appel - ne liez jamais une récompense à son affichage et ne demandez jamais depuis un bouton « Évaluez-nous » en comptant sur son ouverture (ouvrez pour cela la fiche du store). Demandez après un moment de réussite, pas au démarrage. Une installation hors Play ou en débogage n'affiche généralement rien.

Capacitor.KeepAwake Capacitor#

Capacitor.Plugins.KeepAwake — keepAwake(), allowSleep(), isKeptAwake(), isSupported()

Exemple

Empêche l'écran de s'assombrir et de se verrouiller tant que quelque chose doit rester visible - une recette, un itinéraire, un code QR, un minuteur. Intégré @capacitor-community/keep-awake (template/plugins/keep-awake).

Retourne : keepAwake() / allowSleep() → Promise void. isKeptAwake() → { isKeptAwake: boolean }. isSupported() → { isSupported: true }. Nécessite : rien - chaque application héberge le plugin ; aucune autorisation. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var KA = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.KeepAwake;

async function startCooking() {
  if (KA) await KA.keepAwake();
  showSteps();
}

async function stopCooking() {
  if (KA) await KA.allowSleep();      // always release when the view closes
}

if (KA) KA.isKeptAwake().then(function (r) { console.log('awake?', r.isKeptAwake); });

Dans une application créée par IA (l'API Screen Wake Lock sur le web) :

import { keepAwake } from '@/lib/appmintNative';

useEffect(() => {
  void keepAwake(true);
  return () => { void keepAwake(false); };
}, []);

Garder l'écran allumé uniquement pendant qu'un minuteur tourne :

var KA = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.KeepAwake;

async function runTimer(seconds) {
  if (KA) await KA.keepAwake();
  await new Promise(function (done) { setTimeout(done, seconds * 1000); });
  if (KA) await KA.allowSleep();
  alert('Time is up');
}

Remarques : Le drapeau appartient à la fenêtre de l'application : il ne fonctionne que lorsque l'application est au premier plan, et reste actif jusqu'à allowSleep() - libérez-le à chaque sortie de l'écran. keepAwake() retourne false quand rien n'a pu garder l'écran allumé.

Capacitor.Keyboard Capacitor#

Capacitor.Plugins.Keyboard — show(), hide(), addListener('keyboardDidShow' | ...)

Exemple

Ouvre ou ferme le clavier logiciel et indique à la page quand il apparaît et sa hauteur (@capacitor/keyboard 8.0.5).

Retourne : show() / hide() → Promise void. addListener(event, fn) → une Promise d'un handle avec remove(), comme dans l'API propre à Capacitor - utilisez await dessus ou enchaînez .then() ; la valeur retournée a aussi remove() elle-même ; les événements d'affichage passent { keyboardHeight } en pixels CSS. Événements : keyboardWillShow, keyboardDidShow, keyboardWillHide, keyboardDidHide. Nécessite : rien à activer - chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var Keyboard = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Keyboard;

if (Keyboard) {
  Keyboard.addListener('keyboardDidShow', function (info) {
    console.log('keyboard height', info.keyboardHeight);
    document.body.classList.add('typing');       // e.g. hide the bottom tab bar
  });
  Keyboard.addListener('keyboardDidHide', function () {
    document.body.classList.remove('typing');
  });
}

function onSend() {
  if (Keyboard) Keyboard.hide().catch(function () {});   // rejects if no field is focused
}

Dans une application créée par IA, utilisez onKeyboard() pour la mise en page - il ne signale que la partie du clavier que la page redimensionnée ne dégage pas déjà - et hideKeyboard() pour le fermer :

import { onKeyboard, hideKeyboard, Keyboard } from '@/lib/appmintNative';

const off = onKeyboard((px) => { composer.style.paddingBottom = `${px}px`; });  // call off() on unmount
hideKeyboard();

const h = Keyboard.addListener('keyboardWillShow', ({ keyboardHeight }) => console.log(keyboardHeight));
h.remove();

Afficher le clavier pour un champ après un appui sur un bouton :

var Keyboard = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Keyboard;

searchBtn.addEventListener('click', function () {
  searchInput.focus();
  if (Keyboard) Keyboard.show().catch(function () {});
});

Remarques : L'enveloppe redimensionne déjà la page pour le clavier, donc n'ajoutez PAS le keyboardHeight complet comme marge intérieure - une barre du bas est déjà au-dessus des touches. setAccessoryBarVisible, setStyle, setResizeMode et setScroll ne sont pas implémentés sur Android - ne les appelez pas. hide() rejette « Can't close keyboard, not currently focused » quand rien n'a le focus.

Capacitor.LocalNotifications Capacitor#

Capacitor.Plugins.LocalNotifications — schedule, cancel, getPending, requestPermissions, events

Exemple

Notifications que l'application publie elle-même - tout de suite, ou à une heure donnée - avec l'API officielle @capacitor/local-notifications (com.capacitorjs:local-notifications). Le code écrit pour le paquet npm fonctionne sans changement.

Retourne : requestPermissions() / checkPermissions() → { display: 'granted' | 'denied' | 'prompt' } ; schedule({ notifications: [{ id, title, body, schedule?: { at | on | every }, extra?, actionTypeId?, channelId? }] }) → { notifications: [{ id }] } ; getPending() → { notifications } ; cancel({ notifications: [{ id }] }) ; registerActionTypes({ types }) ; createChannel / listChannels / deleteChannel ; checkExactNotificationSetting() → { exact_alarm }. Événements : localNotificationReceived, localNotificationActionPerformed (actionId vaut 'tap' pour un appui sur la notification elle-même). Nécessite : cochez Notifications à l'étape 4 (Accès) - sans cela, le plugin n'est pas dans l'application et chaque appel est rejeté avec « not implemented ». Pour les notifications programmées, cochez aussi ⏰ Rappels (horaire exact et maintien après un redémarrage). Les builds HTML, ZIP et AI-Studio cochent les deux d'eux-mêmes quand le code importe @capacitor/local-notifications et appelle LocalNotifications.schedule(. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

const LN = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.LocalNotifications;

async function remindIn(minutes, text) {
  if (!LN) return false;
  const { display } = await LN.requestPermissions();
  if (display !== 'granted') return false;
  await LN.schedule({ notifications: [{
    id: Date.now() % 2147483647,
    title: 'Reminder',
    body: text,
    schedule: { at: new Date(Date.now() + minutes * 60000), allowWhileIdle: true },
    extra: { screen: 'tasks' },
  }] });
  return true;
}

Ouvrir le bon écran quand l'utilisateur touche une notification - y compris quand ce toucher a lancé l'application, puisque l'événement attend l'écouteur :

const LN = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.LocalNotifications;

if (LN) {
  LN.addListener('localNotificationActionPerformed', ({ actionId, notification }) => {
    if (actionId === 'tap' && notification.extra && notification.extra.screen) {
      location.hash = '#/' + notification.extra.screen;
    }
  });
}

Un rappel d'habitude quotidien avec les boutons Terminé / Reporter :

const LN = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.LocalNotifications;

async function dailyWaterReminder() {
  await LN.registerActionTypes({ types: [{ id: 'water', actions: [
    { id: 'done', title: 'Done' },
    { id: 'snooze', title: 'In 30 min' },
  ] }] });
  await LN.schedule({ notifications: [{
    id: 42, title: 'Drink water', body: 'Time for a glass of water.',
    actionTypeId: 'water', schedule: { on: { hour: 10, minute: 0 }, repeats: true },
  }] });
  LN.addListener('localNotificationActionPerformed', ({ actionId }) => {
    if (actionId === 'snooze') {
      LN.schedule({ notifications: [{ id: 43, title: 'Drink water', body: 'Snoozed reminder.',
        schedule: { at: new Date(Date.now() + 30 * 60000) } }] });
    }
  });
}

Remarques : Sur Android 12+, une notification programmée demande l'autorisation d'alarme exacte : le premier schedule() peut ouvrir la page système « Alarmes et rappels » ; si l'utilisateur la laisse désactivée, la notification se déclenche quand même, un peu plus tard (le résultat contient un warning). Les notifications du plugin utilisent leur propre canal « Default », distinct des autres notifications de l'application. Un sound issu des fichiers web n'est pas pris en charge (Android joue le son par défaut du canal). Les appuis atteignent la page via l'écran de déverrouillage quand l'application a un code PIN. Les applications créées par IA utilisent notify() / LocalNotifications.schedule de @/lib/appmintNative, qui publie via la pile de notifications propre à l'application.

Capacitor.Network Capacitor#

Capacitor.Plugins.Network — getStatus(), addListener('networkStatusChange')

Exemple

Indique à la page si le téléphone est en ligne et sur quel type de connexion, et quand cela change (@capacitor/network 8.0.1).

Retourne : getStatus() → Promise { connected: boolean, connectionType: 'wifi' | 'cellular' | 'none' | 'unknown' }. L'événement networkStatusChange transmet la même forme. Nécessite : rien à activer - chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var Network = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Network;

function showBanner(s) {
  document.getElementById('offline').hidden = s.connected;
}

if (Network) {
  Network.getStatus().then(showBanner);
  Network.addListener('networkStatusChange', function (s) {
    showBanner(s);
    if (s.connected) retryQueuedWrites();
    if (s.connectionType === 'cellular') console.log('on mobile data');
  });
}

Dans une application créée par IA :

import { Network, networkStatus, onNetworkChange } from '@/lib/appmintNative';

const { connected, connectionType } = await Network.getStatus();
const now = networkStatus();                        // sync: { connected, type }
const off = onNetworkChange((s) => setOnline(s.connected));   // call off() on unmount

Mettre en pause un gros envoi sur données mobiles :

var Network = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Network;

async function canUploadVideo() {
  if (!Network) return navigator.onLine;
  var s = await Network.getStatus();
  if (!s.connected) return false;
  return s.connectionType === 'wifi' || confirm('Upload over mobile data?');
}

Remarques : connected signifie que le téléphone a un réseau, pas que votre serveur répond - gérez toujours les requêtes échouées. Les Network.getStatus() et networkStatus() du wrapper lisent navigator.onLine / navigator.connection, pas le plugin, donc leur type peut être 'unknown' ou une classe de débit comme '4g' ; onNetworkChange() utilise bien l'événement du plugin dans l'application.

Capacitor.Preferences Capacitor#

Capacitor.Plugins.Preferences — get / set / remove / keys / clear

Exemple

Un petit stockage clé-valeur natif (Android SharedPreferences) pour les chaînes (@capacitor/preferences 8.0.1).

Retourne : set({ key, value }), remove({ key }), clear() → Promise void ; get({ key }) → { value } (null quand la clé est absente) ; keys() → { keys: string[] }. Nécessite : rien à activer - chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var Prefs = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Preferences;

async function saveTheme(name) {
  if (!Prefs) return false;          // not inside the app
  await Prefs.set({ key: 'theme', value: name });
  return true;
}

async function loadTheme() {
  if (!Prefs) return null;
  var r = await Prefs.get({ key: 'theme' });
  return r.value;            // null if never saved
}

Les objets doivent d'abord être convertis en chaîne :

async function saveUser() {
  if (!Prefs) return;
  await Prefs.set({ key: 'user', value: JSON.stringify({ id: 7, name: 'Asha' }) });
  var u = JSON.parse((await Prefs.get({ key: 'user' })).value || 'null');
  var all = (await Prefs.keys()).keys;
  await Prefs.remove({ key: 'user' });
}

Listez et effacez les clés enregistrées depuis un écran de paramètres :

async function resetSettings() {
  if (!Prefs) return;
  var k = (await Prefs.keys()).keys;
  console.log('clearing', k.length, 'saved values');
  await Prefs.clear();
}

Remarques : @/lib/appmintNative n'a PAS de wrapper Preferences, volontairement : localStorage est déjà réel et persistant dans l'application, et un second stockage répartirait les données d'une application à deux endroits. Les applications créées par IA devraient continuer à utiliser localStorage (ou le runtime de données). N'utilisez Preferences dans une page écrite à la main que si vous voulez y mettre tous vos paramètres, et choisissez un seul stockage par valeur. configure({ group }) change le nom du stockage (par défaut CapacitorStorage).

Capacitor.PrivacyScreen Capacitor#

Capacitor.Plugins.PrivacyScreen — enable(), disable(), isEnabled()

Exemple

Le plugin officiel @capacitor/privacy-screen : bloque les captures et enregistrements d'écran et masque le contenu de l'application dans la vue des applications récentes. Intégré pour que les projets Capacitor importés qui l'appellent fonctionnent.

Retourne : enable({android}) → {success} ; disable() → {success} ; isEnabled() → {enabled}. Nécessite : rien à activer.

const Privacy = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.PrivacyScreen;

async function openVault() {
  if (Privacy) await Privacy.enable({ android: { privacyModeOnActivityHidden: 'dim' } });
  showVault();
}
async function closeVault() {
  if (Privacy) await Privacy.disable();
}

Vérifier l'état actuel avant de basculer :

async function toggleProtection() {
  if (!Privacy) return;
  var s = await Privacy.isEnabled();
  if (s.enabled) await Privacy.disable();
  else await Privacy.enable();
}

Protéger l'écran uniquement pendant qu'une vue sensible est ouverte :

async function showCardNumber() {
  if (Privacy) await Privacy.enable({ android: { privacyModeOnActivityHidden: 'splash' } });
  cardBox.hidden = false;
}
async function hideCardNumber() {
  cardBox.hidden = true;
  if (Privacy) await Privacy.disable();
}

Remarques : privacyModeOnActivityHidden : 'none', 'dim' ou 'splash'. Le code écrit pour l'application elle-même devrait utiliser WebToApk.setSecureScreen(true) / privacyScreen.enable() de @/lib/appmintNative, qui suit la page (libéré quand l'application la quitte) ; si vous mélangez les deux, le dernier appel l'emporte.

Capacitor.PushNotifications Capacitor#

Capacitor.Plugins.PushNotifications — register, requestPermissions, registration, pushNotificationReceived

Exemple

Notifications push depuis VOTRE PROPRE serveur via VOTRE projet Firebase, avec l'API officielle @capacitor/push-notifications (com.capacitorjs:push-notifications, enregistrée par le PushNotificationsPlugin.kt de l'enveloppe). Le code écrit pour le paquet npm fonctionne sans changement : register(), puis envoyez au jeton reçu dans l'événement registration avec le SDK Firebase Admin ou l'API FCM HTTP v1.

Retourne : requestPermissions() / checkPermissions() → { receive: 'granted' | 'denied' | 'prompt' } ; register() / unregister() → void (le jeton arrive comme l'événement registration { value }, un échec comme registrationError { error }) ; getDeliveredNotifications() → { notifications } ; removeDeliveredNotifications({ notifications }), removeAllDeliveredNotifications() ; createChannel({ id, name, importance? }), listChannels(), deleteChannel({ id }). Événements : pushNotificationReceived (un message pendant que l'application est ouverte : { id, title?, body?, data }) et pushNotificationActionPerformed ({ actionId: 'tap', notification: { id, data } }). Nécessite : compiler avec AppMint Push activé et votre google-services.json téléversé (étape Notifications) - c'est le projet Firebase auquel appartient le jeton. Sans cela, register() est rejeté avec le code PUSH_NOT_CONFIGURED (« Push is not set up in this app »). Les builds HTML, ZIP et AI-Studio cochent Notifications d'eux-mêmes quand le code appelle PushNotifications.register( / requestPermissions( / addListener(. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

const Push = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.PushNotifications;

async function enablePush(userId) {
  if (!Push) return;
  await Push.addListener('registration', ({ value }) => {
    // Your server stores the token and sends to it later.
    fetch('https://api.example.com/push-tokens', {
      method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ userId, token: value, platform: 'android' }),
    });
  });
  await Push.addListener('registrationError', ({ error }) => console.warn('push:', error));
  const { receive } = await Push.requestPermissions();
  if (receive !== 'granted') return;
  try { await Push.register(); }
  catch (e) { if (e.code === 'PUSH_NOT_CONFIGURED') alert('Push is not set up in this build.'); }
}

Réagir à un message pendant que l'application est ouverte, et à un appui sur un message arrivé pendant qu'elle était fermée (l'événement d'appui attend votre écouteur, donc un démarrage à froid n'est pas perdu) :

const Push = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.PushNotifications;

if (Push) {
  Push.addListener('pushNotificationReceived', (msg) => {
    alert((msg.title || 'New message') + (msg.body ? ': ' + msg.body : ''));
  });
  Push.addListener('pushNotificationActionPerformed', ({ notification }) => {
    const orderId = notification.data && notification.data.orderId;
    if (orderId) location.hash = '#/orders/' + orderId;
  });
}

Un canal pour les alertes importantes (Android 8+), utilisé par les messages qui le nomment dans android.notification.channel_id:

const Push = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.PushNotifications;

async function setupChannels() {
  if (!Push) return;
  await Push.createChannel({ id: 'orders', name: 'Order updates', description: 'Your order status', importance: 4, vibration: true });
}

Remarques : Un message envoyé avec un bloc notification est affiché par Android lui-même quand l'application est en arrière-plan ; son appui ouvre l'application (via l'écran de déverrouillage quand l'application a un PIN) et déclenche pushNotificationActionPerformed. Tant que l'application est ouverte, les messages arrivent sous forme de pushNotificationReceived et ne sont pas dessinés dans la zone de notifications. Les messages de données seules n'atteignent la page que lorsqu'elle est ouverte. Les messages AppMint Push continuent de fonctionner en parallèle : ils n'atteignent jamais ce plugin. Dans une application créée avec OneSignal au lieu d'AppMint Push, les messages sont livrés par OneSignal et n'atteignent jamais ce plugin. Les applications créées par IA reçoivent les notifications push du créateur via pushInbox() depuis @/lib/appmintNative.

Capacitor.ScreenBrightness Capacitor#

Capacitor.Plugins.ScreenBrightness — getBrightness(), setBrightness({ brightness })

Exemple

Règle la luminosité de l'écran de la fenêtre de l'application - pleine luminosité pour une carte d'embarquement ou un code QR, puis retour à la normale. Intégré @capacitor-community/screen-brightness (template/plugins/screen-brightness).

Retourne : getBrightness() → Promise { brightness } (0-1, ou -1 quand l'application ne l'a pas remplacée et que l'écran suit le système). setBrightness({ brightness }) → Promise void. Nécessite : rien - chaque application héberge le plugin ; aucune autorisation (il ne modifie que la fenêtre de cette application, pas le réglage système). window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var SB = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.ScreenBrightness;

async function showTicket() {
  if (SB) await SB.setBrightness({ brightness: 1 });     // full brightness
  document.getElementById('qr').hidden = false;
}

async function hideTicket() {
  if (SB) await SB.setBrightness({ brightness: -1 });    // -1 = follow the system again
  document.getElementById('qr').hidden = true;
}

Dans une application créée par IA :

import { brightness } from '@/lib/appmintNative';

await brightness.set(1);        // clamped to 0–1; false where not available (web)
// ... on leaving the screen
await brightness.restore();
const level = await brightness.get();   // -1 = following the system / not available

Lisez d'abord le niveau actuel et restaurez exactement celui-ci :

var SB = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.ScreenBrightness;
var before = -1;

async function boost() {
  if (!SB) return;
  before = (await SB.getBrightness()).brightness;
  await SB.setBrightness({ brightness: 1 });
}
async function undo() {
  if (SB) await SB.setBrightness({ brightness: before });
}

Remarques : Passez toujours un nombre - setBrightness({}) n'a aucune valeur à appliquer. Restaurez avec -1 quand la vue se ferme ; le réglage prend aussi fin quand l'application se ferme. Une page web ne peut pas piloter le rétroéclairage, donc can('brightness') vaut 'none' dans un navigateur.

Capacitor.ScreenOrientation Capacitor#

Capacitor.Plugins.ScreenOrientation — orientation(), lock({ orientation }), unlock()

Exemple

Lit l'orientation de l'écran, la verrouille pour une vue (un jeu, un graphique, un pavé de signature) puis la libère (@capacitor/screen-orientation 8.0.1).

Retourne : orientation() → Promise { type } (par ex. 'portrait-primary'). lock() / unlock() → Promise void. L'événement screenOrientationChange transmet { type }. Nécessite : rien à activer - chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

orientation valeurs : 'portrait', 'landscape', 'portrait-primary', 'portrait-secondary', 'landscape-primary', 'landscape-secondary', 'natural', 'any'.

var SO = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.ScreenOrientation;

async function openChart() {
  if (SO) await SO.lock({ orientation: 'landscape' });
  showChart();
}

async function closeChart() {
  if (SO) await SO.unlock();          // always release when leaving the view
  hideChart();
}

if (SO) {
  SO.orientation().then(function (o) { console.log('now', o.type); });
  SO.addListener('screenOrientationChange', function (o) { console.log('rotated to', o.type); });
}

Dans une application créée par IA :

import { lockOrientation, ScreenOrientation } from '@/lib/appmintNative';

const ok = await lockOrientation('landscape');   // false when refused (always on desktop)
await lockOrientation('any');                    // release

await ScreenOrientation.lock({ orientation: 'portrait' });
await ScreenOrientation.unlock();

Gérer un verrouillage refusé et en informer l'utilisateur :

var SO = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.ScreenOrientation;
var Toast = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Toast;

async function tryLandscape() {
  if (!SO) { document.getElementById('rotate-hint').hidden = false; return; }   // ask the user to rotate by hand
  try {
    await SO.lock({ orientation: 'landscape' });
  } catch (e) {
    if (Toast) Toast.show({ text: 'Could not rotate the screen', duration: 'short' });
  }
}

Remarques : Les wrappers ne connaissent que portrait / landscape / any : ScreenOrientation.lock({ orientation: 'landscape-secondary' }) se verrouille sur un simple landscape. Donnez à l'utilisateur un moyen de sortir d'une vue verrouillée.

Capacitor.ScreenReader Capacitor#

Capacitor.Plugins.ScreenReader — isEnabled(), speak({ value, language }), addListener('stateChange')

Exemple

Indique à la page si TalkBack est activé, et prononce une annonce (@capacitor/screen-reader 8.0.1).

Retourne : isEnabled() → Promise { value: boolean }. speak() → Promise void. L'événement stateChange transmet { value: boolean } quand TalkBack est activé ou désactivé. Nécessite : rien à activer - chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var SR = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.ScreenReader;

function setCalmMode(on) {
  document.documentElement.classList.toggle('no-motion', on);   // shorten animations
}

if (SR) {
  SR.isEnabled().then(function (r) { setCalmMode(r.value); });
  SR.addListener('stateChange', function (s) { setCalmMode(s.value); });
}

async function announceSaved() {
  if (SR) await SR.speak({ value: 'Order placed', language: 'en' });
}

Dans une application créée par IA (speak utilise la synthèse vocale sur le web ; isEnabled() y vaut false) :

import { screenReader } from '@/lib/appmintNative';

const on = await screenReader.isEnabled();
const off = screenReader.onChange((enabled) => setCalmMode(enabled));
await screenReader.speak('Order placed', 'en');

Détectez la fonctionnalité et gardez la page utilisable sans le plugin :

var SR = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.ScreenReader;

async function say(message) {
  if (SR) { await SR.speak({ value: message }); return; }
  document.getElementById('live-region').textContent = message;   // an aria-live="polite" element
}

Remarques : language vaut 'en' par défaut. Préférez un balisage accessible normal (libellés, régions aria-live) pour la plupart des annonces ; utilisez speak pour les changements d'état courts et importants. Il n'existe pas d'API web pour détecter un lecteur d'écran, donc can('screenReader') vaut 'none' dans un navigateur.

Capacitor.Share Capacitor#

Capacitor.Plugins.Share — share(options), canShare()

Exemple

Ouvre la feuille de partage d'Android avec un titre, un texte et/ou un lien (@capacitor/share 8.0.1).

Retourne : share() → Promise { activityType } (le nom de composant de l'application choisie, peut être '') ; elle est REJETÉE quand l'utilisateur ferme la feuille. canShare() → Promise { value: boolean }. Nécessite : rien à activer - chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

async function shareLink() {
  var Share = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Share;
  if (!Share) { alert('Sharing is not available here'); return; }
  // Only pass the fields you have. A present but empty `url` is rejected ("Unsupported url").
  var opts = { title: 'My list', text: 'Milk, eggs, bread' };
  var link = 'https://example.com/list/42';
  if (link) opts.url = link;
  try {
    var r = await Share.share(opts);
    console.log('shared to', r.activityType);
  } catch (e) {
    console.log('share cancelled or failed:', e.message);   // "Share canceled" on dismiss
  }
}

Dans une application créée par IA, l'enveloppe a la même forme et rejette aussi en cas d'annulation :

import { Share, can } from '@/lib/appmintNative';

if (can('share') !== 'none') {
  try {
    await Share.share({ title: 'My list', text: 'Milk, eggs, bread', url: 'https://example.com/list/42' });
  } catch {
    // the user closed the sheet — not an error to show
  }
}

Vérifiez d'abord canShare() et masquez le bouton quand le partage n'est pas disponible :

var Share = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Share;
var btn = document.getElementById('share');

btn.hidden = true;
if (Share) {
  Share.canShare().then(function (r) { btn.hidden = !r.value; });
}

Remarques : url doit être http(s):// ou file://. dialogTitle définit le titre du sélecteur. Pour partager des fichiers, il faut des chemins file:// appartenant à l'application ; depuis une page, partagez plutôt les fichiers avec navigator.share({ files }). Un seul partage peut être ouvert à la fois (« Can't share while sharing is in progress »).

Capacitor.SpeechRecognition Capacitor#

Capacitor.Plugins.SpeechRecognition

Exemple

Transforme la voix de l'utilisateur en texte avec la reconnaissance vocale d'Android (le plugin communautaire @capacitor-community/speech-recognition, intégré à l'application). Android WebView n'a pas de reconnaissance Web Speech propre, c'est donc la méthode pour la dictée.

Retourne : des Promises. available() → { available }. checkPermissions() / requestPermissions() → { speechRecognition: 'granted' | 'denied' | 'prompt' }. start({ partialResults: false }) → { status: 'success', matches: [...] } après que l'utilisateur a fini de parler ; rejette en cas d'erreurs comme l'absence de voix ou de correspondance. Nécessite : cochez Micro à l'étape 4 (Accès) lors de la compilation (pour les applications HTML, ZIP et créées par IA, le build ajoute aussi l'autorisation du microphone de lui-même quand vos fichiers mentionnent SpeechRecognition), et l'utilisateur doit autoriser le microphone. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

Dictée en une fois (comme l'utilise @/lib/appmintNative speech) :

var SR = window.Capacitor && window.Capacitor.Plugins ? window.Capacitor.Plugins.SpeechRecognition : null;

async function dictate() {
  var out = document.getElementById('text');
  if (!SR || !(await SR.available()).available) { out.textContent = 'Voice input is not available on this phone.'; return; }

  var p = (await SR.checkPermissions()).speechRecognition;
  if (p !== 'granted') p = (await SR.requestPermissions()).speechRecognition;
  if (p !== 'granted') { out.textContent = 'Microphone permission was not given.'; return; }

  try {
    var r = await SR.start({ language: 'en-US', maxResults: 3, partialResults: false, popup: false });
    out.textContent = r.matches && r.matches.length ? r.matches[0] : '';
  } catch (e) {
    out.textContent = 'Did not catch that. Try again.';
  }
}

document.getElementById('mic').addEventListener('click', dictate);

Texte en direct pendant que l'utilisateur parle (partialResults: true), et l'état d'écoute :

// Add the listeners ONCE, when the page starts.
if (SR) {
  SR.addListener('partialResults', function (d) {
    // Words as they come, and then the final text, all arrive here.
    if (d.matches && d.matches.length) document.getElementById('text').textContent = d.matches[0];
  });
  SR.addListener('listeningState', function (d) {
    // 'started' = the user began speaking, 'stopped' = the user stopped speaking
    document.body.classList.toggle('listening', d.status === 'started');
  });
}

document.getElementById('mic-live').addEventListener('click', async function () {
  if (!SR) return;
  try {
    await SR.start({ language: 'en-US', partialResults: true, popup: false });   // resolves at once, no matches
  } catch (e) {
    document.getElementById('text').textContent = 'Could not start: ' + e.message;
  }
});

document.getElementById('stop').addEventListener('click', function () { if (SR) SR.stop(); });

Affichez le bouton micro uniquement lorsque la dictée peut fonctionner, et arrêtez l'écoute quand la page est masquée :

var SR = window.Capacitor && window.Capacitor.Plugins ? window.Capacitor.Plugins.SpeechRecognition : null;
var mic = document.getElementById('mic');

mic.hidden = true;
if (SR) {
  SR.available().then(function (r) { mic.hidden = !r.available; });
}

document.addEventListener('visibilitychange', function () {
  if (document.hidden && SR) SR.stop();
});

Remarques :

  • En mode direct (partialResults: true), le texte final arrive après l'état 'stopped', donc ne retirez pas l'écouteur partialResults sur 'stopped'. Une erreur survenue après le démarrage (pas de voix, pas de correspondance) n'est pas signalée dans ce mode.
  • language est une balise comme 'en-US' ou 'ta-IN' (par défaut : la langue du téléphone). popup: true affiche à la place la boîte de dialogue d'écoute de Google. getSupportedLanguages() → { languages } et isListening() → { listening } existent aussi.
  • start() est rejeté avec 'Missing permission' si vous n'avez pas demandé l'autorisation d'abord. L'écoute s'arrête d'elle-même après une pause dans la parole.

Capacitor.SplashScreen Capacitor#

Capacitor.Plugins.SplashScreen — show(), hide()

Exemple

L'API @capacitor/splash-screen au-dessus de l'écran de démarrage de marque de l'application, afin que les projets Capacitor / AI Studio importés qui appellent SplashScreen.hide() une fois leur premier écran prêt fonctionnent dans l'application Android.

Retourne : hide() → Promise (l'écran de démarrage disparaît une fois la durée minimale choisie par le créateur écoulée) ; show({showDuration, autoHide}) → Promise (l'écran de démarrage revient par-dessus la page et, avec autoHide - la valeur par défaut - disparaît après showDuration ms, 3000 par défaut). Nécessite : rien à activer.

const Splash = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.SplashScreen;

async function boot() {
  await loadFirstScreen();
  if (Splash) await Splash.hide();     // otherwise the shell hides it at first paint
}
boot();

Masquer un changement de compte lent avec l'écran de démarrage, maintenu jusqu'à ce que les nouvelles données soient à l'écran :

const Splash = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.SplashScreen;

async function switchAccount(accountId) {
  if (Splash) await Splash.show({ autoHide: false });   // stays until hide()
  try {
    await loadAccount(accountId);
    renderHome();
  } finally {
    if (Splash) await Splash.hide();
  }
}

Afficher l'écran de démarrage de marque un instant après la déconnexion ; il disparaît de lui-même après showDuration:

const Splash = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.SplashScreen;

async function signOut() {
  await clearSession();
  showSignInScreen();
  if (Splash) {
    try {
      await Splash.show({ showDuration: 1200 });
    } catch (e) {
      console.warn('splash not shown:', e.code);
    }
  }
}

Remarques : sans appel à hide(), l'écran de démarrage disparaît quand même au premier affichage, comme dans toute application. Les applications créées par IA utilisent splash.hold() / splash.ready() de @/lib/appmintNative.

Capacitor.StatusBar Capacitor#

Capacitor.Plugins.StatusBar — setStyle, setBackgroundColor, show, hide, getInfo

Exemple

Modifie le style des icônes, la couleur et la visibilité de la barre d'état (@capacitor/status-bar 8.0.2).

Retourne : chaque méthode → Promise void, sauf getInfo() → { visible, style, color, overlays, height }. Nécessite : rien à activer - chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

style nomme l'ARRIÈRE-PLAN qui lui convient : 'DARK' = icônes claires (pour une barre sombre), 'LIGHT' = icônes sombres, 'DEFAULT' = suivre le système.

var StatusBar = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.StatusBar;
if (StatusBar) {
  StatusBar.setStyle({ style: 'DARK' });          // light icons
  StatusBar.hide();                               // e.g. while a video plays
  // later
  StatusBar.show();
}

Colorez la barre avec le pont de l'enveloppe, pas avec le plugin. Sur Android 15+, le setBackgroundColor du plugin ne fait rien (le mode bord à bord l'ignore). L'enveloppe peint elle-même la bande et prend le style des icônes dans le même appel :

if (window.WebToApk && window.WebToApk.setStatusBarColor) {
  window.WebToApk.setStatusBarColor('#0B0F1A', 'light');   // dark bar, light icons
} else if (StatusBar) {
  StatusBar.setBackgroundColor({ color: '#0B0F1A' });      // hex only, e.g. #RRGGBB
}

Dans une application créée par IA, utilisez setStatusBar(color, contentStyle) ; il privilégie le pont de l'enveloppe et règle la couleur et les icônes en un seul appel :

import { setStatusBar, StatusBar } from '@/lib/appmintNative';

setStatusBar('#0B0F1A', 'light');                       // dark bar, light icons
await StatusBar.setBackgroundColor({ color: '#FFFFFF' }); // colour only; icons picked from luminance

Remarques : setBackgroundColor rejette une couleur qui n'est pas une chaîne hexadécimale. Dans les builds plein écran / kiosque, les barres sont masquées par l'enveloppe. Dans l'application Android, le StatusBar.setStyle() du wrapper seul ne change rien (le pont a besoin d'une couleur pour peindre) - passez le style à setStatusBar() avec une couleur.

Capacitor.TextToSpeech Capacitor#

Capacitor.Plugins.TextToSpeech — speak(), stop(), getSupportedLanguages(), getSupportedVoices()

Exemple

Le plugin communautaire @capacitor-community/text-to-speech au-dessus du moteur de synthèse vocale du téléphone. Intégré pour que les projets Capacitor importés qui l'appellent fonctionnent.

Retourne : speak({text, lang, rate, pitch, volume, voice}) → Promise qui se résout quand la phrase a été prononcée ; stop() ; getSupportedLanguages() → {languages} ; getSupportedVoices() → {voices} ; isLanguageSupported({lang}) → {supported}. Nécessite : rien à activer.

const Tts = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.TextToSpeech;

async function readAloud(text) {
  if (!Tts) { speechSynthesis.speak(new SpeechSynthesisUtterance(text)); return; }
  await Tts.speak({ text: text, lang: 'en-US', rate: 1.0, pitch: 1.0, volume: 1.0 });
}
document.getElementById('stop').onclick = () => Tts && Tts.stop();

Vérifiez la langue avant de parler et affichez un message quand elle n'est pas installée :

const Tts = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.TextToSpeech;

async function speakIn(lang, text) {
  if (!Tts) return false;
  const { supported } = await Tts.isLanguageSupported({ lang: lang });
  if (!supported) { showMessage('This phone has no ' + lang + ' voice installed.'); return false; }
  await Tts.speak({ text: text, lang: lang });
  return true;
}

Lire un paragraphe à voix haute avec un bouton d'arrêt, et gérer une erreur de synthèse vocale :

const Tts = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.TextToSpeech;

async function readParagraph(el, btn) {
  if (!Tts) return;
  btn.textContent = 'Stop';
  btn.onclick = () => Tts.stop();
  try {
    await Tts.speak({ text: el.textContent, lang: 'en-US', rate: 0.9 });   // resolves when finished
  } catch (e) {
    console.warn('could not speak:', e.message);
  } finally {
    btn.textContent = 'Listen';
    btn.onclick = () => readParagraph(el, btn);
  }
}

Remarques : window.speechSynthesis fonctionne aussi dans l'application (le moteur propre à l'enveloppe) et c'est ce qu'utilisent les applications créées par IA via speak() ; ce plugin est la voie au format Capacitor.

Capacitor.TextZoom Capacitor#

Capacitor.Plugins.TextZoom — get(), getPreferred(), set({ value })

Exemple

Lit et modifie la taille du texte de la page de l'application, pour un contrôle « taille du texte » dans l'application (@capacitor/text-zoom 8.0.1).

Retourne : get() → Promise { value } (zoom actuel, 1 = 100 %). getPreferred() → { value } (la taille choisie par l'utilisateur dans les paramètres Android). set({ value }) → Promise void. Nécessite : rien à activer - chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var TZ = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.TextZoom;

async function biggerText() {
  if (!TZ) return;
  var now = (await TZ.get()).value;
  await TZ.set({ value: Math.min(2, now + 0.1) });
}

async function resetText() {
  if (!TZ) return;
  var pref = (await TZ.getPreferred()).value;   // e.g. 1.15 when the phone uses large text
  await TZ.set({ value: pref });
}

Dans une application créée par IA (sur le web, cela met à l'échelle la taille de police racine à la place) :

import { textZoom } from '@/lib/appmintNative';

const size = await textZoom.get();
await textZoom.set(size + 0.1);                     // clamped to 0.5–3
await textZoom.set(await textZoom.getPreferred());  // back to the system size

Un curseur de taille de texte qui mémorise le choix :

var TZ = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.TextZoom;
var slider = document.getElementById('text-size');   // <input type="range" min="0.8" max="1.6" step="0.1">

if (TZ) {
  var saved = parseFloat(localStorage.getItem('textZoom'));
  if (saved) TZ.set({ value: saved });
  slider.addEventListener('change', function () {
    TZ.set({ value: parseFloat(slider.value) });
    localStorage.setItem('textZoom', slider.value);
  });
} else {
  slider.hidden = true;
}

Remarques : L'application suit déjà la taille de texte du système ; ceci sert à ajouter un contrôle supplémentaire dans l'application. Testez votre mise en page aux grandes tailles - les hauteurs fixes sur les champs de texte seront tronquées.

Capacitor.Toast Capacitor#

Capacitor.Plugins.Toast — show({ text, duration, position })

Exemple

Affiche un court toast système Android comme « Enregistré » ou « Copié » (@capacitor/toast 8.0.1).

Retourne : Promise void. Nécessite : rien à activer - chaque application héberge le plugin. window.Capacitor existe sur les pages que l'application sert elle-même (applications HTML, ZIP et créées par IA) et, dans une application en mode Site web, sur votre propre site (son domaine et ses sous-domaines) - jamais sur les autres sites que l'application ouvre. Détectez la fonctionnalité avant de l'utiliser.

var Toast = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Toast;

function saved() {
  if (Toast) Toast.show({ text: 'Saved', duration: 'short', position: 'bottom' });
}

duration vaut 'short' (environ 2 s) ou 'long' (environ 3,5 s). position vaut 'top', 'center' ou 'bottom'.

Dans une application créée par IA, utilisez toast() ou le Toast au format Capacitor ; sur le web, ils affichent un snackbar aux couleurs de l'application :

import { Toast, toast } from '@/lib/appmintNative';

await Toast.show({ text: 'Added to list', duration: 'long' });
toast('Copied');   // short form, same result

Détectez la fonctionnalité et affichez un message dans la page quand le plugin est absent :

function notify(message) {
  var Toast = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Toast;
  if (Toast) { Toast.show({ text: message, duration: 'short' }); return; }
  var el = document.getElementById('snackbar');   // a plain in-page message
  el.textContent = message;
  el.hidden = false;
  setTimeout(function () { el.hidden = true; }, 2000);
}

Remarques : text est obligatoire (« Must provide text »). Le système dessine le toast dans le style du fabricant du téléphone, et les versions récentes d'Android ignorent position pour les toasts de texte. Un toast se rate facilement : ne l'utilisez jamais pour une erreur sur laquelle l'utilisateur doit agir ; utilisez Dialog.alert pour cela.

Capacitor.Torch Capacitor#

Capacitor.Plugins.Torch — enable(), disable(), toggle(), isEnabled(), isAvailable()

Exemple

La lampe de poche du téléphone, avec l'API @capawesome/capacitor-torch. Plugin propre à l'enveloppe de l'application (TorchPlugin.kt).

Retourne : enable() / disable() / toggle() → Promise (rejette CAMERA_IN_USE tant que le flux de caméra propre à l'application est ouvert, UNAVAILABLE sans flash) ; isEnabled() → {enabled} ; isAvailable() → {available}. Nécessite : rien à activer et aucune autorisation.

const Torch = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Torch;

async function setupLightButton() {
  if (!Torch || !(await Torch.isAvailable()).available) { lightBtn.hidden = true; return; }
  lightBtn.onclick = async () => {
    try {
      await Torch.toggle();
      lightBtn.classList.toggle('on', (await Torch.isEnabled()).enabled);
    } catch (e) {
      alert(e.message);
    }
  };
}

Faites clignoter un signal SOS depuis un bouton, et éteignez la lumière si l'appareil photo prend le flash en cours de route :

const Torch = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Torch;
const wait = (ms) => new Promise((r) => setTimeout(r, ms));

sosBtn.onclick = async () => {
  if (!Torch || !(await Torch.isAvailable()).available) return;
  const flashes = [200, 200, 200, 600, 600, 600, 200, 200, 200];   // S O S, in ms
  try {
    for (const ms of flashes) {
      await Torch.enable();  await wait(ms);
      await Torch.disable(); await wait(200);
    }
  } catch (e) {
    await Torch.disable().catch(() => {});
    alert(e.code === 'CAMERA_IN_USE' ? 'Close the camera first.' : e.message);
  }
};

Garder un bouton de lampe synchronisé avec le système, puisque l'utilisateur peut allumer la lampe depuis la tuile des réglages rapides pendant que l'application est en arrière-plan :

const Torch = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Torch;

async function syncLightButton() {
  if (!Torch) return;
  const { enabled } = await Torch.isEnabled();
  lightBtn.classList.toggle('on', enabled);
  lightBtn.setAttribute('aria-pressed', String(enabled));
}

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'visible') syncLightButton();
});
syncLightButton();

Remarques : la lampe suit l'état du système (l'éteindre depuis la tuile des réglages rapides se lit comme éteinte) et est éteinte à la fermeture de l'application. Tant qu'un flux getUserMedia est ouvert, allumez-la via la piste : track.applyConstraints({ advanced: [{ torch: true }] }). Les applications créées par IA utilisent torch de @/lib/appmintNative.

Généré à partir de l'environnement d'exécution de l'application et de ses fichiers d'exemple à chaque compilation de la documentation. Lire en Markdown · Toutes les familles.

Vérifié par rapport au pont publié le 22/10/2026.