API JavaScript
Apps criados com o Free HTML to APK injetam uma ponte nativa como window.FreeApp. Chame-a em JavaScript puro, em React ou Vue, ou em um motor de jogos. Sua página continua funcionando em um navegador comum se você proteger as chamadas.
Primeiros passos
A ponte pode chegar um instante depois da execução dos seus scripts; por isso, faça a configuração nativa no evento freeappready e também imediatamente, caso window.FreeApp já exista. Sempre ofereça uma alternativa para o navegador.
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');
As chamadas que exigem permissão (câmera, microfone, localização, notificações) pedem autorização ao usuário na primeira vez. Ative a permissão correspondente na etapa Permissões do builder; os modelos ativam o que o código deles usa.
Feedback e interface
FreeApp.brightness(level: number): voidDe 0.0 a 1.0 para esta janela; um valor negativo restaura o brilho do sistema.
FreeApp.fullscreen(on: boolean): voidOcultar as barras do sistema (imersivo).
FreeApp.keepAwake(on: boolean): voidManter a tela ligada.
FreeApp.notify(title: string, body?: string): voidNotificação local instantânea (pede permissão no Android 13+).
FreeApp.orientation(value: 'portrait' | 'landscape' | 'sensor_portrait' | 'sensor_landscape' | 'sensor' | 'unspecified'): voidFreeApp.print(): voidImprimir / salvar a página como PDF.
FreeApp.scheduleNotification(title: string, body: string, delayMs: number, opts?: {id?: number, url?: string, repeatMs?: number, exact?: boolean}): numberRetorna o id.
FreeApp.speak(text: string, lang?: string): voidTexto para fala nativo, com idioma como 'pt-BR'.
FreeApp.statusBar(hexColor: string): voidEx.: '#2563EB'.
FreeApp.stopSpeaking(): voidFreeApp.toast(message: string): voidToast nativo curto.
FreeApp.vibrate(ms?: number | number[]): voidUma vibração única (padrão 50 ms) ou um padrão [desligado, ligado, desligado, ligado…].
Câmera e leitura
FreeApp.camera.capture(opts?: {maxSize?: number, quality?: number, mirror?: boolean}): Promise<{dataUrl, facing}>Foto estática a partir da pré-visualização em execução.
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}>Nativo, rápido em celulares básicos.
FreeApp.saveToGallery(dataUrl: string, fileName?: string): Promise<{uri}>Salva uma imagem em Fotos.
FreeApp.scanCode(opts?: {formats?: string[] /* e.g. ['QR_CODE','EAN_13','CODE_128'] */, facing?: 'back' | 'front'}): Promise<{text, format}>Leitor nativo de QR / código de barras em tela cheia, com lanterna; rejeita com 'cancelled'.
FreeApp.torch(on: boolean): booleanLanterna; retorna false se não houver flash.
Localização e sensores
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) | nullRetorna uma função de parada.
FreeApp.location(opts?: {maxAge?: number}): Promise<{lat, lng, accuracy, altitude, speed, provider, time, fromLastKnown}>FreeApp.maps(query: string): voidAbre um lugar ou "lat,lng" no app de mapas.
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) | nullRetorna uma função de parada, ou null se não estiver disponível.
FreeApp.sensors.stop(type: string): voidFreeApp.watchLocation(cb: (p) => void, opts?: {interval?: number, distance?: number}): () => voidRetorna uma função de parada.
Dispositivo e app
FreeApp.app(): {packageName, versionName, versionCode, name, firstInstall}FreeApp.battery(): {level: number /* 0-100 */, charging: boolean}FreeApp.biometric(title: string, subtitle?: string): Promise<boolean>Desbloqueio por impressão digital / rosto.
FreeApp.device(): {manufacturer, model, brand, androidVersion, sdkInt, language, screenWidth, screenHeight, density, isTablet, darkMode}FreeApp.launchUrl(): string | nullO deep link que abriu o app.
FreeApp.network(): 'wifi' | 'cellular' | 'ethernet' | 'vpn' | 'other' | 'none' | 'unknown'FreeApp.on('deeplink', (d: {url}) => void): () => voidLinks abertos enquanto o app está em execução.
FreeApp.online(): booleanArquivos, compartilhamento e armazenamento
FreeApp.copy(text: string): voidCopiar para a área de transferência.
FreeApp.open(url: string): voidAbrir no navegador / app externo.
FreeApp.paste(): stringLer o texto da área de transferência.
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>Salva em Downloads; FreeApp.on('saved', d => …) retorna {name, ok, location}.
FreeApp.store.get(key: string): any | nullFreeApp.store.set(key: string, value: any): voidArmazenamento nativo persistente de chave/valor (JSON).
NFC
FreeApp.nfc.read(): Promise<{tagId, techs: string[], writable, maxSize, records: Array<{type: "text" | "uri" | "mime" | "unknown", value, mime?, lang?}>}>Espera por uma tag; FreeApp.nfc.stop() cancela.
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}>Permissões
FreeApp.hasPermission(name: string): booleanFreeApp.openSettings(): voidAbre a página de configurações do sistema para este app.
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}>Anúncios
Disponível quando o AdMob está ativado no builder. No modo de teste, são exibidos os anúncios de teste do Google.
FreeApp.ads.loadBanner(unit?: string, position?: 'top' | 'bottom'): voidCarrega e exibe um banner. Sem argumentos, usa o bloco e a posição definidos no builder.
FreeApp.ads.showBanner(position?) / hideBanner() / isBannerLoaded()Mostrar, ocultar ou verificar o banner.
FreeApp.ads.loadInterstitial(unit?) / showInterstitial() / isInterstitialLoaded()Anúncios em tela cheia entre telas. Há um intervalo mínimo obrigatório entre anúncios em tela cheia.
FreeApp.ads.loadRewarded(unit?) / isRewardedLoaded()Pré-carregar um anúncio premiado.
FreeApp.ads.showRewarded(): Promise<{ok, amount, type}>Exibe um anúncio premiado; resolve quando o usuário ganha a recompensa e rejeita se ele fechar antes.
FreeApp.ads.privacyOptionsRequired(): boolean / showPrivacyOptions()Permite que os usuários alterem suas escolhas de consentimento (obrigatório em algumas regiões).
FreeApp.ads.adapterStatus(): {[network]: {installed, configured, ready, description, latencyMs}}Com mediação: quais redes parceiras estão dentro do app e quais sua conta do AdMob configurou.
FreeApp.ads.openAdInspector(): voidAbre o Ad Inspector do Google em dispositivos de teste.
FreeApp.ads.on(cb: (event) => void): () => voidEventos de anúncios como initialized, bannerLoaded, interstitialDismissed ou rewardedFailed. Retorna uma função para cancelar a inscrição.
Com uma compra de Remover anúncios, os anúncios de banner e em tela cheia param e o evento adFree é disparado. Os anúncios premiados continuam funcionando, porque as pessoas escolhem assisti-los.
Compras no app
Disponível quando Compras está ativado no builder. Venda produtos de compra única, consumíveis como moedas e assinaturas pela sua própria conta do Google Play. Crie os produtos no Play Console primeiro, com os mesmos IDs. As compras funcionam em uma cópia instalada pelo Google Play, então teste com uma faixa de teste e um testador de licença.
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[]>Os detalhes ao vivo do Google Play sobre seus produtos: título, preço local, moeda e, para assinaturas, o período de cobrança e as ofertas. IDs que o Play não conhece ficam de fora.
FreeApp.billing.buy(id: string, opts?: {offer?: string}): Promise<Purchase>Abre a tela de pagamento do Google Play. Para uma assinatura, offer escolhe um plano básico ou um ID de oferta. Rejeita com um erro cujo código é cancelled, pending, not_found, unavailable, busy, network ou developer_error.
FreeApp.billing.owned(): string[] / isOwned(id): booleanO que o usuário possui, salvo no celular, então responde na hora e offline. Use na inicialização para liberar os recursos pagos.
FreeApp.billing.restore(): Promise<{purchases, owned}>Pede de novo ao Google Play tudo o que o usuário possui, para um botão Restaurar compras.
FreeApp.billing.consume(idOrToken: string): PromiseConsome um produto de compra única para que possa ser comprado de novo. Os produtos marcados como consumíveis no builder são consumidos automaticamente.
FreeApp.billing.isAdFree(): booleanTrue quando o usuário possui um dos produtos Remover anúncios definidos no builder. O app então para sozinho os anúncios de banner e em tela cheia.
FreeApp.billing.manageSubscriptions(id?: string): voidAbre a tela de assinaturas do Google Play, onde os usuários cancelam ou mudam o plano.
FreeApp.billing.on(cb: (event) => void): () => voidEventos de compra: purchase (libere aqui), pending, owned (a lista do que o usuário possui mudou: uma compra, um reembolso ou uma assinatura expirada), failed e unavailable. Retorna uma função para cancelar a inscrição.
Camada de compatibilidade
Páginas escritas para outras ferramentas de HTML para APK que chamam window.AndroidAPI continuam funcionando: os mesmos nomes de métodos, IDs de callback e nomes de eventos são compatíveis, e as chamadas de anúncios são inofensivas em apps sem anúncios.