API JavaScript
Les applications créées avec Free HTML to APK injectent un pont natif sous le nom window.FreeApp. Appelez-le depuis du JavaScript simple, depuis React ou Vue, ou depuis un moteur de jeu. Votre page continue de fonctionner dans un navigateur normal si vous protégez les appels.
Premiers pas
Le pont peut arriver un instant après l'exécution de vos scripts : faites donc la configuration native dans l'événement freeappready, et aussi immédiatement si window.FreeApp existe déjà. Prévoyez toujours une solution de repli pour le navigateur.
function setup() { FreeApp.statusBar('#E2552A'); FreeApp.toast('Hello from Android'); } if (window.FreeApp) setup(); else window.addEventListener('freeappready', setup, { once: true }); document.querySelector('#buzz').onclick = () => window.FreeApp ? FreeApp.vibrate(40) : console.log('Not in the app');
Les appels qui nécessitent une autorisation (caméra, micro, position, notifications) la demandent à l'utilisateur la première fois. Activez l'autorisation correspondante dans l'étape Autorisations du générateur ; les modèles activent ce que leur code utilise.
Retour d'information et interface
FreeApp.brightness(level: number): voidDe 0.0 à 1.0 pour cette fenêtre ; une valeur négative rétablit la luminosité du système.
FreeApp.fullscreen(on: boolean): voidMasquer les barres système (immersif).
FreeApp.keepAwake(on: boolean): voidGarder l'écran allumé.
FreeApp.notify(title: string, body?: string): voidNotification locale immédiate (demande l'autorisation sur Android 13+).
FreeApp.orientation(value: 'portrait' | 'landscape' | 'sensor_portrait' | 'sensor_landscape' | 'sensor' | 'unspecified'): voidFreeApp.print(): voidImprimer / enregistrer la page en PDF.
FreeApp.scheduleNotification(title: string, body: string, delayMs: number, opts?: {id?: number, url?: string, repeatMs?: number, exact?: boolean}): numberRenvoie l'identifiant.
FreeApp.speak(text: string, lang?: string): voidSynthèse vocale native, langue comme 'en-US'.
FreeApp.statusBar(hexColor: string): voidPar ex. '#2563EB'.
FreeApp.stopSpeaking(): voidFreeApp.toast(message: string): voidCourt toast natif.
FreeApp.vibrate(ms?: number | number[]): voidUne vibration unique (50 ms par défaut) ou un motif [off, on, off, on…].
Caméra et numérisation
FreeApp.camera.capture(opts?: {maxSize?: number, quality?: number, mirror?: boolean}): Promise<{dataUrl, facing}>Photo prise depuis l'aperçu en direct.
FreeApp.camera.start(opts?: {facing?: 'back' | 'front', element?: string | Element /* place the preview over this element */, behind?: boolean /* draw under a transparent page so HTML controls float on top */}): Promise<{facing}>FreeApp.camera.switch(): Promise<{facing}>; FreeApp.camera.torch(on: boolean): boolean; FreeApp.camera.stop(): void; FreeApp.camera.isOpen(): booleanFreeApp.compressImage(dataUrl: string, opts?: {maxSize?: number, quality?: number}): Promise<{dataUrl, width, height, bytes}>Natif, rapide sur les téléphones d'entrée de gamme.
FreeApp.saveToGallery(dataUrl: string, fileName?: string): Promise<{uri}>Enregistre une image dans Photos.
FreeApp.scanCode(opts?: {formats?: string[] /* e.g. ['QR_CODE','EAN_13','CODE_128'] */, facing?: 'back' | 'front'}): Promise<{text, format}>Scanner natif plein écran de QR / codes-barres avec lampe torche ; rejette avec 'cancelled'.
FreeApp.torch(on: boolean): booleanLampe de poche, renvoie false s'il n'y a pas de flash.
Position et capteurs
FreeApp.address(lat: number, lng: number): Promise<{address, city, country, countryCode, postalCode, street}>FreeApp.compass(cb: (d: {heading: number /* degrees */, pitch: number, roll: number}) => void): (() => void) | nullRenvoie une fonction d'arrêt.
FreeApp.location(opts?: {maxAge?: number}): Promise<{lat, lng, accuracy, altitude, speed, provider, time, fromLastKnown}>FreeApp.maps(query: string): voidOuvrir un lieu ou « lat,lng » dans l'application de cartes.
FreeApp.sensors.start(type: 'accelerometer' | 'gyroscope' | 'magnetometer' | 'light' | 'proximity' | 'pressure' | 'gravity' | 'linear_acceleration' | 'rotation' | 'humidity' | 'temperature' | 'steps' | 'step_detector', cb: (d: {type, values: number[], x, y, z, accuracy, t}) => void, intervalMs?: number): (() => void) | nullRenvoie une fonction d'arrêt, ou null si indisponible.
FreeApp.sensors.stop(type: string): voidFreeApp.watchLocation(cb: (p) => void, opts?: {interval?: number, distance?: number}): () => voidRenvoie une fonction d'arrêt.
Appareil et application
FreeApp.app(): {packageName, versionName, versionCode, name, firstInstall}FreeApp.battery(): {level: number /* 0-100 */, charging: boolean}FreeApp.biometric(title: string, subtitle?: string): Promise<boolean>Déverrouillage par empreinte / visage.
FreeApp.device(): {manufacturer, model, brand, androidVersion, sdkInt, language, screenWidth, screenHeight, density, isTablet, darkMode}FreeApp.launchUrl(): string | nullLe lien profond qui a ouvert l'application.
FreeApp.network(): 'wifi' | 'cellular' | 'ethernet' | 'vpn' | 'other' | 'none' | 'unknown'FreeApp.on('deeplink', (d: {url}) => void): () => voidLiens ouverts pendant que l'application est en cours d'exécution.
FreeApp.online(): booleanFichiers, partage et stockage
FreeApp.copy(text: string): voidCopier dans le presse-papiers.
FreeApp.open(url: string): voidOuvrir dans le navigateur / l'application externe.
FreeApp.paste(): stringLire le texte du presse-papiers.
FreeApp.pickFile(opts?: {accept?: string[], multiple?: boolean}): Promise<{name, mime, size, dataUrl}>FreeApp.saveFile(name: string, mime: string, data: string /* base64 or data: URL */ | Blob): Promise<boolean>Enregistre dans Téléchargements ; FreeApp.on('saved', d => …) donne {name, ok, location}.
FreeApp.store.get(key: string): any | nullFreeApp.store.set(key: string, value: any): voidStockage natif persistant clé/valeur (JSON).
NFC
FreeApp.nfc.read(): Promise<{tagId, techs: string[], writable, maxSize, records: Array<{type: "text" | "uri" | "mime" | "unknown", value, mime?, lang?}>}>Attend un tag ; FreeApp.nfc.stop() annule.
FreeApp.nfc.status(): 'ready' | 'disabled' | 'unsupported' | 'not_enabled_in_app'FreeApp.nfc.write(records: string | Array<{type: 'text' | 'uri' | 'mime', value: string, mime?: string}>): Promise<{written}>Autorisations
FreeApp.hasPermission(name: string): booleanFreeApp.openSettings(): voidOuvrir la page des paramètres système de cette application.
FreeApp.permissionStatus(name: 'camera' | 'microphone' | 'location' | 'notifications' | 'activity'): 'granted' | 'prompt' | 'blocked' | 'unavailable'FreeApp.requestPermission(name: 'camera' | 'microphone' | 'location' | 'notifications'): Promise<boolean>FreeApp.requestPermissions(names: string[]): Promise<{[name]: boolean}>Publicités
Disponible lorsque AdMob est activé dans le générateur. En mode test, les publicités de test de Google s'affichent.
FreeApp.ads.loadBanner(unit?: string, position?: 'top' | 'bottom'): voidCharge et affiche une bannière. Sans arguments, elle utilise le bloc et la position définis dans le générateur.
FreeApp.ads.showBanner(position?) / hideBanner() / isBannerLoaded()Afficher, masquer ou vérifier la bannière.
FreeApp.ads.loadInterstitial(unit?) / showInterstitial() / isInterstitialLoaded()Publicités plein écran entre les écrans. Un intervalle minimum entre les publicités plein écran est appliqué.
FreeApp.ads.loadRewarded(unit?) / isRewardedLoaded()Précharger une publicité avec récompense.
FreeApp.ads.showRewarded(): Promise<{ok, amount, type}>Affiche une publicité avec récompense ; se résout quand l'utilisateur a gagné la récompense, est rejetée s'il la ferme trop tôt.
FreeApp.ads.privacyOptionsRequired(): boolean / showPrivacyOptions()Permet aux utilisateurs de modifier leurs choix de consentement (obligatoire dans certaines régions).
FreeApp.ads.adapterStatus(): {[network]: {installed, configured, ready, description, latencyMs}}Avec la médiation : quels réseaux partenaires sont dans l'application et lesquels votre compte AdMob a configurés.
FreeApp.ads.openAdInspector(): voidOuvre l'Ad Inspector de Google sur les appareils de test.
FreeApp.ads.on(cb: (event) => void): () => voidÉvénements publicitaires tels que initialized, bannerLoaded, interstitialDismissed ou rewardedFailed. Renvoie une fonction de désabonnement.
Avec un achat Supprimer les publicités, les bannières et les publicités plein écran s'arrêtent et l'événement adFree se déclenche. Les publicités avec récompense continuent de fonctionner, car les gens choisissent de les regarder.
Achats intégrés
Disponible quand Achats est activé dans le générateur. Vendez des produits à achat unique, des consommables comme des pièces, et des abonnements via votre propre compte Google Play. Créez d'abord les produits dans Play Console, avec les mêmes ID. Les achats fonctionnent dans une copie installée depuis Google Play : testez donc avec une piste de test et un testeur de licence.
const billing = window.FreeApp && FreeApp.billing; if (billing && billing.isOwned('pro_unlock')) unlockPro(); // Unlock in the purchase event: it also arrives for purchases finished while the app was closed. billing && billing.on(e => { if (e.event === 'purchase' && e.id === 'pro_unlock') unlockPro(); }); buyButton.onclick = async () => { try { await billing.buy('pro_unlock'); } catch (err) { if (err.code === 'pending') show('Payment pending'); else if (err.code !== 'cancelled') show('Purchase failed'); } };
FreeApp.billing.products(ids: string[]): Promise<Product[]>Les informations à jour de Google Play sur vos produits : titre, prix local, devise et, pour les abonnements, la période de facturation et les offres. Les ID que Play ne connaît pas sont ignorés.
FreeApp.billing.buy(id: string, opts?: {offer?: string}): Promise<Purchase>Ouvre la fenêtre de paiement de Google Play. Pour un abonnement, offer choisit un forfait de base ou un ID d'offre. Échoue avec une erreur dont le code est cancelled, pending, not_found, unavailable, busy, network ou developer_error.
FreeApp.billing.owned(): string[] / isOwned(id): booleanCe que l'utilisateur possède, enregistré sur le téléphone : la réponse est immédiate, même hors ligne. Utilisez-le au démarrage pour débloquer les fonctionnalités payantes.
FreeApp.billing.restore(): Promise<{purchases, owned}>Redemande à Google Play tout ce que l'utilisateur possède, pour un bouton Restaurer les achats.
FreeApp.billing.consume(idOrToken: string): PromiseConsomme un produit à achat unique pour qu'il puisse être racheté. Les produits indiqués comme consommables dans le générateur sont consommés pour vous.
FreeApp.billing.isAdFree(): booleanTrue quand l'utilisateur possède l'un des produits Supprimer les publicités définis dans le générateur. L'application arrête alors d'elle-même les bannières et les publicités plein écran.
FreeApp.billing.manageSubscriptions(id?: string): voidOuvre l'écran des abonnements de Google Play, où les utilisateurs résilient ou changent leur forfait.
FreeApp.billing.on(cb: (event) => void): () => voidÉvénements d'achat : purchase (débloquez ici), pending, owned (la liste des produits possédés a changé : un achat, un remboursement ou un abonnement expiré), failed et unavailable. Renvoie une fonction de désabonnement.
Couche de compatibilité
Les pages écrites pour d'autres outils HTML vers APK qui appellent window.AndroidAPI continuent de fonctionner : les mêmes noms de méthodes, identifiants de rappel et noms d'événements sont pris en charge, et les appels publicitaires sont sans effet dans les applications sans publicités.