Distribuição do App Center – atualizações no aplicativo do Android

Importante

O Visual Studio App Center está programado para ser desativado em 31 de março de 2025. Embora você possa continuar a usar o Visual Studio App Center até que ele seja totalmente desativado, há várias alternativas recomendadas para as quais você pode considerar migrar.

Saiba mais sobre linhas do tempo e alternativas de suporte.

O App Center Distribute permitirá que os usuários instalem uma nova versão do aplicativo quando você distribuí-lo por meio do App Center. Com uma nova versão do aplicativo disponível, o SDK apresentará uma caixa de diálogo de atualização aos usuários para baixar ou adiar a nova versão. Depois que eles optarem por atualizar, o SDK começará a atualizar seu aplicativo.

Aviso

O Google Play considera o código de atualização no aplicativo como um comportamento mal-intencionado, mesmo que ele não seja usado em runtime. Use uma variante do SDK de Distribuição conforme indicado nesta seção ou remova completamente o SDK de Distribuição que contém o código de atualização no aplicativo antes de enviar seu aplicativo para o Google Play. Não fazer isso pode levar à não conformidade e à remoção do aplicativo do Google Play.

Observação

Se você estiver executando testes automatizados de interface do usuário, as atualizações habilitadas no aplicativo bloquearão seus testes automatizados de interface do usuário, pois eles tentarão se autenticar no back-end do App Center. É recomendável não habilitar a Distribuição do App Center para seus testes de interface do usuário.

Adicionar atualizações no aplicativo ao seu aplicativo

Siga a seção Introdução se você ainda não configurou e iniciou o SDK em seu aplicativo.

1. Adicionar o módulo Distribuir do App Center

O SDK do App Center foi projetado com uma abordagem modular– um desenvolvedor só precisa integrar os módulos dos serviços nos quais está interessado.

  1. Abra o arquivo build.gradle no nível do aplicativo do projeto (app/build.gradle) e adicione as seguintes linhas após apply plugin.

    dependencies {
       def appCenterSdkVersion = '5.0.4'
       implementation "com.microsoft.appcenter:appcenter-distribute:${appCenterSdkVersion}"
    }
    

    Observação

    Se a versão do plug-in do Android Gradle for inferior à 3.0.0, você precisará substituir a implementação pela compilação.

  2. Salve o arquivo build.gradle e dispare uma sincronização do Gradle no Android Studio.

  3. DownloadManager é usado para baixar atualizações. O SDK do App Center impõe o TLS 1.2 para melhorar a segurança.

2. Iniciar Distribuição do App Center

Para usar o App Center, aceite os módulos que você deseja usar. Por padrão, nenhum módulo é iniciado e você deve chamar explicitamente cada um deles ao iniciar o SDK.

Adicione a classe Distribute ao método AppCenter.start() para iniciar o serviço Distribuição do App Center.

AppCenter.start(getApplication(), "{Your App Secret}", Distribute.class);
AppCenter.start(application, "{Your App Secret}", Distribute::class.java)

Verifique se você substituiu {Your App Secret} no exemplo de código acima pelo segredo do aplicativo. O Android Studio sugere automaticamente a instrução de importação necessária depois de adicionar uma referência à Distribute classe ao start() método , mas se você vir um erro informando que os nomes de classe não são reconhecidos, adicione as seguintes linhas às instruções de importação em sua classe de atividade:

import com.microsoft.appcenter.AppCenter;
import com.microsoft.appcenter.distribute.Distribute;
import com.microsoft.appcenter.AppCenter
import com.microsoft.appcenter.distribute.Distribute

Observação

O Android 10 ou superior tem restrições na atividade de inicialização em segundo plano. Consulte o artigo sobre restrições de atividades iniciais em segundo plano.

Observação

Os aplicativos em execução no Android 10 (edição Go) não podem receber a permissão SYSTEM_ALERT_WINDOW . Consulte o artigo sobre SYSTEM_ALERT_WINDOW em dispositivos Go.

Observação

A partir do Android 11, ACTION_MANAGE_OVERLAY_PERMISSION as intenções sempre levam o usuário para a tela Configurações de nível superior, em que o usuário pode conceder ou revogar as SYSTEM_ALERT_WINDOW permissões para aplicativos. Consulte o artigo sobre atualizações de permissões no Android 11.

Preparar sua compilação do Google Play

