Novidades da Web no Google Play

Desde que a Atividade Confiável na Web foi lançada no ano passado, a equipe do Chrome continua trabalhando na , o que facilita o uso com o Bubblewrap, adicionando novos recursos, como o novo Google Play Integração do faturamento e ativação dele em mais plataformas, como o ChromeOS. Neste artigo, resumir as atualizações mais recentes e futuras da Atividade Confiável na Web.

Novos recursos de bolhas e de Atividade confiável na Web

O Bubblewrap ajuda você a criar apps que iniciam seus PWAs dentro de uma Atividade confiável na Web, sem exigindo conhecimento de ferramentas específicas da plataforma.

Fluxo de configuração simplificado

Antes, era preciso configurar manualmente o Java Development Kit e o Android para usar o Bubblewrap. SDK do Cloud, ambos suscetíveis a erros. A ferramenta agora oferece o download automático de dependências ao serem executados pela primeira vez.

Você ainda pode optar por usar uma instalação existente das dependências, se preferir. e o novo comando doctor ajuda a encontrar problemas e recomenda correções para a configuração, o que pode serão atualizadas na linha de comando usando o comando updateConfig.

Assistente aprimorado

Ao criar um projeto com o init, o Bubblewrap precisa de informações para gerar o app Android. A extrai valores do manifesto do app da Web e fornece padrões quando possível.

É possível alterar esses valores ao criar um novo projeto, mas anteriormente o significado de cada campo não era claras. As caixas de diálogo de inicialização foram recriadas com descrições e validação melhores para cada campo de entrada.

display: suporte para tela cheia e orientação

Em alguns casos, você pode querer que seu aplicativo use o máximo possível da tela e, quando criando PWAs. Isso é implementado definindo o campo display no manifesto do app da Web como fullscreen.

Quando o balão detecta a opção de tela cheia no manifesto do app da Web, ele configura o ambiente seja iniciado em tela cheia, ou modo imersivo, em termos específicos do Android.

O campo orientation do manifesto do app da Web define se o aplicativo deve ser iniciado modo retrato, paisagem ou na orientação que o dispositivo está usando no momento. Embalagem de bolha agora lê o campo "Manifesto do app da Web" e o usa como padrão ao criar o app Android.

É possível personalizar as duas configurações como parte do fluxo de bubblewrap init.

Saída de AppBundles

Pacotes de apps é um formato de publicação para apps que delega a geração final de APKs e como assinar o Google Play. Na prática, isso permite que arquivos menores sejam veiculados aos usuários durante o download do app na loja.

Agora o Bubblewrap empacota o aplicativo como um App Bundle, em um arquivo chamado app-release-bundle.aab: Recomendamos esse formato ao publicar apps na Play Store porque isso será exigido pela loja a partir do segundo semestre de 2021.

Delegação de geolocalização

Os usuários esperam que os aplicativos instalados nos dispositivos se comportem de forma consistente, independentemente da a tecnologia. Quando usada dentro de uma Atividade Confiável na Web, a permissão GeoLocation agora pode ser delegados ao sistema operacional e, quando ativados, os usuários veem as mesmas caixas de diálogo dos apps criados com Kotlin ou Java e encontre controles para gerenciar a permissão no mesmo lugar.

O recurso pode ser adicionado pelo Bubblewrap e, como adiciona dependências extras ao Android, você só deve ativá-lo quando o app da Web estiver usando a permissão de geolocalização.

Binários otimizados

Os dispositivos com armazenamento limitado são comuns em certas áreas do mundo e os proprietários deles costumam preferir aplicativos menores. Os aplicativos que usam Atividade na Web Confiável produzem binários, o que elimina um pouco da ansiedade desses usuários.

O Bubblewrap foi otimizado reduzindo a lista de bibliotecas Android necessárias, resultando em gerados binários que são 800 mil menores. Na prática, isso é menos da metade do tamanho médio geradas por versões anteriores. Para aproveitar os binários menores, basta atualizar seu app usando a versão mais recente do Bubblewrap.

Como atualizar um app

