Notificações por push na plataforma Android

266

Estou procurando escrever um aplicativo que receba alertas enviados de um servidor. Encontrei alguns métodos para fazer isso.

  1. SMS - intercepte o SMS recebido e inicie um pull do servidor
  2. Pesquise o servidor periodicamente

Cada um tem suas próprias limitações. SMS - sem garantia na hora de chegada. A pesquisa pode esgotar a bateria.

Você tem uma sugestão melhor, por favor? Muito obrigado.

Vinod
fonte
4
Você também pode assistir à Apresentação do Google I / O 2010 sobre a notificação por push developer.android.com/videos/index.html#v=PLM4LajwDVc
vokilam 02/02/11
Acho que você pode olhar para este post: stackoverflow.com/questions/17629942/… Com o Worklight, você pode receber push por diferentes canais, incluindo o GCM.
Neeraj Krishna
1
A apresentação do Google I / O 2010 está disponível em youtube.com/watch?v=PLM4LajwDVc
elcuco
"A enquete pode esgotar a bateria." Você pode agendar uma votação com o AlarmManager, para que a bateria não seja muito pesada. É uma solução simples e gratuita (sem necessidade de pagar, como no GCM).
Deepscorn
tem o mesmo problema stackoverflow.com/questions/35812304/…
albert

Respostas:

203

A resposta oficial do Google é o Android Cloud to Device Messaging Framework (descontinuado) Google Cloud Messaging (descontinuado) Firebase Cloud Messaging

Ele funcionará no Android> = 2.2 (em telefones que possuem a Play Store).

BoD
fonte
está na versão beta no momento, mas você pode se inscrever na esperança de ser ativado.
brack
3
Geralmente, você pode ser ativado muito rapidamente e está sendo usado para coisas como o GMail, por isso é sabido que funciona na produção. Infelizmente, seu código de amostra para se comunicar com o aspecto do servidor do C2DM está ausente. Eu escrevi um tutorial para esse aspecto aqui blog.boxedice.com/2010/10/07/…
davidmytton
6
O problema é que você precisa de uma conta do Google para seus usuários: o que, penso eu, é uma restrição.
kaffein
33
Observe que o Android Cloud to Device Messaging Framework foi descontinuado. O novo quadro é chamado Google Cloud Messaging e pode ser encontrado aqui: developer.android.com/guide/google/gcm/index.html
Ryan Berger
Em 10 de abril de 2018, o Google reprovou o GCM. As APIs do servidor e do cliente GCM foram removidas em 29 de maio de 2019. Migre os aplicativos GCM para o Firebase Cloud Messaging (FCM), que herda a infraestrutura GCM confiável e escalável, além de muitos novos recursos. Consulte o guia de migração para saber mais.
paiego 13/04
29

( postagem cruzada de uma resposta que eu dei a uma pergunta semelhante - o Android suporta notificação por push quase em tempo real? )

Recentemente, comecei a jogar com o MQTT http://mqtt.org para Android como uma maneira de fazer esse tipo de coisa (por exemplo, notificação por push que não é SMS, mas orientada por dados, entrega quase imediata de mensagens, não pesquisa etc.)

Tenho uma postagem no blog com informações básicas sobre isso, caso seja útil

http://dalelane.co.uk/blog/?p=938

(Nota: MQTT é uma tecnologia IBM e devo salientar que trabalho para IBM.)

dalelane
fonte
Olá Dale, li o seu post sobre o MQTT e, definitivamente, parece ser adequado para a notificação quase instantânea em celulares. Mas não consegui encontrar nenhuma informação sobre como ele realmente faz isso. Mantém um soquete aberto o tempo todo? Como ele notifica o servidor se seu endereço IP foi alterado? Agradeceria se você pudesse lançar alguma luz sobre isso. Cheers Naren
Naren
2
Ele mantém uma conexão aberta. Em um post de acompanhamento ( dalelane.co.uk/blog/?p=1009 ), falei mais sobre as implicações de manter uma conexão aberta - você viu isso? Se a conexão for interrompida, o servidor e o cliente poderão ser notificados. Depois, é uma decisão da camada de aplicação decidir como responder (por exemplo, reconectar). Há mais informações nos documentos mencionados na postagem (por exemplo, IA92: www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006 pdf nessa página e Javadoc no zip nessa página)
dalelane 5/11/2009
18

