Codelab su funzionalità web

Funzionalità web

Vogliamo colmare il divario di funzionalità tra il Web e il formato nativo e consentire agli sviluppatori di creare facilmente esperienze eccezionali sul Web aperto. Crediamo fermamente che tutti gli sviluppatori debbano avere accesso alle funzionalità di cui hanno bisogno per una fantastica esperienza web e ci impegniamo a rendere il Web più efficiente.

Tuttavia, alcune funzionalità, come l'accesso al file system e il rilevamento del inattività, sono disponibili per gli annunci nativi, ma non sono disponibili sul Web. Queste funzionalità mancanti indicano che alcune app non possono essere pubblicate sul Web o sono meno utili.

Progetteremo e svilupperemo queste nuove funzionalità in modo aperto e trasparente, utilizzando i processi esistenti degli standard delle piattaforme web aperte e ricevere feedback tempestivi da sviluppatori e altri fornitori di browser durante l'iterazione sulla progettazione, per garantire una progettazione interoperabile.

Cosa imparerai a realizzare

In questo codelab, disporrai di una serie di API web completamente nuove o disponibili solo dietro un flag. Pertanto, questo codelab si concentra sulle API stesse e sui casi d'uso sbloccati da queste API, anziché sulla creazione di un prodotto finale specifico.

Cosa imparerai a fare:

Questo codelab ti insegnerà le meccaniche di base di diverse API all'avanguardia. Tieni presente che questa meccanica non è ancora completamente strutturata e apprezziamo molto il tuo feedback sul flusso per gli sviluppatori.

Che cosa ti serve

Poiché le API presenti in questo codelab sono davvero all'avanguardia, i requisiti per ciascuna API variano. Assicurati di leggere attentamente le informazioni sulla compatibilità all'inizio di ogni sezione.

Come gestire il codelab

Il codelab non deve necessariamente essere elaborato in sequenza. Ogni sezione rappresenta un'API indipendente, quindi puoi scegliere liberamente quali sono gli aspetti che ti interessano maggiormente.

L'obiettivo dell'API Badging è attirare l'attenzione degli utenti su ciò che accade in background. Per semplicità della demo in questo codelab, utilizziamo l'API per attirare l'attenzione degli utenti su ciò che succede in primo piano. A questo punto puoi trasferire mentale a ciò che accade in background.

Installa Airhorner

Per utilizzare questa API, è necessaria una PWA che sia installata sulla schermata Home, pertanto il primo passaggio consiste nell'installare una PWA, come la famigerata fama mondiale airhorner.com. Fai clic sul pulsante Installa nell'angolo in alto a destra o usa il menu con tre puntini per installarla manualmente.

Verrà visualizzata una richiesta di conferma, fai clic su Installa.

Ora hai una nuova icona nel dock del sistema operativo. Fai clic sull'icona per avviare la PWA. Avrà una propria finestra dell'app e verrà eseguita in modalità autonoma.

Impostare un badge

Ora che hai installato una PWA, devi disporre di alcuni dati numerici (i badge possono contenere solo numeri) da visualizzare su un badge. Una cosa semplice da contare in The Air Horner è sight, il numero di volte in cui è stato attivato il dispositivo. In realtà, con l'app Airhorner installata, prova a suonare il clacson e a controllare il badge. Viene conteggiata una sola volta ogni volta che utilizzi il clacson.

Come funziona? Essenzialmente, il codice è il seguente:

let hornCounter = 0;
const horn = document.querySelector('.horn');
horn.addEventListener('click', () => {
  navigator.setExperimentalAppBadge(++hornCounter);
});

Suona l'airhorn un paio di volte e controlla l'icona di PWA: si aggiorna ogni volta. Ogni volta che suona. È semplicissimo.

Cancellare un badge

Il contatore arriva fino a 99 e poi ricomincia. Puoi anche reimpostarla manualmente. Apri la scheda DevTools Console, incolla la riga seguente e premi Invio.

navigator.setExperimentalAppBadge(0);

In alternativa, puoi anche eliminare il badge cancellandolo esplicitamente come illustrato nello snippet riportato di seguito. L'icona della tua PWA dovrebbe essere nuovamente visibile all'inizio, nitida e senza badge.

navigator.clearExperimentalAppBadge();

Feedback

Come ti è sembrata questa API? Aiutaci rispondendo a questo sondaggio:

Questa API era intuitiva da usare?

No

Hai ricevuto l'esempio da eseguire?