O Google Play considera o código de atualização no aplicativo como um comportamento mal-intencionado, mesmo que ele não seja usado em runtime. Use uma variante do SDK de Distribuição conforme indicado nesta seção ou remova completamente o SDK de Distribuição que contém o código de atualização no aplicativo antes de enviar seu aplicativo para o Google Play. Não fazer isso pode levar à não conformidade e à remoção do aplicativo do Google Play. Para facilitar, fornecemos a versão do SDK de Distribuição do App Center com APIs fragmentadas, portanto, a única alteração para você é uma troca de dependência.

  1. Abra o arquivo build.gradle no nível do aplicativo do projeto (app/build.gradle).

  2. Configure variantes de build adicionando tipos de produto:

    android {
        flavorDimensions "distribute"
        productFlavors {
            appCenter {
                dimension "distribute"
            }
            googlePlay {
                dimension "distribute"
            }
        }
    }
    
  3. Modifique o bloco de dependências para consumir dependências diferentes com base no tipo de produto:

    dependencies {
        def appCenterSdkVersion = "5.0.4"
        appCenterImplementation "com.microsoft.appcenter:appcenter-distribute:${appCenterSdkVersion}"
        googlePlayImplementation "com.microsoft.appcenter:appcenter-distribute-play:${appCenterSdkVersion}"
    }
    
  4. Salve o arquivo build.gradle e dispare uma sincronização do Gradle no Android Studio.

  5. Você pode alterar a variante de build no menu suspenso Build > Select Build Variant ou Build Variants na barra de janelas de ferramentas .

Você pode ler mais sobre como configurar variantes de build na documentação do Android.

Usar grupo de distribuição privado

Por padrão, Distribuir usa um grupo de distribuição público. Se você quiser usar um grupo de distribuição privado, precisará defini-lo explicitamente por meio da setUpdateTrack API.

Distribute.setUpdateTrack(UpdateTrack.PRIVATE);
Distribute.setUpdateTrack(UpdateTrack.PRIVATE)

Observação

O valor padrão é UpdateTrack.PUBLIC. Esse método só pode ser chamado antes da chamada do AppCenter.start método. As alterações na faixa de atualização não são persistidas quando o processo do aplicativo é reiniciado e, portanto, se o método nem sempre for chamado antes da AppCenter.start chamada, ele será público, por padrão.

Quando o aplicativo está em primeiro plano (após Distribute.setUpdateTrack(UpdateTrack.PRIVATE); e AppCenter.start), uma janela do navegador é aberta para autenticar o usuário. Todas as verificações de atualização subsequentes obterão a versão mais recente na faixa privada.

Se um usuário estiver na faixa privada, isso significa que, após a autenticação bem-sucedida, ele obterá a versão mais recente de qualquer grupo de distribuição privado do qual seja membro. Se um usuário estiver na faixa pública, isso significa que ele obterá a versão mais recente de qualquer grupo de distribuição pública.

Desabilitar a Verificação Automática de Atualização

Por padrão, o SDK verifica automaticamente se há novas versões:

  • Quando o aplicativo é iniciado.
  • Quando o aplicativo entra em primeiro plano depois de entrar em segundo plano.
  • Ao habilitar o módulo Distribuir se estiver desabilitado anteriormente.

Se você quiser marcar para novas versões manualmente, poderá desabilitar o marcar automático para atualização. Para fazer isso, chame o seguinte método antes do SDK iniciar:

Distribute.disableAutomaticCheckForUpdate();
Distribute.disableAutomaticCheckForUpdate()

Observação

Esse método deve ser chamado antes da chamada do AppCenter.start método.

Em seguida, você pode usar a checkForUpdate API , que é descrita na seção a seguir.

Verificar manualmente se há atualização

Distribute.checkForUpdate();
Distribute.checkForUpdate()

Isso envia uma solicitação para o App Center e exibe uma caixa de diálogo de atualização caso haja uma nova versão disponível.

Observação

Um marcar manual para a chamada de atualização funciona mesmo quando as atualizações automáticas estão habilitadas. Um marcar manual para atualização será ignorado se outro marcar já estiver sendo feito. O marcar manual para atualização não será processado se o usuário tiver adiado as atualizações (a menos que a versão mais recente seja uma atualização obrigatória).

Personalizar ou localizar a caixa de diálogo de atualização no aplicativo

