Enviando mensagens curtas para o Android via C2DM

Atenção: o Google C2DM não é mais recomendado pelo Google. Há agora o Google Cloud Messaging for Android (GCM), considerado sua nova versão.

Há um tipo de preocupação que aparece bastante nas turmas do nosso curso de Android: você precisa enviar uma notificação para um celular que instalou sua aplicação. Quais são as alternativas? Enviar um SMS e capturá-lo via API? Criar um sistema de push notification? Inventar um botão de sincronização? Uma thread que pinga o servidor de tempos em tempos? Todas essas são válidas, mas há uma possibilidade que pode se adequar melhor em certos casos: o C2DM, um sistema próprio do Google, criado justamente para o envio de mensagens curtas.

O C2DM (Cloud to Device Messaging) é um serviço que permite o envio de mensagens de um computador para um celular, previamente cadastrado, por meio da infraestrutura de cloud do Google.

Para utilizá-lo, temos que nos cadastrar no C2DM. Preencha o formulário em https://developers.google.com/android/c2dm/signup com os seus dados. No campo package name of your Android app guarde o nome que você escrever, pois o usaremos futuramente.

Após o término do cadastro, será enviado um e-mail para o endereço que foi colocado em Contact email; esse e-mail é um sinal de que o Google aceitou o seu cadastro e que já podemos criar aplicativos para usufruir do C2DM.

Como esse serviço funciona apenas para Android maior ou igual à versão 2.2, no Eclipse, crie um novo projeto com um SDK compatível. No campo package name, coloque o nome que foi previamente usado no cadastro. Na sua Activity, coloque o seguinte código para registrarmos nosso aparelho:

private void register() {
    Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");

    intent.putExtra("app", PendingIntent.getBroadcast(<wbr>this, 0, new Intent(), 0));
    intent.putExtra("sender", seu-email-usado-no-cadastro-<wbr>do-c2dm);

    startService(intent);
}

E de dentro do callback onCreate, invoque esse novo método, além de deixar algo visível para nosso teste:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    TextView tv = new TextView(this);
    tv.setText("Aplicação usando C2DM!");
    setContentView(tv);

    register();
}

Após isso, crie uma nova classe que mostrará o Id do nosso aparelho gerado pelo C2DM, assim que receber uma mensagem do servidor. O action do intent que será passado indicando o registro é “com.google.android.c2dm.intent.REGISTRATION“:

public class C2DM_RegistrationReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if ("com.google.android.c2dm.intent.REGISTRATION".equals(action)) {
            String registrationId = intent.getStringExtra("registration_id");
            Toast.makeText(context, "O Id recebido é " + registrationId, 
                        Toast.LENGTH_LONG).show();
        }
    }
}

Agora que podemos cadastrar nosso aparelho, temos que fazer uma classe que reconhecerá uma notificação vinda do C2DM e fará algo com ela. Para isso, crie a seguinte classe:

public class C2DM_MessageReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if ("com.google.android.c2dm.intent.RECEIVE".equals(action)) {
            String message = intent.getStringExtra("message");
            Toast.makeText(context, message, Toast.LENGTH_LONG).show();
        }
    }
}

Nesse ponto já temos uma aplicação simples que recebe mensagens do C2DM e as exibe na tela, mas ainda não sabemos como enviar uma mensagem por esse serviço. Temos que cadastrar um enviador! Para isso, pela linha de comando, execute o seguinte comando, que criará um enviador vinculado ao seu usuário do Google:

curl https://www.google.com/accounts/ClientLogin -d Email=seu_email_do_google \
-d Passwd=sua_senha -d accountType=GOOGLE -d source=Google-cURL-Example -d service=ac2dm

Na resposta, guarde com carinho o valor gigantesco que estiver em Auth, pois ele será usado para identificá-lo como enviador. Pronto! Para enviar uma mensagem do seu computador para o celular cadastrado, basta usar o seguinte comando pelo terminal:

curl --header "Authorization: GoogleLogin auth=hash-do-auth" "https://android.apis.google.com/c2dm/send" \
-d registration_id=registration-id-do-device -d "data.message=Minha mensagem aqui." -d collapse_key=0 -k

Obviamente você não enviará mensagens através do curl. Para isso, utilizará alguma biblioteca como o Apache http client.

Para usarmos o C2DM, temos que nos assegurar de que a nossa aplicação satisfaça duas exigências principais:

  • Ela não deve enviar mensagens grandes (há um limite de 1024 bytes);
  • Nossa aplicação não deve depender da sequência de envio das mensagens;
  • O uso ideal do C2DM é enviar um sinal para que sua aplicação efetue uma determinada ação, como, por exemplo, atualizar um arquivo de configuração, uma fonte de dados ou sincronizar suas informações.

Em conjunto com as classes auxiliares para sincronização de conteúdo, o C2DM facilita muito o nosso trabalho.

12 Comentários

  1. Roberto Nakasa 12/06/2012 at 13:56 #

    Parabéns! bon post.

  2. Walber 12/06/2012 at 15:32 #

    Muito bom!
    Surgiu uma dúvida que deva ser comum a todos os desenvolvedores e não achei na documentação que li.

    Sobre a quantidade de mensagens enviadas pelo servidor da app, se não me engano o campo QuotaExceeded da mensagem de erro, vocês tem alguma informação desta quantidade? Seria mais um daqueles casos onde o google vai cobrar no futuro (rs) e por enquanto seria infinitamente ilimitado?

  3. Felipe Torres 12/06/2012 at 15:52 #

    Oi Walber,

    segundo a página de cotas do C2DM, há um limite padrão gratuito de 200.000 mensagens por dia.
    No entanto, caso sua aplicação necessite de uma cota maior, é possível solicitar um aumento, que é pago.

    Abraço.

  4. Walber 12/06/2012 at 17:27 #

    Nossa, não havia tido tempo de vasculhar tudo. Esta cota é ótima!
    Obrigado e Parabéns.

  5. Peters 13/06/2012 at 11:17 #

    Muito boa alternativa mesmo, só restou uma dúvida, quanto ao Curl, posso usar por exemplo um script dentro de um html para fazer esse envio só “setando” as variaveis necessárias?

  6. Daniel 13/06/2012 at 11:39 #

    Belo post… Espero que a google libere valores maiores para envio e recebimento de mensagens

  7. Leonardo Bessa 13/06/2012 at 11:50 #

    Parabéns pelo post. Este será muito útil nos próximos dias.

  8. Demetrius F. Campos 13/06/2012 at 18:36 #

    Ótimo post. Uma vez fui procurar a respeito mas só achei posts em inglês ou em potuguês mal traduzido.

  9. Marcio 15/07/2012 at 21:04 #

    Este serviço foi descontinuado pelo google, agora se chama GCM (Google Cloud Messaging for Android).

    http://developer.android.com/guide/google/gcm/index.html

  10. Marco Maddo 26/07/2012 at 12:39 #

    Parabéns pela escolha do tema do seu post, bem atual e de aplicação imediata.

    Como o serviço foi descontinuado pelo Google, que agora passa a ser GCM, que tal atualizar seu post?

  11. Paulo Silveira 26/07/2012 at 19:49 #

    Oi Marco

    Pretendemos fazer um post sobre o GCM também.

  12. Adelcio Porto 13/11/2012 at 18:07 #

    Estou desenvolvendo um rastreador para android (baixe gratuito do play store. Chama-se FollowWell) e estava sentindo a necessidade de uma maneira de descobrir se o rastreador está ativado em determinado celular. Parece que esta solução vai resolver o problema. Obrigado!

Deixe uma resposta