Minha compreensão / experiência com a notificação por push do Android são:

  1. C2DM GCM - Se a sua plataforma Android de destino for 2.2+, vá em frente. Apenas uma captura, os usuários do dispositivo precisam sempre estar logados com uma Conta do Google para receber as mensagens.

  2. MQTT - Abordagem baseada em pub / sub, precisa de uma conexão ativa do dispositivo, pode descarregar a bateria se não for implementada com sensibilidade.

  3. Diácono - pode não ser bom a longo prazo devido ao apoio limitado da comunidade.

Editar : Adicionado em 25 de novembro de 2013

GCM - o Google diz ...

Para dispositivos anteriores à 3.0, isso exige que os usuários configurem sua conta do Google em seus dispositivos móveis. Uma conta do Google não é um requisito para dispositivos com Android 4.0.4 ou superior. *

Lalit
fonte
Embora uma conta do Google não seja necessária para 4.0.4 ou superior, parece exigir que você tenha o aplicativo Google Play instalado. Gostaria de saber como você instala isso sem ter uma conta do Google.
Janeiro
1
@ Jan: O aplicativo Google Play vem instalado com o dispositivo. O usuário não precisa instalar.
Dexter
@Dexter, nem todos os dispositivos Android têm o Google Play instalado por padrão. A maioria tem instalado por padrão, especialmente os dispositivos comprados de fornecedores de telefones conceituados, mas os dispositivos que apenas têm o SO Android atualizado para eles nem sempre podem ter o Google Play. (Por exemplo, muitos emuladores do Android, como os novos dispositivos Genymotion, não têm o Google Play por padrão.)
Spencer D
Então ... O MQTT é a melhor opção para dispositivos Android que não possuem o Google Play instalado?
Yeung
17

Estrutura de mensagens da nuvem para o dispositivo Android

Importante: O C2DM foi oficialmente descontinuado em 26 de junho de 2012. Isso significa que o C2DM parou de aceitar novos usuários e solicitações de cota. Nenhum novo recurso será adicionado ao C2DM. No entanto, os aplicativos que usam o C2DM continuarão funcionando. Os desenvolvedores existentes do C2DM são incentivados a migrar para a nova versão do C2DM, chamada Google Cloud Messaging para Android (GCM). Consulte o documento de migração do C2DM para o GCM para obter mais informações. Os desenvolvedores devem usar o GCM para novos desenvolvimentos.

Por favor, verifique o seguinte link:

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

chiranjib
fonte
17

Aqui, escrevi alguns passos para Como obter RegID e Notificação a partir do zero

  1. Criar / registrar aplicativo no Google Cloud
  2. Configurar o Cloud SDK com desenvolvimento
  3. Configurar projeto para GCM
  4. Obter ID de registro do dispositivo
  5. Enviar notificações por push
  6. Receber notificações push

Você pode encontrar o tutorial completo no link da URL abaixo

Introdução à notificação por push do Android: o mais recente Google Cloud Messaging (GCM) - tutorial completo passo a passo

insira a descrição da imagem aqui

Recorte de código para obter a ID de registro (token de dispositivo para notificação por push).

Configurar projeto para GCM


Atualizar arquivo AndroidManifest

Para ativar o GCM em nosso projeto, precisamos adicionar poucas permissões em nosso arquivo de manifesto. Vá para AndroidManifest.xml e adicione o código abaixo.

<uses-permission android:name="android.permission.INTERNET”/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<uses-permission android:name="android.permission.VIBRATE" />

<uses-permission android:name=“.permission.RECEIVE" />
<uses-permission android:name=“<your_package_name_here>.permission.C2D_MESSAGE" />
<permission android:name=“<your_package_name_here>.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

Adicionar declaração de receptor de transmissão GCM

adicione a declaração do GCM Broadcast Receiver na tag do seu aplicativo

<application
        <receiver
            android:name=".GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" ]]>
            <intent-filter]]>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="" />
            </intent-filter]]>

        </receiver]]>
     
<application/>

Adicionar declaração GCM Servie

<application
     <service android:name=".GcmIntentService" />
<application/>

Obter ID de registro (token de dispositivo para notificação por push)

Agora vá para sua atividade de inicialização / splash