No

Hai altro da dire? Non hai fornito alcune funzionalità? Fornisci feedback rapido in questo sondaggio. Thank you!

L'API Native File System consente agli sviluppatori di creare potenti app web che interagiscono con i file sul dispositivo locale dell'utente. Dopo che un utente ha concesso l'accesso a un'app web, questa API consente alle app web di leggere o salvare le modifiche direttamente in file e cartelle sul dispositivo dell'utente.

Leggere un file

L'API Native File System di "Hello World" è quella di leggere un file locale e recuperarne i contenuti. Crea un file .txt semplice e inserisci del testo. Successivamente, accedi a un sito protetto (ovvero un sito pubblicato tramite HTTPS) come example.com e apri la console DevTools. Incolla lo snippet di codice riportato di seguito nella console. Poiché l'API Native File System richiede un gesto dell'utente, alleghiamo un gestore a doppio clic al documento. Abbiamo bisogno del gestore di file in seguito, quindi lo rendiamo una variabile globale.

document.ondblclick = async () => {
  window.handle = await window.chooseFileSystemEntries();
  const file = await handle.getFile();
  document.body.textContent = await file.text();
};

Quando fai doppio clic in qualsiasi punto della pagina example.com, viene visualizzato un selettore di file.

Seleziona il file .txt che hai creato in precedenza. Il contenuto del file andrà a sostituire i contenuti body effettivi di example.com.

Salvataggio di un file

Ora vogliamo apportare alcune modifiche. Perciò, rendiamo modificabile la variabile body incollando lo snippet di codice riportato di seguito. Ora, puoi modificare il testo come se il browser fosse un editor di testo.

document.body.contentEditable = true;

Ora vogliamo riportare queste modifiche al file originale. Di conseguenza, abbiamo bisogno di un autore nell'handle del file, che possiamo ottenere incollando lo snippet di seguito nella console. Anche in questo caso, è necessario un gesto dell'utente, che questa volta attendiamo un clic sul documento principale.

document.onclick = async () => {
  const writer = await handle.createWriter();
  await writer.truncate(0);
  await writer.write(0, document.body.textContent);
  await writer.close();
};

Quando fai clic sul documento (e non ne fai doppio clic), viene visualizzata una richiesta di autorizzazione. Quando concedi l'autorizzazione, i contenuti del file saranno le modifiche che hai modificato in body. Verifica le modifiche aprendo il file in un altro editor o riavvia il processo facendo doppio clic sul documento e riaprindo il file.

Complimenti! Hai appena creato l'editor di testo più piccolo del mondo [citation needed].

Feedback

Come ti è sembrata questa API? Aiutaci rispondendo a questo sondaggio:

Questa API era intuitiva da usare?

No

Hai ricevuto l'esempio da eseguire?

No

Hai altro da dire? Non hai fornito alcune funzionalità? Fornisci feedback rapido in questo sondaggio. Thank you!

L'API Shape Detection consente l'accesso ai rilevatori di forma accelerata (ad es. per i volti umani) e funziona con immagini statiche e/o feed di immagini in tempo reale. I sistemi operativi hanno rilevatori di funzionalità ad alte prestazioni e ottimizzati, come FaceDetector per Android. L'API Shape Detection apre queste implementazioni native e le espone tramite un set di interfacce JavaScript.

Attualmente le funzionalità supportate sono il rilevamento dei volti tramite l'interfaccia FaceDetector, il rilevamento dei codici a barre tramite l'interfaccia BarcodeDetector e il testo (riconoscimento ottico dei caratteri) tramite l'interfaccia TextDetector.

Rilevamento facciale

Una funzionalità interessante dell'API Shape Detection è il riconoscimento facciale. Per testarla, abbiamo bisogno di una pagina con i volti. Questa pagina con il volto dell'autore è un ottimo inizio. La home page avrà un aspetto simile a quello dell'immagine qui sotto. Su un browser supportato, la casella del confine del volto e i punti di riferimento del volto verranno riconosciuti.

Puoi controllare la quantità di codice necessaria per eseguire questa operazione remixando o modificando il progetto Glitch, in particolare il file script.js.

Se vuoi passare completamente a un linguaggio dinamico e non lavorare solo con il volto dell'autore, vai a questa pagina dei risultati della Ricerca Google ricca di volti in una scheda privata o in modalità ospite. Ora in questa pagina apri gli Strumenti per sviluppatori di Chrome facendo clic con il pulsante destro in qualsiasi punto e selezionando Ispeziona. Successivamente, nella scheda Console, incolla lo snippet riportato di seguito. Il codice evidenzierà i volti rilevati con una casella rossa semitrasparente.

