Até agora, falamos sobre o acesso às APIs do Google, que usam contas e usuários definidos pelo Google. No entanto, se você tiver seu próprio serviço on-line, ele não terá usuários ou Contas do Google. Então, o que você precisa fazer? Na verdade, é relativamente simples instalar novos tipos de conta no dispositivo de um usuário. Esta lição explica como criar um tipo de conta personalizada que funciona da mesma maneira que as contas integradas.
Implementar seu código de conta personalizado
Primeiramente, você precisará de uma forma de receber credenciais do usuário. Isso pode ser tão simples quanto uma caixa de diálogo que solicita um nome e uma senha. Ou pode ser um procedimento mais diferente, como uma senha única ou uma verificação biométrica. De qualquer maneira, é sua responsabilidade implementar o código que:
- coleta as credenciais do usuário.
- autentica as credenciais com o servidor;
- armazena as credenciais no dispositivo,
Normalmente, uma única atividade pode lidar com esses três requisitos. Chamaremos isso de atividade do autenticador.
Como as atividades do autenticador precisam interagir com o sistema do AccountManager
,
as atividades do autenticador têm alguns requisitos que as atividades normais não têm. Para que seja mais fácil
acertar tudo, o framework do Android fornece uma classe de base, AccountAuthenticatorActivity
, que pode ser estendida para criar seu próprio autenticador
personalizado.
Você decide como lidar com os dois primeiros requisitos de uma atividade do autenticador, coleta de credenciais e autenticação. Se houvesse apenas uma maneira de fazer isso, não haveria necessidade de tipos de conta "personalizados". O terceiro requisito tem uma implementação canônica e bastante simples:
Kotlin
Account(username, your_account_type).also { account -> accountManager.addAccountExplicitly(account, password, null) }
Java
final Account account = new Account(username, your_account_type); accountManager.addAccountExplicitly(account, password, null);
Segurança inteligente
É importante entender que AccountManager
não é um serviço
de criptografia
nem um conjunto de chaves. Ele armazena as credenciais da conta na forma como você as transmite, em texto simples. Na maioria dos dispositivos, essa não é
uma preocupação específica, porque as informações são armazenadas em
um banco de dados que só pode ser acessado pela raiz. No entanto, em um dispositivo com acesso root, as
credenciais podem ser lidas por qualquer pessoa com acesso adb
ao dispositivo.
Com isso em mente, não transmita a senha atual
do usuário para AccountManager.addAccountExplicitly()
. Em vez disso, é necessário armazenar um
token criptograficamente seguro que teria uso limitado para um invasor. Se suas credenciais de usuário estiverem protegendo algo valioso, considere fazer algo semelhante.
Lembrete:quando se trata do código de segurança, siga a regra do "Caça-mitos": não tente fazer isso em casa. Consulte um profissional de segurança antes de implementar um código de conta personalizado.
Agora que já tratamos das exoneração de responsabilidade sobre segurança, é hora de voltar ao trabalho. Você já implementou a parte principal do código da sua conta personalizada. O que resta é simples.
Estender o AbstractAccountAuthenticator
Para que AccountManager
funcione com seu código de conta
personalizado, você
precisa de uma classe que implemente as interfaces esperadas pelo AccountManager
.
Essa classe é a de autenticador.
A maneira mais fácil de criar uma classe de autenticador é estender
AbstractAccountAuthenticator
e implementar os métodos abstratos dele. Se você já
concluiu as lições anteriores, os métodos abstratos de
AbstractAccountAuthenticator
parecerão familiares: eles são o lado oposto
dos
métodos que você chamou na lição anterior para receber informações da conta e
tokens de autorização.
A implementação correta de uma classe de autenticador requer várias partes
separadas de código. Primeiro, o AbstractAccountAuthenticator
tem sete métodos
abstratos que precisam ser modificados. Em segundo lugar, você precisa adicionar um
filtro de intent para
"android.accounts.AccountAuthenticator"
ao manifesto do
aplicativo (mostrado na próxima seção). Por fim, você precisa fornecer dois recursos XML que definem, entre
outras
coisas, o nome do seu tipo de conta personalizada e o ícone que o sistema
exibirá ao lado de contas desse tipo.
Você pode encontrar um guia passo a passo para implementar uma classe de autenticador
e os arquivos XML na documentação
AbstractAccountAuthenticator
.
Se a atividade do autenticador precisar de quaisquer parâmetros especiais de inicialização,
você poderá anexá-los à intent usando
Intent.putExtra()
.
Criar um serviço de autenticador
Agora que você tem uma classe de autenticador, precisa de um lugar para ela funcionar.
Autenticadores de conta precisam estar disponíveis para vários aplicativos e funcionar em
segundo plano. Portanto, é necessário que sejam executados dentro de um Service
. Chamaremos
isso de serviço de autenticador.
Seu serviço de autenticador pode ser muito simples. Tudo o que ele precisa fazer é criar
uma instância da sua classe de autenticador em
onCreate()
e chamar
getIBinder()
em onBind()
.
Adicione uma tag <service>
ao arquivo de manifesto,
adicione um filtro de intent para a intent AccountAuthenticator e declare o autenticador
de conta:
<service ...> <intent-filter> <action android:name="android.accounts.AccountAuthenticator" /> </intent-filter> <meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator" /> </service>
Distribuir o serviço
Pronto! O sistema agora reconhece seu tipo de conta, ao lado de todos os tipos de conta conhecidos, como "Google" e "Corporate". Você pode usar a página Configurações de contas e sincronização para adicionar uma conta. Os apps que solicitam contas do seu tipo personalizado poderão enumerar e autenticar como fariam com qualquer outro tipo de conta.
Obviamente, tudo isso pressupõe que o serviço da sua conta está realmente instalado no dispositivo. Se apenas um app acessar o serviço, isso não é um grande problema, basta agrupar o serviço no app. Mas, se você quiser que o serviço da sua conta seja usado por mais de um app, as coisas ficam mais complicadas. Não é recomendável agrupar o serviço com todos os apps e ter várias cópias dele ocupando espaço no dispositivo do usuário.
Uma solução seria colocar o serviço em um APK pequeno para fins especiais. Quando um app quiser usar um tipo de conta personalizada, ele poderá verificar se o serviço dessa conta está disponível no dispositivo. Caso contrário, ele pode direcionar o usuário ao Google Play para fazer o download do serviço. Isso pode parecer um grande problema no início, mas é bem fácil em comparação com a alternativa de inserir novamente as credenciais para todos os apps que usam sua conta personalizada.