Adicionar constantes e variáveis ​​de classe

private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
public static final String EXTRA_MESSAGE = "message";
public static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "appVersion";
private final static String TAG = "LaunchActivity";
protected String SENDER_ID = "Your_sender_id";
private GoogleCloudMessaging gcm =null;
private String regid = null;
private Context context= null;

Atualizar os métodos OnCreate e OnResume

@Override
protected void onCreate(Bundle savedInstanceState)
{
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_launch);
     context = getApplicationContext();
         if (checkPlayServices()) 
     {
            gcm = GoogleCloudMessaging.getInstance(this);
            regid = getRegistrationId(context);

            if (regid.isEmpty())
            {
                registerInBackground();
            }
            else
            {
            Log.d(TAG, "No valid Google Play Services APK found.");
            }
      }
 }

@Override protected void onResume()
{
       super.onResume();       checkPlayServices();
}


# Implement GCM Required methods (Add below methods in LaunchActivity)

private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                        PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Log.d(TAG, "This device is not supported - Google Play Services.");
                finish();
            }
            return false;
        }
        return true;
 }

private String getRegistrationId(Context context) 
{
   final SharedPreferences prefs = getGCMPreferences(context);
   String registrationId = prefs.getString(PROPERTY_REG_ID, "");
   if (registrationId.isEmpty()) {
       Log.d(TAG, "Registration ID not found.");
       return "";
   }
   int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
   int currentVersion = getAppVersion(context);
   if (registeredVersion != currentVersion) {
        Log.d(TAG, "App version changed.");
        return "";
    }
    return registrationId;
}

private SharedPreferences getGCMPreferences(Context context) 
{
    return getSharedPreferences(LaunchActivity.class.getSimpleName(),
                Context.MODE_PRIVATE);
}

private static int getAppVersion(Context context) 
{
     try 
     {
         PackageInfo packageInfo = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0);
            return packageInfo.versionCode;
      } 
      catch (NameNotFoundException e) 
      {
            throw new RuntimeException("Could not get package name: " + e);
      }
}


private void registerInBackground() 
{     new AsyncTask() {
     Override
     protected Object doInBackground(Object... params) 
     {
          String msg = "";
          try 
          {
               if (gcm == null) 
               {
                        gcm = GoogleCloudMessaging.getInstance(context);
               }
               regid = gcm.register(SENDER_ID);               Log.d(TAG, "########################################");
               Log.d(TAG, "Current Device's Registration ID is: "+msg);     
          } 
          catch (IOException ex) 
          {
              msg = "Error :" + ex.getMessage();
          }
          return null;
     }     protected void onPostExecute(Object result) 
     { //to do here };
  }.execute(null, null, null);
}

Nota : armazene REGISTRATION_KEY, é importante que o envio de mensagens PN para o GCM também mantenha o meu, isso será exclusivo para todos os dispositivos. Ao usar isso, apenas o GCM enviará a notificação por push.

Receber notificações push

Adicionar classe de receptor de transmissão GCM

Como já declaramos “GcmBroadcastReceiver.java” em nosso arquivo Manifest, então vamos criar esse código de classe receptor de atualização de classe dessa maneira

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) 
    {        ComponentName comp = new ComponentName(context.getPackageName(),
                GcmIntentService.class.getName());        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);
        Toast.makeText(context, wow!! received new push notification", Toast.LENGTH_LONG).show();
    }
}

Adicionar classe de serviço GCM

Como já declaramos “GcmBroadcastReceiver.java” em nosso arquivo Manifest, então vamos criar esse código de classe receptor de atualização de classe dessa maneira