document.querySelectorAll('img[alt]:not([alt=""])').forEach(async (img) => {
  try {
    const faces = await new FaceDetector().detect(img);
    faces.forEach(face => {
      const div = document.createElement('div');
      const box = face.boundingBox;
      const computedStyle = getComputedStyle(img);
      const [top, right, bottom, left] = [
        computedStyle.marginTop,
        computedStyle.marginRight,
        computedStyle.marginBottom,
        computedStyle.marginLeft
      ].map(m => parseInt(m, 10));
      const scaleX = img.width / img.naturalWidth;
      const scaleY = img.height / img.naturalHeight;
      div.style.backgroundColor = 'rgba(255, 0, 0, 0.5)';
      div.style.position = 'absolute';
      div.style.top = `${scaleY * box.top + top}px`;
      div.style.left = `${scaleX * box.left + left}px`;
      div.style.width = `${scaleX * box.width}px`;
      div.style.height = `${scaleY * box.height}px`;
      img.before(div);
    });
  } catch(e) {
    console.error(e);
  }
});

Vedrai che sono presenti alcuni messaggi DOMException e che non tutte le immagini sono in fase di elaborazione. Questo perché le immagini above the fold sono incorporate come URI di dati e sono quindi accessibili, mentre le immagini above the fold provengono da un dominio diverso che non è configurato per supportare CORS. Per motivi legati alla demo, non dobbiamo preoccuparci di questo aspetto.

Rilevamento dei punti di riferimento del volto

Oltre al solo volto, di per sé, macOS supporta anche il rilevamento dei punti di riferimento del volto. Per testare il rilevamento dei punti di riferimento del volto, incolla il seguente snippet nella Console. Promemoria: la linea dei punti di riferimento non è affatto perfetta a causa di crbug.com/914348, ma puoi vedere dove si sta dirigendo e quanto può essere potente questa funzionalità.

document.querySelectorAll('img[alt]:not([alt=""])').forEach(async (img) => {
  try {
    const faces = await new FaceDetector().detect(img);
    faces.forEach(face => {
      const div = document.createElement('div');
      const box = face.boundingBox;
      const computedStyle = getComputedStyle(img);
      const [top, right, bottom, left] = [
        computedStyle.marginTop,
        computedStyle.marginRight,
        computedStyle.marginBottom,
        computedStyle.marginLeft
      ].map(m => parseInt(m, 10));
      const scaleX = img.width / img.naturalWidth;
      const scaleY = img.height / img.naturalHeight;
      div.style.backgroundColor = 'rgba(255, 0, 0, 0.5)';
      div.style.position = 'absolute';
      div.style.top = `${scaleY * box.top + top}px`;
      div.style.left = `${scaleX * box.left + left}px`;
      div.style.width = `${scaleX * box.width}px`;
      div.style.height = `${scaleY * box.height}px`;
      img.before(div);

      const landmarkSVG = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
      landmarkSVG.style.position = 'absolute';
      landmarkSVG.classList.add('landmarks');
      landmarkSVG.setAttribute('viewBox', `0 0 ${img.width} ${img.height}`);
      landmarkSVG.style.width = `${img.width}px`;
      landmarkSVG.style.height = `${img.height}px`;
      face.landmarks.map((landmark) => {                    
        landmarkSVG.innerHTML += `<polygon class="landmark-${landmark.type}" points="${
        landmark.locations.map((point) => {          
          return `${scaleX * point.x},${scaleY * point.y} `;
        }).join(' ')
      }" /></svg>`;          
      });
      div.before(landmarkSVG);
    });
  } catch(e) {
    console.error(e);
  }
});

Rilevamento dei codici a barre

La seconda funzionalità dell'API Shape Detection è il rilevamento dei codici a barre. Come nel caso precedente, abbiamo bisogno di una pagina con codici a barre, come questa. Quando la apri in un browser, vengono visualizzati i vari codici QR decifrati. Esegui il remix o modifica il progetto Glitch, in particolare il file script.js per scoprire come funziona.

