google cloud messaging for android
TRANSCRIPT
IntroduIntroduçção ao Google ão ao Google CloudCloud MessagingMessaging
Edilson Mendes Bizerra [email protected]@edilsonmendess
Edilson Mendes
� Mestre em Engenharia da Computação pela
Universidade de Pernambuco
� Engenheiro de Sistemas do Centro de Estudos
e Sistema Avançados do Recife (C.E.S.A.R)
desde 2005
� Professor de Android da Faculdade de
Filosofia Ciências e Letras de Caruaru (FAFICA)
Agenda
� Motivação
� Pulling vs Pushing
� Google Cloud Messaging (GCM)
� Principais Características
� Funcionamento
� A requisição e a resposta
� GCM na Prática
� Habilitando o GCM
� Instalando as Helper Libraries
� A Aplicação Cliente
� A Aplicação Servidora
Motivação
Uso de internet nos smartphones cresce a cada dia
Considerando uma aplicação cliente
(android)/servidor (aplicação web qualquer)
Exemplos: Sistema de notícias, placar de futebol, divulgação de propagandas, avisos em geral, etc.
Como manter os dados do
cliente sempre atualizados?
Como manter os dados do
cliente sempre atualizados?
E se quisermos enviar uma mensagem para algum(uns) cliente(s)?
E se quisermos enviar uma mensagem para algum(uns) cliente(s)?
Existem duas técnicas básicas que podemos
utilizar: Pulling e Pushing
Existem duas técnicas básicas que podemos
utilizar: Pulling e Pushing
Pulling
Simples de Implementar
Aparelho consulta de tempos e tempos o servidor a fim de obter dados atualizados
Mas...
Conexão Wifi e
3G drenam sua bateriaem poucas horas
A
autonomiada bateria dos smartphones
não é boa
Só para se ter uma idéia...
Fazer requisições a cada 5 minutos pode consumir
aproximadamente 10% da
sua bateria por dia
Pode parecer pouco, mas é um absurdo para uma única aplicação
Não sabemos se teremos novas informações, tentamoscegamente
Além disso...
Notificação usando pulling sempre terá um atraso
Atraso
Aumentar oudiminuir o tempo entre as requisições?
Caímos então no problema Eficiência X Dados Sincronizados
Com o pullingconsumimosmais dados
Os planos de dados no Brasil são caros e não prestam!
Tráfico no lado do servidor
Cada dispositivo, a cada n minutos bombardeando o Servidor
PushingO servidor notifica o cliente quando tiver novos dados
Apenas usa rede (e bateria) quando necessárioComo implementar?
• SMS?• Conexão permanente?• Google Cloud Messaging?
SMS
Simples de implementar
É muito fácil interceptar um SMS no Android
Simples de implementar
É muito fácil interceptar um SMS no Android
Pode ser muito caro� Poucos serviços de envio de SMS de graça
� Muito deles possuem algum tipo de limitação (quantidade de mensagens ou localização)
� Lembre-se, pessoas de todo o mundo podem baixar sua aplicação do Google Play
� Necessidade de contratar um serviço pago de envio de SMS
Pode ser muito caro� Poucos serviços de envio de SMS de graça
� Muito deles possuem algum tipo de limitação (quantidade de mensagens ou localização)
� Lembre-se, pessoas de todo o mundo podem baixar sua aplicação do Google Play
� Necessidade de contratar um serviço pago de envio de SMS
Informações em “tempo-real”
Informações em “tempo-real”
Conexão Permanente
O ideal era que essa responsabilidade não fosse da aplicação
Exemplo: Banco de Dados
O ideal era que essa responsabilidade não fosse da aplicação
Exemplo: Banco de Dados
Difícil de implementar (no cliente e servidor)
Algumas preocupações: identificar e diferenciar os aparelhos, entrega de mensagem, e se o aparelho estiver desligado?
Difícil de implementar (no cliente e servidor)
Algumas preocupações: identificar e diferenciar os aparelhos, entrega de mensagem, e se o aparelho estiver desligado?
Google Cloud Messaging (GCM) for Android é um serviçogratuito que ajuda os desenvolvedores a enviar dados de aplicativos no servidor para aplicações Android.
O GCM trata todos os aspectos de fila e entrega de mensagens
Principais características
Dois tipos de mensagens: Send-to-Sync ou Mensagens com payload(limite de 4kb)
Dois tipos de mensagens: Send-to-Sync ou Mensagens com payload(limite de 4kb)
GCM não garante a ordem e entrega da mensagem
GCM não garante a ordem e entrega da mensagem
Um aplicativo Android não precisa estar em execução para receber mensagens
Um aplicativo Android não precisa estar em execução para receber mensagens
GCM não faz tratamento nos dados ou fornece inteface gráfica
GCM não faz tratamento nos dados ou fornece inteface gráfica
Principais características
Requer Android 2.2+ com o Google Play Store, ou um emulador com Android 2.2+ com Google APIs.
Requer Android 2.2+ com o Google Play Store, ou um emulador com Android 2.2+ com Google APIs.
É necessária uma conta do Google no dispositivo se o Android for inferior ao 4.0.4.
É necessária uma conta do Google no dispositivo se o Android for inferior ao 4.0.4.
Usa a mesma conexão dos serviços do Google (Gmail, Contatos, etc).
Usa a mesma conexão dos serviços do Google (Gmail, Contatos, etc).
Continuação do Cloud to Device Messaging (C2DM)Continuação do Cloud to Device Messaging (C2DM)
GCM
Android Application
GCM
Server ApplicationGoogle Cloud Messaging
1
23
4
5
6
Funcionamento
A aplicação Android, GCM e aplicação servidora precisam se conhecer entre si
Credenciais
Android Application Server Application
GCM
Google Cloud Messaging
Project Number
API KeyRegistration ID
https://android.googleapis.com/gcm/send
Android Application Server Application
GCM
Google Cloud Messaging
Registro da Aplicação Android
Project
Number
Registration ID
Registration ID
Android Application Server Application
Envio de Dados
Mensagem
HTTP Post contendo
API Key + Reg IDs +
Dados (https://android.google
apis.com/gcm/send)
GCM
Google Cloud Messaging
Resposta
Busca novos dados
A Requisição
� Para enviar uma mensagem o servidor deve realizar
uma requisição HTTP POST para
https://android.googleapis.com/gcm/send.
� Duas formas de criar a requisição e a resposta:
� Plain Text (limitado, não suporta multicast
message)
� JSON
Formato da Requisição (JSON)
� A requisição necessita dos seguintes cabeçalhos HTTP
� Authorization: key=YOUR_API_KEY
� Content-Type: application/json
� O corpo HTTP deve conter uma string representando
um objeto JSON com os seguintes campos:
� registration_ids, data, collapse_key, etc
Exemplo
Content-Type:application/json
Authorization:key=AIzaSyB-1uEai2WiUapxCs2Q0GZYzPu7Udno5aA
{
"registration_ids" : ["APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx..."],
"data": {
"score": "5x1",
"time": "15:10"
},
}
� Array de Strings com os registration IDs dos dispositivos (pelo
menos 1 e no máximo 1000) que receberão a mensagem
{
"collapse_key": "score_update",
"time_to_live": 108,
"delay_while_idle": true,
"data": {
"score": "4x8",
"time": "15:16.2342"
},
"registration_ids":["4", "8", "15", "16", "23", "42"]
}
� Descarta mensagens sobre o mesmo tema, armazenadas
enquanto o dispositivo estava offline, enviando apenas a mais
recente
� O GCM permite no máximo 4 collapse keys ao mesmo tempo
{
"collapse_key": "score_update",
"time_to_live": 108,
"delay_while_idle": true,
"data": {
"score": "4x8",
"time": "15:16.2342"
},
"registration_ids":["4", "8", "15", "16", "23", "42"]
}
� Objeto JSON cujos campos são os pares chave-valor com dados
da mensagem.
� Não há limite para o número de pares chave-valor (o tamanho
total da mensagem < 4kb)
{
"collapse_key": "score_update",
"time_to_live": 108,
"delay_while_idle": true,
"data": {
"score": "4x8",
"time": "15:16.2342"
},
"registration_ids":["4", "8", "15", "16", "23", "42"]
}
� Tempo (padrão são 4 semanas), em segundos, que a mensagem é mantida
no GCM enquanto o dispositivo está offline
� Limite de 100 mensagens, após isso as mensagens armazenadas são
descartadas e quando o dispositivo estiver online recebe uma mensagem
especial informando o número de mensagens descartadas
{
"collapse_key": "score_update",
"time_to_live": 108,
"delay_while_idle": true,
"data": {
"score": "4x8",
"time": "15:16.2342"
},
"registration_ids":["4", "8", "15", "16", "23", "42"]
}
� Se definido para true (padrão é false), indica que a mensagem
não deve ser enviada imediatamente se o dispositivo está em
idle.
{
"collapse_key": "score_update",
"time_to_live": 108,
"delay_while_idle": true,
"data": {
"score": "4x8",
"time": "15:16.2342"
},
"registration_ids":["4", "8", "15", "16", "23", "42"]
}
A Resposta{
"multicast_id": 216,
"success": 3,
"failure": 3,
"canonical_ids": 1,
"results": [
{ "message_id": "1:0408" },
{ "error": "Unavailable" },
{ "error": "InvalidRegistration" },
{ "message_id": "1:1516" },
{ "message_id": "1:2342", "registration_id": "32" },
{ "error": "NotRegistered"}
]
}
GCM na prGCM na prááticatica
Habilitando o GCM
1. Acessar o Google APIs Console
(https://code.google.com/apis/console) e criar um novo
projeto.
2. No primeiro acesso aparecerá a página acima, clique em
Create Project...
Habilitando o GCM
4. Sua URL irá mudar para algo como:
https://code.google.com/apis/console/#project:4815162342
5. Em seguida, clique em Services no painel esquerdo e
habilite o Google Cloud Messaging for Android.
Gerando a API Key
1. Acesse API Access e clique em Create new Server Key... Ou
Create new Browser key... para gerar a API key. A API key
é usada para fazer requisições ao servidor GCM
Instalando as Helper Libraries
1. Abra o SDK Manager e na se instale o Google Cloud Messaging for Android Library na seção Extras
2. Após a instalação, serão criados os arquivos gcm-client/dist/gcm.jar e gcm-server/dist/gcm-server.jar dentro da pasta
YOUR_SDK_ROOT/extras/google/gcm
A Aplicação Cliente (AndroidManifest.xml)
<permission android:name="my_app_package.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission
android:name="my_app_package.permission.C2D_MESSAGE" />
<!-- App receives GCM messages. -->
<uses-permission
android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received.
-->
<uses-permission android:name="android.permission.WAKE_LOCK" />
A Aplicação Cliente (AndroidManifest.xml)
<receiver android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action
android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="my_app_package" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
A Aplicação Cliente (GCMIntentService )import com.google.android.gcm.GCMBaseIntentService;
public class GCMIntentService extends GCMBaseIntentService {
private static final String PROJECT_ID = "337954533874";
public GCMIntentService() {
super(PROJECT_ID);
}
protected void onRegistered(Context ctx, String regId) {}
protected void onUnregistered(Context ctx, String regId) {}
protected void onMessage(Context ctx, Intent intent) {
String score = intent.getStringExtra("score");
}
protected void onDeletedMessages(Context ctx, int total) {}
public void onError(Context ctx, String errorId) {}
protected boolean onRecoverableError(Context ctx, String errorId) {}
}
Adicionar no classpath
SDK_ROOT/extras/google/gcm/
gcm-client/dist/gcm.jar
A Aplicação Cliente (Activity)
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
GCMRegistrar.register(this, PROJECT_ID);
} else {
Log.v(TAG, "Already registered");
}
import com.google.android.gcm.GCMRegistrar;
A Aplicação Servidora (Envio)
import com.google.android.gcm.server.*;
List<String> devices = new ArrayList<String>();
devices.add("4");
// ...
devices.add("43");
Sender sender = new Sender(API_KEY);
Message message = new Message.Builder()
.collapseKey("score_update")
.timeToLive(108)
.delayWhileIdle(true)
.addData("score", "4x8")
.addData("time", "15:16.2342")
.build();
MulticastResult result = sender.send(message, devices, 1);
Adicionar no classpath
(SDK_ROOT/extras/google
/gcm) gcm-
server/dist/gcm-
server.jar
e
gcm-
server/lib/json_simple-
1.1.jar
A Aplicação Servidora (Resposta)MulticastResult multicastResult = sender.send(message, devices, 1);
multicastResult.getCanonicalIds();
multicastResult.getFailure();
multicastResult.getSuccess();
multicastResult.getMulticastId();
multicastResult.getTotal();
for (Result result : multicastResult.getResults()) {
if (result.getMessageId() != null) {
String canonicalRegId = result.getCanonicalRegistrationId();
if (canonicalRegId != null) {
// same device has more than on registration ID: update
// database
}
} else {
String error = result.getErrorCodeName();
if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
// application has been removed from device - unregister
// database
}
}
}
DDúúvidasvidas
Referências
• http://developer.android.com/guide/google/g
cm/index.html
• http://www.androidhive.info/2012/10/androi
d-push-notifications-using-google-cloud-
messaging-gcm-php-and-mysql/
• http://www.slideshare.net/johannilsson/foss-
sthlm-android-cloud-to-device-messaging
Obrigado!!!Obrigado!!!
Edilson Mendes Bizerra [email protected]@edilsonmendess
Edilson Mendes Bizerra [email protected]@edilsonmendess