Um aplicativo gerado pelo Bubblewrap é composto por um aplicativo da Web e um aplicativo Android que abre o PWA. Mesmo que o PWA aberto dentro de uma Atividade na Web Confiável siga a com os mesmos ciclos de atualização de qualquer app da Web, o wrapper nativo pode e deve ser atualizado.

Você deve atualizar seu aplicativo para garantir que esteja usando a versão mais recente do wrapper, com a versão mais recente correções de bugs e recursos. Com a versão mais recente do Bubblewrap instalada, o comando update vai aplicar a versão mais recente do wrapper a um projeto existente:

npm update -g @bubblewrap/cli
bubblewrap update
bubblewrap build

Outro motivo para atualizar esses aplicativos é garantir que as alterações no manifesto da Web sejam aplicadas ao aplicativo. Para isso, use o novo comando merge:

bubblewrap merge
bubblewrap update
bubblewrap build

Atualizações nos critérios de qualidade

O Chrome 86 introduziu mudanças nos Critérios de qualidade da Atividade Confiável na Web, que são explicados em completo em Mudanças nos critérios de qualidade para PWAs usando Atividade confiável na Web.

Um breve resumo é que você deve garantir que seus aplicativos lidem com os seguintes cenários para evitar falhas:

  • Falha ao verificar os links de ativos digitais na inicialização do aplicativo
  • Falha ao retornar HTTP 200 para uma solicitação de recurso de rede off-line
  • Retorno de um erro HTTP 404 ou 5xx no aplicativo.

Além de garantir que o aplicativo passe na validação do Digital Asset Links, o restante podem ser tratados por um service worker:

self.addEventListener('fetch', event => {
  event.respondWith((async () => {
    try {
      return await fetchAndHandleError(event.request);
    } catch {
      // Failed to load from the network. User is offline or the response
      // has a status code that triggers the Quality Criteria.
      // Try loading from cache.
      const cachedResponse = await caches.match(event.request);
      if (cachedResponse) {
        return cachedResponse;
      }
      // Response was not found on the cache. Send the error / offline
      // page. OFFLINE_PAGE should be pre-cached when the service worker
      // is activated.
      return await caches.match(OFFLINE_PAGE);
    }
  })());
});

async function fetchAndHandleError(request) {
  const cache = await caches.open(RUNTIME_CACHE);
  const response = await fetch(request);

  // Throw an error if the response returns one of the status
  // that trigger the Quality Criteria.
  if (response.status === 404 ||
      response.status >= 500 && response.status < 600) {
    throw new Error(`Server responded with status: ${response.status}`);
  }

  // Cache the response if the request is successful.
  cache.put(request, response.clone());
  return response;
}

O Workbox incorpora as práticas recomendadas e remove o código boilerplate durante o uso de service workers. Como alternativa, use um plug-in do Workbox para lidar com estes cenários:

export class FallbackOnErrorPlugin {
  constructor(offlineFallbackUrl, notFoundFallbackUrl, serverErrorFallbackUrl) {
    this.notFoundFallbackUrl = notFoundFallbackUrl;
    this.offlineFallbackUrl = offlineFallbackUrl;
    this.serverErrorFallbackUrl = serverErrorFallbackUrl;
  }

  checkTrustedWebActivityCrash(response) {
    if (response.status === 404 || response.status >= 500 && response.status <= 600) {
      const type = response.status === 404 ? 'E_NOT_FOUND' : 'E_SERVER_ERROR';
      const error = new Error(`Invalid response status (${response.status})`);
      error.type = type;
      throw error;
    }
  }

  // This is called whenever there's a network response,
  // but we want special behavior for 404 and 5**.
  fetchDidSucceed({response}) {
    // Cause a crash if this is a Trusted Web Activity crash.
    this.checkTrustedWebActivityCrash(response);

    // If it's a good response, it can be used as-is.
    return response;
  }

  // This callback is new in Workbox v6, and is triggered whenever
  // an error (including a NetworkError) is thrown when a handler runs.
  handlerDidError(details) {
    let fallbackURL;
    switch (details.error.details.error.type) {
      case 'E_NOT_FOUND': fallbackURL = this.notFoundFallbackUrl; break;
      case 'E_SERVER_ERROR': fallbackURL = this.serverErrorFallbackUrl; break;
      default: fallbackURL = this.offlineFallbackUrl;
    }

    return caches.match(fallbackURL, {
      // Use ignoreSearch as a shortcut to work with precached URLs
      // that have _WB_REVISION parameters.
      ignoreSearch: true,
    });
  }
}

