Saltare al contenuto principale

Come utilizzare Gemini Nano in un'app Capacitor

Utilizzare Gemini Nano in un'app Capacitor per l'intelligenza artificiale su dispositivo Android: supporto dispositivo, verifiche AICore, streaming con @capgo/capacitor-llm e un fallback Gemma.

Crediti dell'articolo

Martino Donadieu

Autore

Valeria

Recensore

Jordan

Curatore

Come utilizzare Gemini Nano in un'app Capacitor

Per utilizzare Gemini Nano in un'app Capacitor, installa @capgo/capacitor-llmchiamare setModel({ path: 'Gemini Nano' }) su Android, quindi crea una chat e trasmetti la risposta attraverso il textFromAi l'evento. Il plugin parla con Gemini Nano attraverso il kit di Google ML GenAI Prompts API, che esegue il modello all'interno del sistema di servizio AICore di Android, quindi il testo non lascia mai il telefono.

Questa guida copre come funziona Gemini Nano, quali dispositivi lo supportano, le chiamate plugin esatte, il flusso, le quote e i limiti, un fallback Gemma per i telefoni non supportati e come lo stesso code raggiunge l'intelligenza Apple su iOS.

Come funziona Gemini Nano su Android

Gemini Nano è il modello Gemini più piccolo di Google, progettato per i telefoni. Gli app non lo integrano. AICore servizio scarica, aggiorna e esegue l'inferenza, e le app raggiungono tramite il Kit di apprendimento ML GenAI API:

  • Prompt API: testi di input liberi da forma, il API utilizzato da questo plugin (com.google.mlkit:genai-prompt).
  • Funzionalità API: Compiti fissi come la riassunzione, la correzione di bozze, la riscrittura e la descrizione di immagini.

Google ships the Prompt API as a beta, without an SLA or deprecation policy, so expect behavior changes between releases and keep the integration behind your own small wrapper.

Poiché l'inferenza è locale, ottenete tre cose che un modello cloud non può offrire: funziona in modalità offline, non ha un costo per token e il testo dell'utente rimane sul dispositivo. Il trade-off è un modello più piccolo con un contesto e un output brevi, quindi scegliere compiti che si adattino: riscrittura, riassunto di una nota, classificazione di un messaggio, estrazione di campi, redazione di risposte brevi.

Dispositivi e requisiti supportati

Google pubblica la lista dei dispositivi supportati per API sul sito ML Kit GenAI, raggruppati per versione di Gemini Nano (nano-v2, nano-v3, nano-v4). Per il Prompt API copre il Pixel 9 e successivi, recenti Samsung Galaxy S e Z flagship, e recenti flagship di OnePlus, OPPO, Xiaomi, vivo, Honor, realme, Motorola e altri. Controlla la lista in tempo reale prima di promettere una funzionalità a un dispositivo specifico.

Ogni dispositivo supportato ha anche bisogno di:

Requisito Dettaglio
Versione di Android API livello 26 o superiore (il plugin controlla questo)
Bootloader Chiuso. Google non supporta le API GenAI su bootloader sbloccati
AICore Presente e configurato. Dopo una configurazione o un reset del dispositivo può volerci un po' di tempo per completare
Stato dell'app L'applicazione deve essere l'applicazione di primo piano durante l'inferenza.

Diversi modelli Nano possono restituire output diversi per la stessa richiesta. Testa le tue richieste su almeno un dispositivo per ogni versione che ti interessa.

Installa il plugin

bun add @capgo/capacitor-llm
bunx cap sync

Il plugin segue la versione maggiore di Capacitor: utilizza 8.x con Capacitor 8. Non sono necessarie modifiche al manifesto Android per Gemini Nano. Riferimento completo: plugin docs e pagina del plugin.

Passo 1: Carica Gemini Nano e controlla la prontezza

setModel con la percorso speciale 'Gemini Nano' chiede a ML Kit lo stato del modello. Risolve quando lo stato è disponibile e rifiuta altrimenti, con un messaggio che include lo stato:

Stato da AICore Comportamento del plugin
disponibile setModel risolve readinessChange emette ready
scaricabile Rifiuta: “Gemini Nano è scaricabile ma non scaricato su questo dispositivo”
in fase di download Rifiuta con lo stato di download
non disponibile Rifiuta: “Gemini Nano non è disponibile su questo dispositivo”
import { Capacitor } from '@capacitor/core';
import { CapgoLLM } from '@capgo/capacitor-llm';