1. Personalizar ou localizar texto

Você pode fornecer facilmente suas próprias cadeias de caracteres de recurso se quiser alterar ou localizar o texto exibido na caixa de diálogo de atualização. Examine os arquivos de cadeia de caracteres neste arquivo de recurso. Use o mesmo nome/chave de cadeia de caracteres e especifique o valor localizado a ser refletido na caixa de diálogo em seus próprios arquivos de recurso de aplicativo.

2. Personalizar a caixa de diálogo de atualização

Você pode personalizar a aparência da caixa de diálogo de atualização padrão implementando a DistributeListener interface . Você precisa registrar o ouvinte antes de chamar AppCenter.start , conforme mostrado no exemplo a seguir:

Distribute.setListener(new MyDistributeListener());
AppCenter.start(...);
Distribute.setListener(MyDistributeListener())
AppCenter.start(...)

Aqui está um exemplo da implementação do ouvinte que substitui a caixa de diálogo do SDK por uma personalizada:

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.net.Uri;

import com.microsoft.appcenter.distribute.Distribute;
import com.microsoft.appcenter.distribute.DistributeListener;
import com.microsoft.appcenter.distribute.ReleaseDetails;
import com.microsoft.appcenter.distribute.UpdateAction;

public class MyDistributeListener implements DistributeListener {

    @Override
    public boolean onReleaseAvailable(Activity activity, ReleaseDetails releaseDetails) {

        // Look at releaseDetails public methods to get version information, release notes text or release notes URL
        String versionName = releaseDetails.getShortVersion();
        int versionCode = releaseDetails.getVersion();
        String releaseNotes = releaseDetails.getReleaseNotes();
        Uri releaseNotesUrl = releaseDetails.getReleaseNotesUrl();

        // Build our own dialog title and message
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity);
        dialogBuilder.setTitle("Version " + versionName + " available!"); // you should use a string resource instead, this is just a simple example
        dialogBuilder.setMessage(releaseNotes);

        // Mimic default SDK buttons
        dialogBuilder.setPositiveButton(com.microsoft.appcenter.distribute.R.string.appcenter_distribute_update_dialog_download, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {

                // This method is used to tell the SDK what button was clicked
                Distribute.notifyUpdateAction(UpdateAction.UPDATE);
            }
        });

        // We can postpone the release only if the update isn't mandatory
        if (!releaseDetails.isMandatoryUpdate()) {
            dialogBuilder.setNegativeButton(com.microsoft.appcenter.distribute.R.string.appcenter_distribute_update_dialog_postpone, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                    // This method is used to tell the SDK what button was clicked
                    Distribute.notifyUpdateAction(UpdateAction.POSTPONE);
                }
            });
        }
        dialogBuilder.setCancelable(false); // if it's cancelable you should map cancel to postpone, but only for optional updates
        dialogBuilder.create().show();

        // Return true if you're using your own dialog, false otherwise
        return true;
    }
    
    @Override
    public void onNoReleaseAvailable(Activity activity) {
        Toast.makeText(activity, activity.getString(R.string.no_updates_available), Toast.LENGTH_LONG).show();
    }
}
import android.app.Activity
import android.app.AlertDialog
import com.microsoft.appcenter.distribute.Distribute
import com.microsoft.appcenter.distribute.DistributeListener
import com.microsoft.appcenter.distribute.ReleaseDetails
import com.microsoft.appcenter.distribute.UpdateAction

class MyDistributeListener : DistributeListener {

    override fun onReleaseAvailable(activity: Activity, releaseDetails: ReleaseDetails): Boolean {

        // Look at releaseDetails public methods to get version information, release notes text or release notes URL
        val versionName = releaseDetails.shortVersion
        val versionCode = releaseDetails.version
        val releaseNotes = releaseDetails.releaseNotes
        val releaseNotesUrl = releaseDetails.releaseNotesUrl

        // Build our own dialog title and message
        val dialogBuilder = AlertDialog.Builder(activity)
        dialogBuilder.setTitle("Version $versionName available!") // you should use a string resource instead, this is just a simple example
        dialogBuilder.setMessage(releaseNotes)

        // Mimic default SDK buttons
        dialogBuilder.setPositiveButton(
            com.microsoft.appcenter.distribute.R.string.appcenter_distribute_update_dialog_download
        ) { dialog, which ->
            // This method is used to tell the SDK what button was clicked
            Distribute.notifyUpdateAction(UpdateAction.UPDATE)
        }

        // We can postpone the release only if the update isn't mandatory
        if (!releaseDetails.isMandatoryUpdate) {
            dialogBuilder.setNegativeButton(
                com.microsoft.appcenter.distribute.R.string.appcenter_distribute_update_dialog_postpone
            ) { dialog, which ->
                // This method is used to tell the SDK what button was clicked
                Distribute.notifyUpdateAction(UpdateAction.POSTPONE)
            }
        }
        dialogBuilder.setCancelable(false) // if it's cancelable you should map cancel to postpone, but only for optional updates
        dialogBuilder.create().show()

        // Return true if you're using your own dialog, false otherwise
        return true
    }