Google Play Faturamento

Além de permitir que seu app venda produtos e assinaturas digitais na Play Store, O Google Play Faturamento oferece ferramentas úteis para gerenciar seu catálogo, preços e assinaturas. e um fluxo de finalização de compra da Play Store que os usuários já conhecem. Ela também é um requisito para aplicativos publicados na Play Store que vendem produtos e softwares digitais.

O Chrome 88 será lançado com um teste de origem no Android que permite a integração de Atividades confiáveis na Web, a API Payment Request e API de produtos e softwares digitais para implementar fluxos de compra pelo Google Play Faturamento. Esperamos que este teste de origem também esteja disponível para o ChromeOS na versão 89.

Importante:a API Google Play Billing tem terminologia própria e inclui cliente e componentes de back-end. Esta seção aborda apenas uma pequena parte da API que é específica para o uso da API de produtos digitais e Atividade confiável na Web. Leia o documentação do Google Play Faturamento e entenda os conceitos antes de integrá-lo a um aplicativo de produção.

O fluxo básico

Menu do Play Console

Para fornecer produtos e softwares digitais por meio da Play Store, configure seu catálogo no Google Play Store e conectar a Play Store como uma forma de pagamento do seu PWA.

Para configurar seu catálogo, acesse a seção "Produtos" à esquerda Menu lateral do Play Console:

Aqui você encontra a opção de visualizar suas assinaturas e os produtos no app, além de use o botão "Criar" para adicionar novos.

Produtos no app

Detalhes do produto

Para criar um novo produto no app, é necessário informar o ID, o nome, a descrição e o preço do produto. Está importantes para criar IDs de produto significativos e fáceis de lembrar, você vai precisar deles mais tarde, e os IDs não podem ser alteradas depois da criação.

Ao criar assinaturas, você também vai precisar especificar um período de faturamento. Você tem a opção de liste os benefícios da assinatura e adicione recursos como, por exemplo, se você tem um teste sem custo financeiro, preço inicial, período de carência e opção de reativação de assinatura.

Depois de criar cada produto, ative-os para disponibilizá-los no seu app.

Se preferir, adicione seus produtos usando a API Play Developers.

Depois de configurar o catálogo, a próxima etapa é configurar o fluxo de finalização de compra do PWA. Você vai usar uma combinação da API de produtos e softwares digitais e da API Payment Request para alcançar isso.

Buscar o preço de um produto com a API Digital Goods

Ao usar o Google Play Faturamento, você vai querer garantir que o preço exibido para os usuários seja igual o preço da página "Detalhes do app". Seria impossível manter esses preços sincronizados manualmente, por isso a API de produtos digitais fornece uma maneira de o aplicativo da Web consultar o pagamento provedor para saber os preços:

// The SKU for the product, as defined in the Play Store interface
async function populatePrice(sku) {
  try {
    // Check if the Digital Goods API is supported by the browser.
    if (window.getDigitalGoodsService) {
      // The Digital Goods API can be supported by other Payments provider.
      // In this case, we're retrieving the Google Play Billing provider.
      const service =
          await window.getDigitalGoodsService("https://play.google.com/billing");

      // Fetch product details using the `getDetails()` method.
      const details = await service.getDetails([sku]);

      if (details.length === 0) {
        console.log(`Could not get SKU: "${sku}".`);
        return false;
      }

      // The details will contain both the price and the currenncy.
      item = details[0];
      const value = item.price.value;
      const currency = item.price.currency;

      const formattedPrice = new Intl.NumberFormat(navigator.language, {
        style: 'currency', currency: currency }).format(value);

      // Display the price to the user.
      document.getElementById("price").innerHTML = formattedPrice;
    } else {
      console.error("Could not get price for SKU \"" + sku + "\".");
    }
  } catch (error) {
    console.log(error);
  }
  return false;
}