export async function loadGeminiNano(): Promise<boolean> {
  if (Capacitor.getPlatform() !== 'android') return false;

  try {
    await CapgoLLM.setModel({
      path: 'Gemini Nano',
      temperature: 0.3,
      topk: 16,
    });
  } catch (error) {
    console.warn('Gemini Nano not ready:', error);
    return false;
  }

  const { readiness } = await CapgoLLM.getReadiness();
  return readiness === 'ready';
}

Il plugin non avvia il download del modello AICore da solo. Se un dispositivo segnala che è scaricabile, il modello arriva di solito dopo che un'altra app o il sistema lo richiede, quindi controlla nuovamente in una sessione successiva anziché nascondere la funzionalità permanentemente.

Passo 2: Crea un chat e trasmetti la risposta

A un chat si conserva la storia della conversazione. Su Android, sendMessage si risolve non appena inizia la generazione e il testo arriva attraverso gli eventi. Avvolgilo in una promessa che si risolve su aiFinished:

import { CapgoLLM } from '@capgo/capacitor-llm';

// Android sends deltas. iOS Apple Intelligence sends the full text so far.
// This merge handles both.
function mergeChunk(current: string, chunk: string) {
  return chunk.startsWith(current) ? chunk : current + chunk;
}

export async function ask(
  chatId: string,
  message: string,
  onText: (textSoFar: string) => void,
): Promise<string> {
  let text = '';
  let finish!: (value: string) => void;
  let fail!: (error: Error) => void;
  const done = new Promise<string>((resolve, reject) => {
    finish = resolve;
    fail = reject;
  });

  const handles = await Promise.all([
    CapgoLLM.addListener('textFromAi', (event) => {
      if (event.chatId !== chatId) return;
      text = mergeChunk(text, event.text);
      onText(text);
    }),
    CapgoLLM.addListener('aiFinished', (event) => {
      if (event.chatId === chatId) finish(text);
    }),
    CapgoLLM.addListener('generationError', (event) => {
      if (!event.chatId || event.chatId === chatId) fail(new Error(event.error));
    }),
  ]);

  // If the app is backgrounded mid-answer, neither event may arrive
  const timeout = setTimeout(() => fail(new Error('Generation timed out')), 60_000);

  try {
    await CapgoLLM.sendMessage({ chatId, message });
    return await done;
  } finally {
    clearTimeout(timeout);
    await Promise.all(handles.map((h) => h.remove()));
  }
}

Utilizzalo per una funzione reale, ad esempio la stesura di una risposta a una recensione di un cliente:

const INSTRUCTIONS =
  'You write short, polite replies to customer reviews for a small shop. ' +
  'Answer each point, stay under 60 words, never promise refunds.';

export async function draftReply(review: string, render: (t: string) => void) {
  const { id } = await CapgoLLM.createChat();
  return ask(id, `${INSTRUCTIONS}\n\nReview:\n${review}\n\nReply:`, render);
}

createChat() non accetta alcuna opzione, quindi metti le istruzioni all'inizio del primo messaggio. Crea un nuovo chat per ogni compito. Sulla via Gemini Nano il plugin conserva la storia in memoria e la invia con ogni messaggio, quindi le lunghe chat utilizzano velocemente il budget di input.

Limiti da progettare per

Limite Valore Cosa fare
Input Sotto i circa 4.000 token per richiesta (Google) Conserva le chat brevi, taglia i documenti lunghi
Output Il plugin limita le risposte di Gemini Nano a 256 token Richiedi output brevi, suddividi compiti lunghi
Anteriore Eseguire l'inferenza solo quando l'app è in primo piano Non eseguirlo mai dalle attività di background
Quota Quoti per applicazione, BUSY errori di batteria e quote Evita la generazione ad ogni singolo tasto premuto
Concurrency Una generazione per chat Disabilita il pulsante di invio durante la trasmissione
Velocità Pochi secondi per un paragrafo Flusso costante verso l'interfaccia utente

Tratta un errore di quota come temporaneo. Mostra un'opzione di riprova invece di un dialogo di errore.

Fallback: Gemma 4 quando Gemini Nano è assente

La maggior parte dei telefoni Android in uso oggi non dispone di Gemini Nano. Lo stesso plugin può eseguire modelli Gemma aperti tramite LiteRT-LM, quindi conserva uno API. Il modello è grande, spesso supera un gigabyte, quindi scaricalo solo dopo che l'utente ha optato per l'opzione, idealmente su Wi-Fi.

import { Preferences } from '@capacitor/preferences';
import { CapgoLLM } from '@capgo/capacitor-llm';

const GEMMA_URL =
  'https://huggingface.co/litert-community/gemma-4-E2B-it-litert-lm/resolve/main/gemma-4-E2B-it.litertlm?download=true';