    override fun onNoReleaseAvailable(activity: Activity) {
        Toast.makeText(activity, activity.getString(R.string.no_updates_available), Toast.LENGTH_LONG).show()
    }
}

Conforme mostrado no exemplo, você deve chamar Distribute.notifyUpdateAction(UpdateAction.UPDATE); ou Distribute.notifyUpdateAction(UpdateAction.POSTPONE); se o ouvinte retornar true.

Se você não chamar notifyUpdateAction, o retorno de chamada será repetido em cada alteração de atividade.

O ouvinte poderá ser chamado novamente com a mesma versão se a atividade for alterada antes que a ação do usuário seja notificada para o SDK.

Esse comportamento é necessário para abranger os seguintes cenários:

  • Seu aplicativo é enviado para o segundo plano (como pressionar HOME) e, em seguida, retomado em uma atividade diferente.
  • Sua atividade é coberta por outra sem sair do aplicativo (como clicar em algumas notificações).
  • Outros cenários semelhantes.

Nesse caso, a atividade que hospeda a caixa de diálogo pode ser substituída sem interação do usuário. Portanto, o SDK chama o ouvinte novamente para que você possa restaurar a caixa de diálogo personalizada.

Nos casos em que o SDK verifica se há atualizações e não encontra nenhuma atualização disponível mais recente do que a usada atualmente, um onNoReleaseAvailable retorno de chamada da DistributeListener interface é invocado. Isso permite que você execute um código personalizado nesses cenários. O exemplo acima mostra como exibir a mensagem do sistema quando nenhuma atualização é encontrada.

Habilitar ou desabilitar a Distribuição do App Center no runtime

Você pode habilitar e desabilitar a Distribuição do App Center em runtime. Se você desabilitar, o SDK não fornecerá nenhuma funcionalidade de atualização no aplicativo, mas você ainda poderá usar o serviço Distribuir no portal do App Center.

Distribute.setEnabled(false);
Distribute.setEnabled(false)

Para habilitar a Distribuição do App Center novamente, use a mesma API, mas passe true como um parâmetro.

Distribute.setEnabled(true);
Distribute.setEnabled(true)

O estado é persistente no armazenamento do dispositivo entre as inicializações de aplicativos.

Essa API é assíncrona, você pode ler mais sobre isso em nosso guia de APIs assíncronas do App Center .

Observação

Esse método só deve ser usado depois Distribute de ter sido iniciado.

Verificar se a Distribuição do App Center está habilitada

Você também pode marcar se a Distribuição do App Center estiver habilitada ou não:

Distribute.isEnabled();
Distribute.isEnabled()

Essa API é assíncrona, você pode ler mais sobre isso em nosso guia de APIs assíncronas do App Center .

Observação

Esse método só deve ser usado depois Distribute de iniciado, ele sempre retornará false antes de começar.

Habilitar atualizações no aplicativo para builds de depuração

Por padrão, o App Center habilita atualizações no aplicativo somente para builds de versão.

Para habilitar atualizações no aplicativo em builds de depuração, chame o seguinte método antes AppCenter.startde :

Distribute.setEnabledForDebuggableBuild(true);
Distribute.setEnabledForDebuggableBuild(true)

Observação

Esse método afeta apenas builds de depuração e não tem impacto sobre builds de versão. A compilação de depuração significa que o android:debuggable sinalizador está definido como true (que geralmente é definido automaticamente por variantes de build de depuração predefinidas degradle). Caso contrário, essa é uma compilação de versão.

Como funcionam as atualizações no aplicativo?