Se vuoi qualcosa di più dinamico, possiamo utilizzare di nuovo Google Ricerca immagini. Questa volta, nel browser, vai a questa pagina dei risultati della Ricerca Google in una scheda privata o in modalità ospite. Ora incolla lo snippet riportato di seguito nella scheda della console di Chrome DevTools. Dopo qualche istante, i codici a barre riconosciuti vengono annotati con il valore non elaborato e il tipo di codice a barre.

document.querySelectorAll('img[alt]:not([alt=""])').forEach(async (img) => {
  try {
    const barcodes = await new BarcodeDetector().detect(img);
    barcodes.forEach(barcode => {
      const div = document.createElement('div');
      const box = barcode.boundingBox;
      const computedStyle = getComputedStyle(img);
      const [top, right, bottom, left] = [
        computedStyle.marginTop,
        computedStyle.marginRight,
        computedStyle.marginBottom,
        computedStyle.marginLeft
      ].map(m => parseInt(m, 10));
      const scaleX = img.width / img.naturalWidth;
      const scaleY = img.height / img.naturalHeight;
      div.style.backgroundColor = 'rgba(255, 255, 255, 0.75)';
      div.style.position = 'absolute';
      div.style.top = `${scaleY * box.top + top}px`;
      div.style.left = `${scaleX * box.left - left}px`;
      div.style.width = `${scaleX * box.width}px`;
      div.style.height = `${scaleY * box.height}px`;
      div.style.color = 'black';
      div.style.fontSize = '14px';      
      div.textContent = `${barcode.rawValue}`;
      img.before(div);
    });
  } catch(e) {
    console.error(e);
  }
});

Rilevamento testo

La funzionalità finale dell'API Shape Detection è il rilevamento del testo. Ora sai che il trapano è importante: abbiamo bisogno di una pagina con immagini che contengano testo, come questo, con risultati di scansione di Google Libri. Sui browser supportati, il testo verrà riconosciuto e verrà visualizzato un riquadro di delimitazione intorno ai passaggi di testo. Esegui il remix o modifica il progetto Glitch, in particolare il file script.js per scoprire come funziona.

Per testarlo in modo dinamico, vai a questa pagina dei risultati di ricerca in una scheda privata o in modalità ospite. Ora incolla lo snippet riportato di seguito nella scheda della console di Chrome DevTools. Con un po' di attesa, una parte del testo verrà riconosciuta.

document.querySelectorAll('img[alt]:not([alt=""])').forEach(async (img) => {
  try {
    const texts = await new TextDetector().detect(img);
    texts.forEach(text => {
      const div = document.createElement('div');
      const box = text.boundingBox;
      const computedStyle = getComputedStyle(img);
      const [top, right, bottom, left] = [
        computedStyle.marginTop,
        computedStyle.marginRight,
        computedStyle.marginBottom,
        computedStyle.marginLeft
      ].map(m => parseInt(m, 10));
      const scaleX = img.width / img.naturalWidth;
      const scaleY = img.height / img.naturalHeight;
      div.style.backgroundColor = 'rgba(255, 255, 255, 0.75)';
      div.style.position = 'absolute';
      div.style.top = `${scaleY * box.top + top}px`;
      div.style.left = `${scaleX * box.left - left}px`;
      div.style.width = `${scaleX * box.width}px`;
      div.style.height = `${scaleY * box.height}px`;
      div.style.color = 'black';
      div.style.fontSize = '14px';      
      div.innerHTML = text.rawValue;
      img.before(div);
    });
  } catch(e) {
    console.error(e);
  }
});

Feedback

Come ti è sembrata questa API? Aiutaci rispondendo a questo sondaggio:

Questa API era intuitiva da usare?

No

Hai ricevuto l'esempio da eseguire?

No

Hai altro da dire? Non hai fornito alcune funzionalità? Fornisci feedback rapido in questo sondaggio. Thank you!

L'API Web Share Target consente alle app web installate di registrarsi con il sistema operativo sottostante come target di condivisione per ricevere contenuti condivisi dall'API Web Share o dagli eventi di sistema, ad esempio il pulsante di condivisione a livello di sistema operativo.

Installa una PWA da condividere con

Come primo passaggio, hai bisogno di una PWA da condividere. Questa volta, Airhorner (fortunatamente) non ha fatto il lavoro, ma ti serve l'app demo Condividi sul Web. Installa l'app sulla schermata Home del dispositivo.

Condividere contenuti con la PWA

Devi condividere qualcosa, ad esempio una foto di Google Foto. Utilizza il pulsante Condividi e seleziona Scrapbook PWA come target di condivisione.