export async function loadGemma(onProgress: (pct: number) => void) {
  const saved = await Preferences.get({ key: 'gemmaPath' });
  if (saved.value) {
    try {
      await CapgoLLM.setModel({ path: saved.value, modelType: 'litertlm', maxTokens: 4096 });
      return;
    } catch {
      // File missing or corrupt, download again
    }
  }

  const sub = await CapgoLLM.addListener('downloadProgress', (e) => onProgress(e.progress));
  try {
    const { path } = await CapgoLLM.downloadModel({
      url: GEMMA_URL,
      filename: 'gemma-4-E2B-it.litertlm',
    });
    await Preferences.set({ key: 'gemmaPath', value: path });
    await CapgoLLM.setModel({ path, modelType: 'litertlm', maxTokens: 4096 });
  } finally {
    await sub.remove();
  }
}

Seleziona poi l'engine all'avvio:

export async function initOnDeviceAI(userAcceptedDownload: boolean, onProgress: (p: number) => void) {
  if (await loadGeminiNano()) return 'gemini-nano';
  if (userAcceptedDownload) {
    await loadGemma(onProgress);
    return 'gemma';
  }
  return 'none';
}

Se nessuna delle due opzioni è possibile, nascondi la funzione o chiama un modello cloud. Non bloccare i flussi core sulle AI locali.

Lo stesso code su iOS

Sul iOS il plugin utilizza l'Intelligenza Apple attraverso il framework dei Modelli Fondamentali. Cambia una riga:

await CapgoLLM.setModel({ path: 'Apple Intelligence' });

createChat, sendMessage, e gli eventi rimangono gli stessi, e il mergeChunk il nostro helper sopra già gestisce il formato di streaming iOS. Le richieste del dispositivo differiscono (iOS 26 e un dispositivo capace di Apple Intelligence). Intelligenza Apple in un'app Capacitor copre quella parte.

Test

  • Usa un telefono reale supportato. Gli emulatori non forniscono AICore con Gemini Nano.
  • Logga il setModel messaggio di rifiuto. Ti dice esattamente quale stato AICore riporta.
  • Sulla dispositivo appena configurato o resettato, aspetta che AICore finisca la sua configurazione iniziale mentre è online, quindi riprova.
  • Testa le tue richieste sul Nano più basso che supporti. Le richieste più brevi e esplicite sono più stabili across versioni.

Risolvere i problemi

“Gemini Nano non è disponibile su questo dispositivo.” Il dispositivo non è nella lista di Google, il bootloader non è bloccato o AICore non è stato configurato ancora.

“Gemini Nano è scaricabile ma non scaricato”. Il dispositivo supporta ma il modello non è presente. Offri il fallback Gemma o riprova più tardi.

“Sessione di chat non trovata”. Hai chiamato sendMessage con una chat creata prima di una nuova setModel. Caricare un modello cancella le chat esistenti, quindi crea una nuova.

“Modello non pronto”. setModel non riuscito o non è stato chiamato prima createChat.

L'output si ferma a metà frase. Hai raggiunto il limite dell'output. Chiedi una risposta più breve o suddividi il compito.

Errori quando l'app va in background. Inference is foreground-only. Cancel UI state on pause and let the user retry.

Privacy e recensione del negozio

Promozioni e risposte rimangono sul dispositivo con Gemini Nano, che semplifica la tua forma di sicurezza dei dati. I termini di Google ML Kit menzionano ancora la elaborazione dei metrici, quindi descrivi l'uso dell'AI sul dispositivo nella tua politica di privacy. Se aggiungi il fallback Gemma, il download del modello proviene da Hugging Face, quindi menziona anche quella richiesta di rete.

Prompiti e copia dell'interfaccia per le funzionalità AI cambiano spesso. Se hai bisogno di regolarli dopo la rilascio, Capgo aggiornamenti in tempo reale ti consentono di spedire nuove web code senza dover aspettare la revisione della store. Per una visione più ampia dell'AI nelle applicazioni ibride, leggi perché Capacitor funziona bene per le applicazioni mobili AI.

Conclusione

Gemini Nano offre alle applicazioni Capacitor una generazione di testo privata e gratuita, offline, su dispositivi Android supportati. Caricane con setModel({ path: 'Gemini Nano' })flusso attraverso textFromAimantenere le promozioni e gli output brevi, rispettare le regole di foreground e quota e mantenere un fallback Gemma o cloud per i molti dispositivi che non lo hanno.

Aggiornamenti in tempo reale per le app Capacitor

When a web-layer bug is live, ship the fix through Capgo instead of waiting days for app store approval. Users get the update in the background while native changes stay in the normal review path.

Ultimi dalla nostra Blog

Capgo vi offre le migliori informazioni che avete bisogno per creare un'app mobile davvero professionale.