Observação

Para que as atualizações no aplicativo funcionem, um build de aplicativo deve ser baixado do link. Ele não funcionará se for instalado de um IDE ou manualmente.

O recurso de atualizações no aplicativo funciona da seguinte maneira:

  1. Esse recurso só funciona com builds RELEASE (por padrão) distribuídos usando o serviço Distribuição do App Center .

  2. Depois de integrar o SDK, compilar a versão de lançamento do aplicativo e carregar no App Center, os usuários desse grupo de distribuição serão notificados para a nova versão por meio de um email.

  3. Quando cada usuário abrir o link em seu email, o aplicativo será instalado em seu dispositivo. É importante que eles usem o link de email para instalar – não oferecemos suporte ao sideload. Quando um aplicativo é baixado do link, o SDK salva informações importantes de cookies para marcar para atualizações posteriormente, caso contrário, o SDK não tem essas informações importantes.

  4. Se o aplicativo definir a faixa como privada, um navegador será aberto para autenticar o usuário e habilitar as atualizações no aplicativo. O navegador não será aberto novamente, desde que as informações de autenticação permaneçam válidas mesmo ao alternar de volta para a faixa pública e voltar para privada novamente mais tarde. Se a autenticação do navegador for bem-sucedida, o usuário será redirecionado de volta para o aplicativo automaticamente. Se a faixa for pública (que é o padrão), a próxima etapa ocorrerá diretamente.

  5. Uma nova versão do aplicativo mostra a caixa de diálogo de atualização no aplicativo solicitando que os usuários atualizem seu aplicativo se ele for:

    • um valor mais alto de versionCode ou
    • um valor igual de versionCode , mas um valor diferente de versionName.

Dica

Se você carregar a mesma APK uma segunda vez, a caixa de diálogo NÃO aparecerá, pois as versões são idênticas.

Como fazer testar atualizações no aplicativo?

Você precisa carregar builds de versão (que usam o módulo Distribuir do SDK do App Center) no Portal do App Center para testar atualizações no aplicativo, aumentando os números de versão a cada vez.

  1. Crie seu aplicativo no Portal do App Center, caso ainda não tenha feito isso.
  2. Crie um novo grupo de distribuição e nomeie-o, para que você possa reconhecer que ele destina-se a testar o recurso de atualização no aplicativo.
  3. Adicione a si mesmo (ou a todas as pessoas que você deseja incluir no teste do recurso de atualização no aplicativo). Use um endereço de email novo ou descartado para isso, que não foi usado para esse aplicativo no App Center. Isso garante que sua experiência esteja próxima da experiência de seus testadores reais.
  4. Crie um novo build de seu aplicativo que inclua a Distribuição do App Center e contenha a lógica de instalação, conforme descrito acima. Se o grupo for privado, não se esqueça de definir a faixa de atualização privada no aplicativo antes de começar a usar a API setUpdateTrack.
  5. Clique no botão Distribuir nova versão no portal e carregue o build do aplicativo.
  6. Depois que o upload for concluído, clique em Avançar e selecione o Grupo de distribuição que você criou como o Destino dessa distribuição de aplicativo.
  7. Examine a Distribuição e distribua o build para o grupo de testes no aplicativo.
  8. Pessoas nesse grupo receberão um convite para serem testadores do aplicativo. Depois de aceitar o convite, eles poderão baixar o aplicativo no Portal do App Center de seu dispositivo móvel. Depois que elas tiverem as atualizações no aplicativo instaladas, você estará pronto para testar as atualizações no aplicativo.
  9. Aumente o versionCode de seu aplicativo.
  10. Crie a versão de lançamento do aplicativo e carregue um novo build do aplicativo como você fez na etapa anterior e distribua isso para o Grupo de Distribuição criado anteriormente. Os membros do Grupo de Distribuição serão solicitados a obter uma nova versão na próxima vez que o aplicativo for iniciado.

Dica

Confira as informações sobre como utilizar a Distribuição do App Center para obter informações mais detalhadas sobre grupos de distribuição etc. Embora seja possível usar a Distribuição do App Center para distribuir uma nova versão do seu aplicativo sem adicionar nenhum código, adicionar a Distribuição do App Center ao código do aplicativo resultará em uma experiência mais perfeita para seus testadores e usuários à medida que eles obtêm a experiência de atualização no aplicativo.