Você pode usar o GoogleApiClient
("Cliente da API do Google")
para acessar as APIs do Google fornecidas na biblioteca do Google Play Services
(como o Login do Google, Jogos e Drive). O cliente da API do Google fornece
um ponto de entrada comum para o Google Play Services e gerencia a rede
conexão entre o dispositivo do usuário e cada Serviço do Google.
No entanto, a interface GoogleApi
mais recente e as implementações dela são mais fáceis de usar.
usam e são a maneira preferencial de acessar as APIs do Google Play Services.
Consulte Como acessar as APIs do Google.
Neste guia, mostramos como:
- Gerencie automaticamente sua conexão com o Google Play Services.
- Realizar chamadas de API síncronas e assíncronas para qualquer um dos serviços do Google Play.
- Gerenciar manualmente sua conexão com o Google Play Services nos raros casos em que isso for necessários. Para saber mais, consulte Conexões gerenciadas manualmente.
Para começar, instale a biblioteca do Google Play Services (revisão 15 ou superior) para o SDK do Android. Caso ainda não tenha feito isso, siga as instruções em Configure o SDK do Google Play Services.
Iniciar uma conexão gerenciada automaticamente
Depois que seu projeto estiver vinculado à biblioteca do Google Play Services, crie uma instância do
GoogleApiClient
usando o
GoogleApiClient.Builder
nas APIs da instância
onCreate()
. A
GoogleApiClient.Builder
oferece métodos que permitem especificar as APIs do Google que você quer usar e as
escopos do OAuth 2.0. Aqui está um exemplo de código que cria uma
Instância do GoogleApiClient
que se conecta ao serviço do Google Drive:
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Drive.API) .addScope(Drive.SCOPE_FILE) .build();
É possível adicionar várias APIs e vários escopos ao mesmo
GoogleApiClient
anexando chamadas adicionais a addApi()
e addScope()
.
Importante:se você estiver adicionando a API Wearable
com outras APIs a uma
GoogleApiClient
, podem ocorrer erros de conexão com o cliente em dispositivos
não têm o app para Wear OS instalado. Para
evitar erros de conexão, chame o método addApiIfAvailable()
e transmita
a API Wearable
para permitir que seu cliente lide com as solicitações
API. Para mais informações, consulte Acessar a API Wearable.
Para iniciar uma conexão gerenciada automaticamente, você precisa especificar uma
implementação para OnConnectionFailedListener
para receber erros de conexão sem solução. Quando sua conta do Google Cloud
GoogleApiClient
tentar se conectar às APIs do Google, ela será automaticamente
interface de usuário de exibição para tentar corrigir falhas de conexão que podem ser resolvidas (por exemplo, se
o Google Play Services precisa ser atualizado). Se ocorrer um erro que não possa ser
resolvido, você receberá uma chamada para
onConnectionFailed()
Você também pode especificar uma implementação opcional para a interface ConnectionCallbacks
caso seu app precise saber quando o
uma conexão gerenciada automaticamente
é estabelecida ou suspensa. Por exemplo, se
seu app faz chamadas para gravar dados nas APIs do Google, elas devem ser chamadas
somente depois que o método onConnected()
for chamado.
Aqui está um exemplo de atividade que implementa as interfaces de callback e adiciona ao cliente da API do Google:
import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; import gms.drive.*; import android.support.v4.app.FragmentActivity; public class MyActivity extends FragmentActivity implements OnConnectionFailedListener { private GoogleApiClient mGoogleApiClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a GoogleApiClient instance mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Drive.API) .addScope(Drive.SCOPE_FILE) .build(); // ... } @Override public void onConnectionFailed(ConnectionResult result) { // An unresolvable error has occurred and a connection to Google APIs // could not be established. Display an error message, or handle // the failure silently // ... } }
Sua instância do GoogleApiClient
se conectará automaticamente após sua atividade
liga para onStart()
e se desconecta após chamar onStop()
.
Seu app pode começar a fazer
solicitações de leitura para as APIs do Google após a criação do GoogleApiClient
, sem
aguardando a conclusão da conexão.
Comunicar-se com os Serviços do Google
Após a conexão, o cliente pode fazer chamadas de leitura e gravação usando as APIs específicas do serviço para
quais seu aplicativo está autorizado, conforme especificado pelas APIs e pelos escopos adicionados ao
Instância de GoogleApiClient
.
Observação: antes de fazer chamadas para serviços específicos do Google, talvez seja necessário registrar seu no Google Developers Console. Para mais instruções, consulte o guia de para a API que você está usando, como Google Drive ou Login do Google.
Quando você executa uma solicitação de leitura ou gravação usando GoogleApiClient
, o cliente da API retorna um objeto PendingResult
que representa a solicitação.
Isso ocorre imediatamente, antes da solicitação ser entregue ao serviço do Google que seu app está chamando.
Por exemplo, aqui está uma solicitação para ler um arquivo do Google Drive que fornece um
Objeto PendingResult
:
Query query = new Query.Builder() .addFilter(Filters.eq(SearchableField.TITLE, filename)); PendingResult<DriveApi.MetadataBufferResult> result = Drive.DriveApi.query(mGoogleApiClient, query);
Depois que o app tiver um objeto PendingResult
,
o app poderá especificar se a solicitação será tratada como assíncrona ou síncrona.
Dica:seu app pode enfileirar solicitações de leitura enquanto não estiver conectado ao Google Play Services. Para
exemplo, seu app pode chamar métodos para ler um arquivo do Google Drive, mesmo que a instância do GoogleApiClient
ainda esteja conectada. Depois que uma conexão é estabelecida, as solicitações de leitura na fila são executadas. As solicitações de gravação geram um erro quando o app chama
Métodos de gravação do Google Play Services enquanto o cliente da API do Google não está conectado.
Como usar chamadas assíncronas
Para tornar a solicitação assíncrona, chame
setResultCallback()
no PendingResult
e forneça um
implementação do
ResultCallback
. Para
exemplo, veja a solicitação executada de forma assíncrona:
private void loadFile(String filename) { // Create a query for a specific filename in Drive. Query query = new Query.Builder() .addFilter(Filters.eq(SearchableField.TITLE, filename)) .build(); // Invoke the query asynchronously with a callback method Drive.DriveApi.query(mGoogleApiClient, query) .setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() { @Override public void onResult(DriveApi.MetadataBufferResult result) { // Success! Handle the query result. // ... } }); }
Quando seu app recebe um objeto Result
em
o callback onResult()
,
ele é entregue como uma instância da subclasse apropriada, conforme especificado pela API que você está usando,
como
DriveApi.MetadataBufferResult
.
Como usar chamadas síncronas
Se quiser que seu código seja executado em uma ordem estritamente definida, talvez porque o resultado de um
chamada é necessária como um argumento para outra, você pode tornar sua solicitação síncrona chamando
await()
no
PendingResult
Isso bloqueia a linha de execução
e retorna o objeto Result
quando o
é concluída. Esse objeto é entregue como uma instância da subclasse apropriada, conforme especificado pelo
a API que você está usando, por exemplo
DriveApi.MetadataBufferResult
Como chamar await()
bloqueia a linha de execução até que o resultado chegue, o aplicativo nunca deve fazer solicitações síncronas às APIs do Google no
linha de execução de IU. Seu app pode criar uma nova linha de execução usando um objeto AsyncTask
e usá-la para fazer a solicitação síncrona.
O exemplo a seguir mostra como fazer uma solicitação de arquivo ao Google Drive como uma chamada síncrona:
private void loadFile(String filename) { new GetFileTask().execute(filename); } private class GetFileTask extends AsyncTask{ protected void doInBackground(String filename) { Query query = new Query.Builder() .addFilter(Filters.eq(SearchableField.TITLE, filename)) .build(); // Invoke the query synchronously DriveApi.MetadataBufferResult result = Drive.DriveApi.query(mGoogleApiClient, query).await(); // Continue doing other stuff synchronously // ... } }
Acessar a API Wearable
A API Wearable fornece um canal de comunicação para apps executados em dispositivos portáteis e wearable. A API consiste em um conjunto de objetos de dados que o sistema pode enviar e sincronizar e listeners que notificam seus aplicativos sobre eventos importantes usando uma camada de dados. A A API Wearable está disponível em dispositivos com Android 4.3 (API de nível 18) ou versões mais recentes quando um dispositivo wearable está conectado e o app complementar do Wear OS está instalado no dispositivo.
Como usar a API Wearable independente
Caso seu app use a API Wearable, mas não outras APIs do Google, é possível adicionar essa API
chame o método addApi()
. O exemplo a seguir mostra como adicionar o
API Wearable à instância do GoogleApiClient
:
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Wearable.API) .build();
Quando a API Wearable não está disponível, as solicitações de conexão que
incluem a API Wearable falhar com o
API_UNAVAILABLE
código de erro.
O exemplo abaixo mostra como determinar se a API Wearable está disponível:
// Connection failed listener method for a client that only // requests access to the Wearable API @Override public void onConnectionFailed(ConnectionResult result) { if (result.getErrorCode() == ConnectionResult.API_UNAVAILABLE) { // The Wearable API is unavailable } // ... }
Como usar a API Wearable com outras APIs do Google
Caso seu app use a API Wearable além de outras APIs do Google, chame o método
addApiIfAvailable()
e transmita a API Wearable para verificar se ela está disponível. Use essa verificação para ajudar o aplicativo a processar adequadamente os casos em que a API não está disponível.
O exemplo abaixo mostra como acessar a API Wearable junto com a API Drive:
// Create a GoogleApiClient instance mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Drive.API) .addApiIfAvailable(Wearable.API) .addScope(Drive.SCOPE_FILE) .build();
No exemplo acima, o GoogleApiClient
pode se conectar com sucesso
Google Drive sem se conectar à API Wearable se ela estiver indisponível. Depois
Quando você conecta seu GoogleApiClient
verifique se a API Wearable está disponível antes de fazer chamadas de API:
boolean wearAvailable = mGoogleApiClient.hasConnectedApi(Wearable.API);
Como ignorar falhas de conexão de API
Se você chamar addApi()
e o GoogleApiClient
não conseguir
se conectar a essa API, toda a operação de conexão desse cliente vai falhar e
aciona o callback onConnectionFailed()
.
Você pode registrar uma falha de conexão de API para ser ignorada usando
addApiIfAvailable()
Se uma API adicionada com
Falha na conexão de addApiIfAvailable()
devido a um erro irrecuperável
(como API_UNAVAILABLE
para Wear),
essa API é descartada do GoogleApiClient
e o cliente continua para
se conectar a outras APIs. No entanto, se alguma conexão de API falhar com um erro recuperável (como uma
intent de resolução de consentimento OAuth), a operação de conexão do cliente vai falhar. Quando
usando uma conexão gerenciada automaticamente, o GoogleApiClient
tentará
resolver esses erros quando possível. Ao usar uma conexão gerenciada manualmente
um ConnectionResult
contendo uma intent de resolução é
entregues ao callback onConnectionFailed()
. API
falhas de conexão são ignoradas apenas se não houver resolução para a falha
e a API foi adicionada
com addApiIfAvailable()
.
Para saber como implementar a falha de conexão manual
o processamento de dados, consulte Solucionar falhas de conexão.
Como as APIs adicionadas com
addApiIfAvailable()
nem sempre estará presente nos arquivos
GoogleApiClient
, você precisa proteger as chamadas para essas APIs adicionando uma verificação
usando hasConnectedApi()
. Para saber por que um
uma determinada API falhar ao se conectar quando toda a operação de conexão for bem-sucedida para o cliente, chame
getConnectionResult()
e receba o código do erro do
objeto ConnectionResult
. Se o cliente chamar uma API quando ela não estiver
estiver conectado ao cliente, a chamada falhará com o
API_NOT_AVAILABLE
.
Se a API que você está adicionando pelo addApiIfAvailable()
exigir uma ou
mais escopos, adicione-os como parâmetros
chamada de método addApiIfAvailable()
em vez de usar o
addScope()
. Os escopos adicionados com essa abordagem não poderão ser solicitados se a API
falha antes de obter o consentimento do OAuth, enquanto os escopos adicionados com
addScope()
são sempre solicitadas.
Conexões gerenciadas manualmente
A maior parte deste guia mostra como usar
Método enableAutoManage
para iniciar uma
uma conexão gerenciada automaticamente com erros resolvidos automaticamente. Em quase
em todos os casos, essa é a maneira mais fácil e melhor de se conectar às APIs do Google do seu
App Android. No entanto, há algumas situações em que convém usar um
conexão gerenciada manualmente às APIs do Google no seu app:
- Para acessar as APIs do Google fora de uma atividade ou manter o controle delas conexão
- Para personalizar o tratamento e a resolução de erros de conexão
Esta seção fornece exemplos desses e de outros casos de uso avançados.
Iniciar uma conexão gerenciada manualmente
Para iniciar uma conexão gerenciada manualmente com o GoogleApiClient
, você precisa
especificar uma implementação para as interfaces de callback
ConnectionCallbacks
e OnConnectionFailedListener
.
Essas interfaces recebem callbacks em resposta ao método assíncrono
método connect()
quando o
conexão com o Google Play Services funciona, falha ou é suspensa.
mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(Drive.API) .addScope(Drive.SCOPE_FILE) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build()
Ao gerenciar uma conexão manualmente, você precisará chamar o método
connect()
e
disconnect()
métodos nos pontos certos do ciclo de vida do seu app. Em uma atividade
contexto, a prática recomendada é chamar connect()
no onStart()
da sua atividade
e disconnect()
no método onStop()
da sua atividade.
Os métodos connect()
e
Métodos disconnect()
são chamados automaticamente
ao usar uma conexão gerenciada automaticamente.
Se você estiver usando GoogleApiClient
para se conectar a APIs que exigem
de autenticação, como o Google Drive ou o Google Play Games, é provável que
na primeira tentativa de conexão, e o app vai receber uma chamada
para onConnectionFailed()
com o SIGN_IN_REQUIRED
porque a conta de usuário não foi especificada.
Lidar com falhas de conexão
Quando o app recebe uma chamada para o onConnectionFailed()
chame hasResolution()
nos ConnectionResult
fornecidos
objeto. Se retornar verdadeiro, o app poderá solicitar que o usuário aja imediatamente para resolver o erro.
Ligando para startResolutionForResult()
no objeto ConnectionResult
.
O método startResolutionForResult()
se comporta da mesma forma que startActivityForResult()
nessa situação,
e inicia uma atividade adequada ao contexto que ajuda o usuário a resolver o erro (como uma atividade que ajuda o usuário a
selecione uma conta).
Se hasResolution()
retornar falso, seu aplicativo deverá chamar
GoogleApiAvailability.getErrorDialog()
,
passando o código de erro para este método. Isso retorna uma
Dialog
fornecido pelo Google Play
serviços adequados para o erro. A caixa de diálogo pode simplesmente fornecer uma mensagem explicando
o erro ou também pode fornecer uma ação para iniciar uma atividade que possa resolver o erro
(por exemplo, quando o usuário precisa instalar uma versão mais recente do Google Play Services).
Por exemplo, seu
O método de callback onConnectionFailed()
vai ficar assim:
public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener { // Request code to use when launching the resolution activity private static final int REQUEST_RESOLVE_ERROR = 1001; // Unique tag for the error dialog fragment private static final String DIALOG_ERROR = "dialog_error"; // Bool to track whether the app is already resolving an error private boolean mResolvingError = false; // ... @Override public void onConnectionFailed(ConnectionResult result) { if (mResolvingError) { // Already attempting to resolve an error. return; } else if (result.hasResolution()) { try { mResolvingError = true; result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR); } catch (SendIntentException e) { // There was an error with the resolution intent. Try again. mGoogleApiClient.connect(); } } else { // Show dialog using GoogleApiAvailability.getErrorDialog() showErrorDialog(result.getErrorCode()); mResolvingError = true; } } // The rest of this code is all about building the error dialog /* Creates a dialog for an error message */ private void showErrorDialog(int errorCode) { // Create a fragment for the error dialog ErrorDialogFragment dialogFragment = new ErrorDialogFragment(); // Pass the error that should be displayed Bundle args = new Bundle(); args.putInt(DIALOG_ERROR, errorCode); dialogFragment.setArguments(args); dialogFragment.show(getSupportFragmentManager(), "errordialog"); } /* Called from ErrorDialogFragment when the dialog is dismissed. */ public void onDialogDismissed() { mResolvingError = false; } /* A fragment to display an error dialog */ public static class ErrorDialogFragment extends DialogFragment { public ErrorDialogFragment() { } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Get the error code and retrieve the appropriate dialog int errorCode = this.getArguments().getInt(DIALOG_ERROR); return GoogleApiAvailability.getInstance().getErrorDialog( this.getActivity(), errorCode, REQUEST_RESOLVE_ERROR); } @Override public void onDismiss(DialogInterface dialog) { ((MyActivity) getActivity()).onDialogDismissed(); } } }
Depois que o usuário preenche a caixa de diálogo fornecida pelo
startResolutionForResult()
ou dispensa a mensagem fornecida por GoogleApiAvailability.getErrorDialog()
,
sua atividade recebe
onActivityResult()
com a função
Código de resultado de RESULT_OK
.
Seu app pode chamar
connect()
novamente.
Exemplo:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_RESOLVE_ERROR) { mResolvingError = false; if (resultCode == RESULT_OK) { // Make sure the app is not already connected or attempting to connect if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } } }
No código acima, você provavelmente notou o booleano mResolvingError
. Isso acompanha
estado do aplicativo enquanto o usuário está resolvendo o erro para evitar tentativas repetitivas de resolver o mesmo
erro. Por exemplo, embora a caixa de diálogo do seletor de conta seja exibida para ajudar o usuário a resolver o
SIGN_IN_REQUIRED
o usuário poderá girar a tela. Isso recria a atividade e faz com que o
método onStart()
a ser
chamado novamente, que então chama
connect()
novamente. Isso
resulta em outra chamada para
startResolutionForResult()
,
que cria outra caixa de diálogo do seletor de conta na frente da existente.
Esse booleano serve à finalidade pretendida somente se persistir em todas as instâncias da atividade. A próxima seção explica como manter o estado de tratamento de erros do app, mesmo com outras ações do usuário ou eventos que ocorrem no dispositivo.
Manter o estado ao resolver um erro
Para evitar a execução do código em
onConnectionFailed()
enquanto uma tentativa anterior de resolver um erro está em andamento, você precisa reter um booleano que
rastreia se o app já está tentando resolver um erro.
Conforme mostrado no exemplo de código acima, seu app precisa definir um booleano como true
sempre que chamar
startResolutionForResult()
ou exibe a caixa de diálogo do
GoogleApiAvailability.getErrorDialog()
Então, quando seu app receber
RESULT_OK
no
onActivityResult()
defina o booleano como false
.
Para acompanhar o booleano entre as reinicializações da atividade (como quando o usuário gira a tela),
salve o booleano nos dados de instância salvos da atividade usando
onSaveInstanceState()
:
private static final String STATE_RESOLVING_ERROR = "resolving_error"; @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(STATE_RESOLVING_ERROR, mResolvingError); }
Depois, recupere o estado salvo durante
onCreate()
:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... mResolvingError = savedInstanceState != null && savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false); }
Agora você está pronto para executar o app com segurança e se conectar manualmente ao Google Play Services.