Os usuários podem copiar Contas do Google e dados de um dispositivo Android existente
para um novo usando o recurso
Toque e pronto. Use a
API Account Transfer para permitir que os usuários também copiem credenciais de contas personalizadas
implementadas usando
AbstractAccountAuthenticator
e integradas com
AccountManager
. O sistema
invoca a API Account Transfer do assistente de configuração do Toque e pronto em execução no
novo dispositivo. O sistema também invoca a API Account Transfer para
transferir dados de um smartphone Android para o Pixel
usando um cabo.
Para adicionar suporte à transferência de contas personalizadas, integre a API Account Transfer ao app. O Google Play Services pode estabelecer um canal criptografado bidirecional entre o dispositivo existente, também conhecido como dispositivo de origem, e o novo dispositivo, também conhecido como dispositivo de destino, para transferir dados da conta, conforme ilustrado na Figura 2. O canal criptografado não depende de conexão com servidores de terceiros para concluir a transferência.
Considere estes requisitos ao integrar a API Account Transfer ao seu app:
- O dispositivo de origem precisa ter o Android 4.0.1 (API nível 14) ou versão mais recente.
- O dispositivo de destino precisa ter o Android 8.0 (API nível 26) ou versão mais recente.
- Os dispositivos de origem e de destino precisam ter a versão 11.2.0 ou mais recente do Google Play Services.
- Você precisa criar seu app usando o SDK do Google Play Services versão 11.2.0 ou mais recente.
Adicionar a API Account Transfer ao seu projeto
Para usar a API Account Transfer no seu projeto, é necessário começar pela configuração do projeto com o SDK do Google Play Services. Para instruções detalhadas sobre como configurar o SDK do Google Play Services, consulte Configurar o Google Play Services.
Se você quiser compilar seletivamente a API Account Transfer do Google no
app, adicione a seguinte regra de build ao bloco dependencies
no
arquivo build.gradle
dentro do diretório do módulo do aplicativo:
Groovy
plugins { id 'com.android.application' } ... dependencies { // VERSION_NUMBER must be equal to or higher than 11.2.0. implementation 'com.google.android.gms:play-services-auth:<VERSION_NUMBER>' }
Kotlin
plugins { id("com.android.application") } ... dependencies { // VERSION_NUMBER must be equal to or higher than 11.2.0. implementation("com.google.android.gms:play-services-auth:<VERSION_NUMBER>") }
Para adicionar compatibilidade com a transferência de contas personalizadas, é necessário declarar o
broadcast receiver START_ACCOUNT_EXPORT
para seu serviço de autenticador no
manifesto do app:
<receiver android:name=".MyBroadcastReceiver" android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.auth.START_ACCOUNT_EXPORT"/>
...
</intent-filter>
</receiver>
Se o app não estiver instalado em uma imagem de sistema OEM e você não planejar colocá-lo
em uma imagem de sistema OEM, faça o registro para ouvir
a transmissão
ACTION_START_ACCOUNT_EXPORT
no dispositivo de origem para exportar os dados da conta, conforme descrito acima.
Se você instalar seu app em uma imagem de sistema OEM, também vai ser necessário fazer o registro para estas transmissões:
- No dispositivo de origem, faça o registro para detectar a
transmissão
ACTION_ACCOUNT_EXPORT_DATA_AVAILABLE
. - No dispositivo de destino, faça o registro para detectar a
transmissão
ACTION_ACCOUNT_IMPORT_DATA_AVAILABLE
.
Transferir os dados da conta
Depois que um usuário optar por restaurar o conteúdo do dispositivo existente,
o sistema vai enviar a transmissão
ACTION_START_ACCOUNT_EXPORT
aos pacotes associados às contas relevantes no dispositivo
de origem.
Enviar os dados da conta
Para enviar dados da conta, inicie um serviço de autenticador no dispositivo de origem e
chame
sendData()
depois que o serviço receber a
transmissão
ACTION_START_ACCOUNT_EXPORT
. Você pode extrair uma referência a um objeto
AccountTransferClient
chamando
getAccountTransferClient(Context)
ou
getAccountTransferClient(Activity)
.
O snippet de código abaixo ilustra como enviar dados do dispositivo
de origem:
Kotlin
val client: AccountTransferClient = AccountTransfer.getAccountTransferClient(this) val exportTask: Task<Void> = client.sendData(ACCOUNT_TYPE, transferBytes) try { // Wait for the task to either complete or provide the callback. Tasks.await(exportTask, TIMEOUT_API, TIME_UNIT) } catch (e: Exception) { when(e) { is ExecutionException, is InterruptedException, is TimeoutException -> { client.notifyCompletion(ACCOUNT_TYPE, AuthenticatorTransferCompletionStatus.COMPLETED_FAILURE) return } else -> throw e } }
Java
AccountTransferClient client = AccountTransfer.getAccountTransferClient(this); Task<Void> exportTask = client.sendData(ACCOUNT_TYPE, transferBytes); try { // Wait for the task to either complete or provide the callback. Tasks.await(exportTask, TIMEOUT_API, TIME_UNIT); } catch (ExecutionException | InterruptedException | TimeoutException e) { client.notifyCompletion(ACCOUNT_TYPE,AuthenticatorTransferCompletionStatus.COMPLETED_FAILURE); return; }
O assistente de configuração do dispositivo de destino recebe os dados da conta.
Receber os dados da conta
Se o mesmo serviço de autenticador estiver instalado neste dispositivo e tiver registrado
interesse detectando a transmissão
ACTION_ACCOUNT_IMPORT_DATA_AVAILABLE
, o dispositivo de destino enviará a transmissão ACTION_ACCOUNT_IMPORT_DATA_AVAILABLE
para os pacotes correspondentes.
Ao receber a transmissão
ACTION_ACCOUNT_IMPORT_DATA_AVAILABLE
, inicie um serviço e chame
retrieveData()
no dispositivo de destino para extrair os dados enviados do dispositivo de origem. O
snippet de código abaixo ilustra como extrair dados no dispositivo
de destino:
Kotlin
val client: AccountTransferClient = AccountTransfer.getAccountTransferClient(this) val transportTask: Task<Void> = client.retrieveData(ACCOUNT_TYPE) try { val transferBytes: ByteArray = Tasks.await(transferTask, TIMEOUT_API, TIME_UNIT) // Add the transferred account(s) to AccountManager to register with the framework. } catch (e: Exception) { when(e) { is ExecutionException, is InterruptedException, is TimeoutException -> { client.notifyCompletion(ACCOUNT_TYPE, AuthenticatorTransferCompletionStatus.COMPLETED_FAILURE) return } else -> throw e } } client.notifyCompletion(ACCOUNT_TYPE, AuthenticatorTransferCompletionStatus.COMPLETED_SUCCESS)
Java
AccountTransferClient client = AccountTransfer.getAccountTransferClient(this); Task<Void> transferTask = client.retrieveData(ACCOUNT_TYPE); try { byte[] transferBytes = Tasks.await(transferTask, TIMEOUT_API, TIME_UNIT); // Add the transferred account(s) to AccountManager to register with the framework. } catch (ExecutionException | InterruptedException | TimeoutException e) { client.notifyCompletion(ACCOUNT_TYPE, AuthenticatorTransferCompletionStatus.COMPLETED_FAILURE); return; } client.notifyCompletion(ACCOUNT_TYPE, AuthenticatorTransferCompletionStatus.COMPLETED_SUCCESS);
Concluir a transferência
Se necessário, o serviço de autenticador no dispositivo de destino também pode transferir
dados de volta para o dispositivo de origem chamando
sendData()
.
Para receber dados no dispositivo de origem, o serviço de autenticador precisa
detectar a
transmissão
ACTION_ACCOUNT_EXPORT_DATA_AVAILABLE
. De maneira semelhante, o serviço de autenticador no dispositivo de origem pode enviar
outras mensagens para o dispositivo de destino.
Quando a transferência for concluída, o serviço de autenticador precisará chamar
notifyCompletion()
com o status de conclusão correto.
Se você precisa de mais segurança, é possível introduzir um desafio para o
usuário nos dispositivos de origem ou de destino. Primeiro, confira se os desafios podem
ser mostrados chamando
getDeviceMetaData()
e inspecionando o resultado. Se o serviço de autenticador no dispositivo de destino
oferecer suporte a desafios, chame
showUserChallenge()
para mostrar o desafio.
Se o serviço de autenticador exigido não estiver instalado no dispositivo de destino no
momento da transferência, o sistema armazenará os dados transferidos no armazenamento
local temporário. Quando o app for instalado e aberto pela primeira vez, ele poderá chamar
retrieveData()
para verificar se há dados disponíveis no armazenamento local temporário. Se
houver dados disponíveis, a API Account Transfer os retornará,
caso contrário, a chamada falhará. Se não houver dados disponíveis no armazenamento local temporário,
qualquer outra tentativa de recuperar dados falhará. Não chame
notifyCompletion()
,
porque ele pode falhar.
Testar a transferência de conta
O assistente de configuração é executado quando você configura um novo dispositivo. Redefinir um dispositivo para a configuração original regularmente para testar a configuração e a transferência de uma conta seria cansativo e demorado. Em vez disso, execute um subconjunto do fluxo do assistente de configuração para testar a transferência de uma conta de usuário de um dispositivo para outro.
Confira se há pelo menos uma conta personalizada no dispositivo de origem antes de
iniciar o teste. Verifique também se o dispositivo de destino não está conectado a nenhuma conta
personalizada. Se o dispositivo de destino já estiver conectado a uma conta personalizada quando você
executar o assistente de configuração, não será possível adicionar essa conta quando o sistema chamar
o
método
AccountManager.addAccountExplicitly()
.
Para fins de teste, é necessário usar um dispositivo com o Android 8.0 (nível 26 da API) ou mais recente como o dispositivo de destino.
É possível usar um dispositivo com o Android 4.0.1 (nível 14 da API) ou mais recente, e com o Google Play Services versão 11.2.0 ou mais recente, como o dispositivo de origem. Para criar o APK que você está testando, é necessário usar o SDK do Google Play Services versão 11.2.0 ou mais recente.
Para testar o fluxo do assistente de configuração, execute o comando abaixo no dispositivo de destino:
$ adb shell am start -a android.intent.action.MAIN -n com.google.android.gms/.smartdevice.d2d.ui.TargetActivity
O comando inicia uma atividade e mostra o assistente de configuração, pronto para parear o dispositivo de teste com outro dispositivo. Depois que os dispositivos estabelecerem uma conexão, você pode iniciar o processo de transferência da conta.