public class GcmIntentService extends IntentService
{     public static final int NOTIFICATION_ID = 1;     private NotificationManager mNotificationManager;     private final static String TAG = "GcmIntentService";     public GcmIntentService() {
     super("GcmIntentService");     
     }     @Override
     protected void onHandleIntent(Intent intent) {
          Bundle extras = intent.getExtras();
          Log.d(TAG, "Notification Data Json :" + extras.getString("message"));

          GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
          String messageType = gcm.getMessageType(intent);          if (!extras.isEmpty()) {          if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
               .equals(messageType)) {
               sendNotification("Send error: " + extras.toString());
          } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
          .equals(messageType)) {
          sendNotification("Deleted messages on server: "
          + extras.toString());          // If it's a regular GCM message, do some work.
          } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
          .equals(messageType)) {
          // This loop represents the service doing some work.
          for (int i = 0; i < 5; i++) {
               Log.d(TAG," Working... " + (i + 1) + "/5 @ "
               + SystemClock.elapsedRealtime());               try {
                    Thread.sleep(5000);
               } catch (InterruptedException e) {
               }
             }
             Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
             sendNotification(extras.getString("message"));
           }
        }        // Release the wake lock provided by the WakefulBroadcastReceiver.
        GcmBroadcastReceiver.completeWakefulIntent(intent);
     }     // Put the message into a notification and post it.
     // This is just one simple example of what you might choose to do with
     // a GCM message.
     private void sendNotification(String msg) {          mNotificationManager = (NotificationManager) this
          .getSystemService(Context.NOTIFICATION_SERVICE);
          PendingIntent contentIntent = PendingIntent.getActivity(this, 0,          new Intent(this, LaunchActivity.class), 0);

          NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(          this)
          .setSmallIcon(R.drawable.icon)
          .setContentTitle("Ocutag Snap")
          .setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
          .setContentText(msg)
          .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);

          mBuilder.setContentIntent(contentIntent);          mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
     }
}
swiftBoy
fonte
@Rohit você verificou o link com o tutorial completo. Também, por favor, deixe-me saber o que está faltando. Atualizarei a resposta.
usar o seguinte código
11

Há um novo esforço de código aberto para desenvolver uma biblioteca Java para notificações push no Android com base no servidor da web Meteor. Você pode conferir no Deacon Project Blog , onde encontrará links para Meteor e o repositório GitHub do projeto. Precisamos de desenvolvedores, então espalhe a palavra!

mtbkrdave
fonte
9

Você pode usar o Xtify ( http://developer.xtify.com ) - eles têm um serviço da web de notificações por push que funciona com seu SDK. é gratuito e, até agora, funcionou muito bem para mim.

Peter
fonte
3
Recebi uma resposta do vice-presidente dizendo que não há planos de cobrar pelo serviço de envio. É um SDK incrível.
Crowe T. Robot
8

ou....

3) Mantenha uma conexão com o servidor, envie keep-alives a cada poucos minutos, e o servidor poderá enviar mensagens instantaneamente. É assim que o Gmail, o Google Talk etc. funcionam.

Isaac Waller
fonte
5
Infelizmente, acho que isso produzirá uma quantidade considerável de bateria. Se você seguir esse caminho, limite a quantidade de tempo que fizer isso.
HASEMAN
Não, na verdade, não vai, porque as conexões TCP / IP ociosas quase não usam energia no modem celular.
Isaac Waller
Na verdade, vai demorar muito tempo, então você está certo. O envio de keep-alives com longos intervalos também ajuda muito.
Isaac Waller
O que são "longos intervalos" a esse respeito? Eu sei que o push do gmail funciona assim, mas não sei quais intervalos de tempo limite eles usam.
tobsen
Eu encontrei esta imagem sobre Pull desempenho da bateria vs push: labs.ericsson.com/files/battery.jpg Levei-o a partir da API Ericsson Empurre aqui: labs.ericsson.com/apis/mobile-java-push/documentation
Menda
6

Eu recomendo usar o GCM - Google Cloud Messaging para Android. É grátis e, para usos simples, deve ser muito fácil.

No entanto, é necessário manter um servidor do terceiro lado para enviar as notificações em seu nome. Se você deseja evitar que haja algumas soluções industriais muito boas para o serviço de notificações por push do Android:

  • Dirigível urbano - livre até 1 milhão de notificações por mês, depois você é cobrado por 1.000 notificações
  • PushApps - gratuito para notificações de 1 milhão por mês e notificações ilimitadas por 19,99 por mês
  • PushWoosh - gratuito para dispositivos 1M, os planos premium são de 39 EURO

Diclaimer - Trabalho no PushApps e também uso o produto em meus aplicativos há mais de um ano.

Orr
fonte
6

A partir de 18/05/2016, o Firebase é a plataforma unificada do Google para desenvolvedores de dispositivos móveis, incluindo notificações push.

Freek Nortier
fonte
4