Quando tocchi l'icona dell'app, viene visualizzata direttamente la Scrapbook PWA, dove la foto è proprio lì.

Come funziona? Per scoprirlo, esplora il file manifest dell'app web di Scrapbook PWA. La configurazione per il funzionamento dell'API Web Share Target si trova nella proprietà "share_target" del manifest, che nel campo "action" rimanda a un URL decorato con i parametri elencati in "params".

Il lato di condivisione, poi, viene compilato di conseguenza (questo modello viene facilitato da un'azione di condivisione o controllato in modo programmatico dallo sviluppatore utilizzando l'API Web Share), in modo che il lato ricevente possa estrarre i parametri ed eseguire operazioni con essi, ad esempio visualizzarli.

{
  "action": "/_share-target",
  "enctype": "multipart/form-data",
  "method": "POST",
  "params": {
    "files": [{
      "name": "media",
      "accept": ["audio/*", "image/*", "video/*"]
    }]
  }
}

Feedback

Come ti è sembrata questa API? Aiutaci rispondendo a questo sondaggio:

Questa API era intuitiva da usare?

No

Hai ricevuto l'esempio da eseguire?

No

Hai altro da dire? Non hai fornito alcune funzionalità? Fornisci feedback rapido in questo sondaggio. Thank you!

Per evitare di scaricare la batteria, la maggior parte dei dispositivi entra rapidamente in modalità di sospensione quando il dispositivo è inattivo. Nella maggior parte dei casi non è un problema, ma alcune applicazioni devono mantenere lo schermo o il dispositivo attivo per poter completare il lavoro. L'API Wake Lock offre un modo per evitare che il dispositivo si oscura e blocchi lo schermo, oppure per evitare che il dispositivo entri in modalità di sospensione. Questa funzionalità consente nuove esperienze che prima richiedevano un'app nativa.

Configurare un salvaschermo