Você pode detectar o suporte para a API Digital Goods verificando se getDigitalGoodsService() é disponíveis no objeto window.

Em seguida, chame window.getDigitalGoodsService() com o identificador do Google Play Faturamento como parâmetro. Isso vai retornar uma instância de serviço para o Google Play Faturamento, e outros fornecedores podem implementar o suporte. para a API de produtos e softwares digitais e terão identificadores diferentes.

Por fim, chame getDetails() na referência ao objeto do Google Play Faturamento, transmitindo a SKU o item como parâmetro. O método retornará um objeto de detalhe contendo o preço e o moeda do item que pode ser exibido ao usuário.

Iniciar o fluxo de compra

A API Payment Request permite fluxos de compra na Web e também é usada para o Integração de faturamento. Confira How Payment Request API funciona para saber mais se você é novo no Payment API Request.

Para usar a API com o Google Play Faturamento, você precisará adicionar um instrumento de pagamento que tem um método compatível chamado https://play.google.com/billing e adicione a SKU como parte dos dados. para o instrumento:

const supportedInstruments = [{
  supportedMethods: "https://play.google.com/billing",
  data: {
    sku: sku
  }
}];

Em seguida, crie um objeto PaymentRequest normalmente e use a API normalmente

const request = new PaymentRequest(supportedInstruments, details);

Confirmar a compra

Quando a transação for concluída, você precisará usar a API de produtos e softwares digitais para confirmar a pagamento. O objeto de resposta de PaymentRequest vai conter um token que você vai usar para Confirme a transação:

const response = await request.show();
const token = response.details.token;
const service =
          await window.getDigitalGoodsService("https://play.google.com/billing");
await service.acknowledge(token, 'onetime');

A API Digital Goods e a API Payment Request não têm conhecimento sobre a identidade do usuário. Como final, cabe a você associar a compra ao usuário no back-end e garantir que ele tenha acesso aos itens comprados. Ao associar a compra a um usuário, lembre-se de salvar o token de compra, pois pode ser necessário para verificar se a compra foi cancelada ou reembolsada, ou se uma assinatura ainda está ativa. Confira a API Real Time Developer Notifications e o API Google Play Developer, já que elas fornecem endpoints para lidar com esses casos no back-end.

Verificar se há direitos

Talvez o usuário tenha resgatado um código promocional ou já tenha uma assinatura do seu produto. Em para confirmar que o usuário tem os direitos apropriados, chame o método listPurchases() no serviço de produtos e softwares digitais. Isso retornará todas as compras feitas que o cliente fez no seu app. Este também seria o lugar para confirmar qualquer mensagem não confirmada compras para garantir que o usuário resgate os direitos corretamente.

const purchases = await itemService.listPurchases();
for (p of purchases) {
  if (!p.acknowledged) {
    await itemService.acknowledge(p.purchaseToken, 'onetime');
  }
}

Fazer upload para a Play Store do ChromeOS

As Atividades Confiáveis na Web também estão disponíveis desde o Chrome 85 na Play Store do ChromeOS. O processo listar o app na loja é o mesmo para o ChromeOS e para Android.

Depois de criar o pacote de apps, o Play Console vai guiar você pelas etapas para listar o app na Play Store. Na documentação do Play Console, você encontra ajuda para criar a página "Detalhes do app", gerenciar seus arquivos APK e outras configurações, além das instruções para testar e lançar seu app com segurança.

Para restringir seu aplicativo apenas a Chromebooks, adicione a sinalização --chromeosonly ao inicializar o aplicativo no Bubblewrap:

bubblewrap init --manifest="https://example.com/manifest.json" --chromeosonly

Ao criar seu aplicativo manualmente, sem o Bubblewrap, adicione uma flag uses-feature ao Manifesto do Android:

<uses-feature  android:name="org.chromium.arc" android:required="true"/>

Caso sua página de detalhes seja compartilhada com um app Android, a versão do pacote somente do ChromeOS sempre terá uma versão mais recente do que a versão do pacote de apps Android. Você pode configurar a versão do pacote do ChromeOS para um um número muito maior do que a versão do Android, então não é necessário atualizar as duas versões lançamento.