Receio que você tenha encontrado os dois métodos possíveis. O Google estava, pelo menos inicialmente, implementando uma API do GChat que você poderia usar para uma implementação push / pull. Infelizmente, essa biblioteca foi cortada pelo Android 1.0.

haseman
fonte
1
Eles prometeram devolvê-lo assim que os problemas de segurança forem resolvidos ... se isso acontecer.
Jeremy Logan
3

Não sei se isso ainda é útil. Consegui algo assim com uma biblioteca java em http://www.pushlets.com/

Althoug fazê-lo em um serviço não impedirá o android de desligá-lo e matar o segmento do ouvinte.

n3utrino
fonte
2

C2DM: os usuários do seu aplicativo devem ter a conta do Gmail.

MQTT: quando sua conexão chegou a 1024, ele parará de funcionar por causa do uso de "selecionar modelo" do linux.

Há um serviço de push gratuito e API para Android, você pode experimentá-lo: http://push-notification.org

Jacky
fonte
2

Método gratuito e fácil:

Se a sua base de usuários-alvo não for grande (menor que 1000) e você quiser um serviço gratuito, o Airbop é o melhor e o mais conveniente.

Site da Airbop Ele usa o serviço Google Cloud Messaging por meio de sua API e fornece um bom desempenho. usei-o para dois dos meus projetos e foi fácil implementá-lo.

Serviços como o Urbanship são excelentes, mas fornecem uma pilha de implantação inteira e não apenas a coisa das notificações por push.

Se apenas o serviço push for seu objetivo, o Airbop funcionará bem.

Eu não usei o Pushwoosh , mas também é uma ótima opção. Permite enviar para 1.000.000 de dispositivos gratuitamente

adimoh
fonte
1

Eu sugeriria o uso de SMS e HTTP. Se o usuário não estiver conectado, envie um SMS ao telefone para notificá-lo de que há uma mensagem aguardando.

É assim que este serviço do Ericsson Labs funciona: https://labs.ericsson.com/apis/mobile-java-push/

Se você implementar isso sozinho, a parte complicada é excluir o SMS recebido sem que o usuário o veja. Ou talvez esteja tudo bem se eles virem no seu caso.

Parece que funciona: Excluindo SMS usando o BroadCastReceiver - Android

Sim, escrever um código como esse pode ser perigoso e você pode arruinar a vida de alguém porque seu aplicativo excluiu um SMS que não deveria ter.

Sarel Botha
fonte
1
lol: "Sim, escrever um código como esse pode ser perigoso e você pode arruinar a vida de alguém porque seu aplicativo excluiu um SMS que não deveria ter." voto positivo por isso. ri muito.
precisa saber é o seguinte
O link para o Mobile Java Push está inoperante e o próprio serviço parece estar obsoleto.
NaXa
1

Você pode usar o Google Cloud Messaging ou GCM , é gratuito e fácil de usar. Além disso, você pode usar servidores push de terceiros como o PushWoosh, o que oferece mais flexibilidade

Mohsen Afshin
fonte
1

Existem muitos servidores de terceiros, como Urban Airship , Xtify, Mainline , ... que permitem o envio não apenas no Android, mas também em iOs, Windows Phone ...

Panchine Lac
fonte
1

Firebase Cloud Messaging ( ) é a nova versão do GCM. O FCM é uma solução de mensagens entre plataformas que permite enviar mensagens de forma segura e gratuita. Herda a infraestrutura central do GCM para entregar mensagens de forma confiável no Android, iOS, Web (javascript), Unity e C ++.

Em 10 de abril de 2018, o Google reprovou o GCM. As APIs do servidor e do cliente GCM foram descontinuadas e serão removidas em 11 de abril de 2019. O Google recomenda a migração de aplicativos GCM para o Firebase Cloud Messaging (FCM), que herda a infraestrutura GCM confiável e escalável.

Recurso

Fahed Hermoza
fonte
0

Você pode usar o Pusher

É um serviço hospedado que facilita a adição de dados e funcionalidade em tempo real a aplicativos da Web e móveis.
O Pusher oferece bibliotecas para integrar em todos os principais tempos de execução e estruturas.

PHP, Ruby, Python, Java, .NET, Go and Nodeno servidor
JavaScript, Objective-C (iOS) and Java (Android)no cliente.

Arash Hatami
fonte