Per testare l'API Wake Lock, devi prima assicurarti che il tuo dispositivo venga disattivato. Pertanto, nel riquadro delle preferenze del tuo sistema operativo, attiva un salvaschermo che preferisci e assicurati che inizi dopo un minuto. Assicurati che funzioni lasciando il dispositivo solo per quell'ora (sì, mi dispiace! Gli screenshot riportati di seguito mostrano macOS, ma puoi ovviamente provare a farlo sul tuo dispositivo mobile Android o su qualsiasi piattaforma desktop supportata.

Impostare un wakelock dello schermo

Ora che sai che il salvaschermo funziona, utilizzerai un wakelock di tipo "screen" per evitare che il salvaschermo esegua il suo lavoro. Vai all'app demo Wake Lock e fai clic sulla casella di controllo Attiva screen Wake Lock.

A partire da quel momento, sarà attivo un wakelock. Se sei abbastanza paziente da lasciare il dispositivo intatto per un minuto, ora vedrai che il salvaschermo non è effettivamente iniziato.

Come funziona? Per scoprirlo, vai al progetto Glitch per l'app demo di Wake Lock e controlla script.js. Il contenuto del codice è riportato nello snippet di seguito. Apri una nuova scheda (o utilizza qualsiasi scheda che hai aperto) e incolla il codice riportato di seguito in una console degli Strumenti per sviluppatori di Chrome. Quando fai clic sulla finestra, dovresti vedere un wakelock attivo per esattamente 10 secondi (vedi i log della console) e il salvaschermo non deve iniziare.

if ('wakeLock' in navigator && 'request' in navigator.wakeLock) {  
  let wakeLock = null;
  
  const requestWakeLock = async () => {
    try {
      wakeLock = await navigator.wakeLock.request('screen');
      wakeLock.addEventListener('release', () => {        
        console.log('Wake Lock was released');                    
      });
      console.log('Wake Lock is active');      
    } catch (e) {      
      console.error(`${e.name}, ${e.message}`);
    } 
  };

  requestWakeLock();
  window.setTimeout(() => {
    wakeLock.release();
  }, 10 * 1000);
}

Feedback

Come ti è sembrata questa API? Aiutaci rispondendo a questo sondaggio:

Questa API era intuitiva da usare?

No

Hai ricevuto l'esempio da eseguire?

No

Hai altro da dire? Non hai fornito alcune funzionalità? Fornisci feedback rapido in questo sondaggio. Thank you!

Un'API che siamo molto entusiasti è l'API Contact Picker. Consente a un'app web di accedere ai contatti dalla Gestione contatti nativa del dispositivo affinché l'app abbia accesso ai nomi, agli indirizzi email e ai numeri di telefono dei tuoi contatti. Puoi specificare se vuoi solo uno o più contatti e se tutti i campi o solo un sottoinsieme di nomi, indirizzi email e numeri di telefono.

Considerazioni sulla privacy

Una volta aperto il selettore, puoi selezionare i contatti che vuoi condividere. Come potrai notare, non esiste un'opzione "Seleziona tutto", che è deliberata: vogliamo che la condivisione sia una decisione consapevole. Analogamente, l'accesso non è continuo, ma è una decisione una tantum.

Accesso ai contatti

L'accesso ai contatti è un'attività semplice. Prima dell'apertura del selettore, puoi specificare i campi che preferisci (le opzioni sono name, email e telephone) e se vuoi accedere a più contatti o a un solo contatto. Puoi testare questa API su un dispositivo Android aprendo l'applicazione demo. La sezione pertinente del codice sorgente è essenzialmente lo snippet riportato di seguito:

getContactsButton.addEventListener('click', async () => {
  const contacts = await navigator.contacts.select(
      ['name', 'email'],
      {multiple: true});
  if (!contacts.length) {
    // No contacts were selected, or picker couldn't be opened.
    return;
  }
  console.log(contacts);
});

Copiare e incollare testo

Finora non era possibile copiare e incollare le immagini negli appunti del sistema in modo programmatico. Di recente abbiamo aggiunto il supporto per le immagini all'API Async Clipboard,

in modo da poter copiare e incollare immagini. La cosa nuova è che puoi anche scrivere immagini negli appunti. Per un po' di tempo, l'API asincrona degli appunti supportava la copia e incolla di testo. Puoi copiare il testo negli appunti chiamando navigator.clipboard.writeText() e, successivamente, incolla il testo richiamando navigator.clipboard.readText().

Copiare e incollare immagini

Ora puoi anche scrivere immagini negli appunti. Affinché questo metodo funzioni, devi utilizzare i dati immagine come blob da trasmettere al costruttore degli elementi degli appunti. Infine, puoi copiare questo elemento degli appunti chiamando navigator.clipboard.write().

// Copy: Writing image to the clipboard
try {
  const imgURL = 'https://developers.google.com/web/updates/images/generic/file.png';
  const data = await fetch(imgURL);
  const blob = await data.blob();
  await navigator.clipboard.write([
    new ClipboardItem(Object.defineProperty({}, blob.type, {
      value: blob,
      enumerable: true
    }))
  ]);
  console.log('Image copied.');
} catch(e) {
  console.error(e, e.message);
}

Incollare l'immagine dagli appunti sembra molto semplice, ma in realtà consiste semplicemente nel recuperare il blob dall'elemento degli appunti. Poiché possono esistere più combinazioni, devi eseguirne il loop fino a quando non trovi quello che ti interessa. Per motivi di sicurezza, al momento questo è limitato alle immagini PNG, ma in futuro potrebbero essere supportati altri formati delle immagini.

async function getClipboardContents() {
  try {
    const clipboardItems = await navigator.clipboard.read();
    for (const clipboardItem of clipboardItems) {
      try {
        for (const type of clipboardItem.types) {
          const blob = await clipboardItem.getType(type);
          console.log(URL.createObjectURL(blob));
        }
      } catch (e) {
        console.error(e, e.message);
      }
    }
  } catch (e) {
    console.error(e, e.message);
  }
}

Puoi vedere questa API in azione in un'app demo; gli snippet pertinenti del suo codice sorgente sono incorporati sopra. La copia delle immagini negli appunti può essere eseguita senza autorizzazione, ma è necessario concedere l'accesso per incollare dagli appunti.

Dopo aver concesso l'accesso, puoi leggere l'immagine dagli appunti e incollarla nell'applicazione:

Congratulazioni, hai raggiunto la fine del codelab. Anche in questo caso, vogliamo ricordarti che la maggior parte delle API è ancora attiva e viene utilizzata attivamente. Pertanto, il team apprezza molto il tuo feedback, poiché solo l'interazione con persone come te ci aiuterà a rendere corrette queste API.

Ti invitiamo inoltre a consultare spesso la nostra pagina di destinazione delle funzionalità. Terremo aggiornato il documento e contiene suggerimenti su tutti gli articoli approfonditi relativi alle API su cui lavoriamo. Continua così!

Tom e l'intero team di funzionalità 🐡