Spanish Enviar notificaciones Push utilizando Google

inakigarm

Well-Known Member
Licensed User
Acúerdate de comentar las líneas diguientes en AppStart en Main
B4X:
'iOSPush.Start 'comment these two lines to disable iOS notifications
'iOSFeedback.Start

Si no, te saldrá un error ya que en el config.txt estas líneas están deshabilitadas
 

desof

Well-Known Member
Licensed User
ya estoy mas cerca pero n otengo esas lineas que dices!

mira todo

disUj.jpg
 

desof

Well-Known Member
Licensed User
eso me da la consola
LogCat connected to: B4A-Bridge: motorola XT890
Connected to B4A-Bridge (Wifi)
sending message to waiting queue (CallSubDelayed - UpdateStatus)
Installing file.
** Activity (main) Resume **
--------- beginning of /dev/log/main
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (service1) Create **
** Service (service1) Start **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
** Service (service1) Destroy **
** Service (service1) Create **
** Service (service1) Start **
** Activity (main) Pause, UserClosed = false **
Connected to B4A-Bridge (Wifi)
sending message to waiting queue (CallSubDelayed - UpdateStatus)
running waiting messages (1)
** Activity (main) Resume **
Installing file.
** Activity (main) Pause, UserClosed = false **
PackageAdded: package:anywheresoftware.b4a.samples.push
Installing file.
PackageAdded: package:anywheresoftware.b4a.samples.push
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (pushservice) Create **
** Service (pushservice) Start **
** Service (pushservice) Start **
** Service (httputils2service) Create **
** Service (httputils2service) Start **
Error uploading token
** Activity (main) Pause, UserClosed = false **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (pushservice) Create **
** Service (pushservice) Start **
** Service (pushservice) Start **
** Service (httputils2service) Create **
** Service (httputils2service) Start **
Error uploading token
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = true **
** Activity (main) Resume **
** Service (pushservice) Destroy **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (pushservice) Create **
** Service (pushservice) Start **
** Service (pushservice) Start **
** Service (httputils2service) Create **
** Service (httputils2service) Start **
Error uploading token
** Activity (main) Pause, UserClosed = true **
** Activity (main) Resume **
** Service (pushservice) Destroy **
Installing file.
** Activity (main) Pause, UserClosed = false **
PackageAdded: package:anywheresoftware.b4a.samples.push
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (pushservice) Create **
** Service (pushservice) Start **
** Service (pushservice) Start **
** Service (httputils2service) Create **
** Service (httputils2service) Start **
Error uploading token
** Activity (main) Pause, UserClosed = false **
** Activity (main) Pause, UserClosed = false **
Installing file.
PackageAdded: package:anywheresoftware.b4a.samples.push
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (pushservice) Create **
** Service (pushservice) Start **
** Service (pushservice) Start **
** Service (httputils2service) Create **
** Service (httputils2service) Start **
Error uploading token
** Activity (main) Pause, UserClosed = false **
libcore.io.ErrnoException: recvfrom failed: ECONNRESET (Connection reset by peer)
sending message to waiting queue (CallSubDelayed - UpdateStatus)
Connected to B4A-Bridge (Wifi)
sending message to waiting queue (CallSubDelayed - UpdateStatus)
Installing file.
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
PackageAdded: package:anywheresoftware.b4a.samples.push
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (pushservice) Create **
** Service (pushservice) Start **
** Service (pushservice) Start **
** Service (httputils2service) Create **
** Service (httputils2service) Start **
Error uploading token
** Activity (main) Pause, UserClosed = false **


lo estoy ejcutando en mi movil mediante El Bridge !
 

inakigarm

Well-Known Member
Licensed User
Para que funcione, primero se ha de registrar la app Android en el servidor B4J y para ello, el programa B4X-PushServer ha de estar ejecutándose

Es decir, pasos:
1) Ejecutar el B4X-Pushserver.b4j
2) Cuando está corriendo, ejecuta la aplicación Android desde B4A y entonces verás que se sube correctamente el Token
3) Si no está corriendo 1) no se puede subir nada porque no hay ningún servidor en esa IP/puerto

Las líneas que te comentaba antes están en el B4X-Pushserver.B4j en las líneas 28 y 29
 

desof

Well-Known Member
Licensed User
ok!!

Ya las comente ahora no conozco un detalle por que csi nunca use el B4j como se que esta corriendo el Servidor ?
Lo ejecuto en modo Release y se crea un JAR en objects .. Ese le doy doble clik y no se ve si corre...
entiendes?
 

inakigarm

Well-Known Member
Licensed User
El push server es una aplicacion no UI, es decir, se ejecuta como un programa residente; puedes ver si está corriendo mirando el Log o accediendo al servidor en la dirección IP y puerto configurado y ver si te carga la página inicial del servidor
 

desof

Well-Known Member
Licensed User
El push server es una aplicacion no UI, es decir, se ejecuta como un programa residente; puedes ver si está corriendo mirando el Log o accediendo al servidor en la dirección IP y puerto configurado y ver si te carga la página inicial del servidor

En el log me da esto todo en rojo!!

B4X:
2016-03-03 16:48:09.536:INFO::main: Logging initialized @259ms
2016-03-03 16:48:09.632:INFO:oejs.Server:main: jetty-9.3.z-SNAPSHOT
2016-03-03 16:48:09.676:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@1b40d5f0{/,file:///C:/Users/DeSof/Downloads/B4X-PushServer/PushServer/Objects/www,AVAILABLE}
2016-03-03 16:48:09.679:INFO:oejs.AbstractNCSARequestLog:main: Opened C:\Users\DeSof\Downloads\B4X-PushServer\PushServer\Objects\logs\b4j-2016_03_03.request.log
main._appstart (java line: 66)
java.net.BindException: Address already in use: bind
    at sun.nio.ch.Net.bind0(Native Method)
    at sun.nio.ch.Net.bind(Net.java:433)
    at sun.nio.ch.Net.bind(Net.java:425)
    at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
    at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:326)
    at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80)
    at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:244)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.server.Server.doStart(Server.java:384)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at anywheresoftware.b4j.object.ServerWrapper.Start(ServerWrapper.java:182)
    at b4j.example.main._appstart(main.java:66)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:84)
    at b4j.example.main.main(main.java:29)
main.main (java line: 29)
java.lang.RuntimeException: java.net.BindException: Address already in use: bind
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:114)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:84)
    at b4j.example.main.main(main.java:29)
Caused by: java.net.BindException: Address already in use: bind
    at sun.nio.ch.Net.bind0(Native Method)
    at sun.nio.ch.Net.bind(Net.java:433)
    at sun.nio.ch.Net.bind(Net.java:425)
    at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
    at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:326)
    at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80)
    at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:244)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.server.Server.doStart(Server.java:384)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at anywheresoftware.b4j.object.ServerWrapper.Start(ServerWrapper.java:182)
    at b4j.example.main._appstart(main.java:66)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
    ... 2 more

Además yo a esto no lo quiero implementar de forma local no me sirve para lo que yo quiero por que solo quiero enviar a las apps y supongo que para eso debera estar corriendo en un servidor web. no?
He visto por ahi que con un php se puedde hacer
 

inakigarm

Well-Known Member
Licensed User
Si tienes otros requerimientos puede que tengas que utilizar otras soluciones (como con PHP por ejemplo)

Por cierto, las primeras líneas siempre salen al arrancar el servidor y el error
B4X:
java.net.BindException: Address already in use: bind
se refiere a que tienes un proceso anterior de Java (el servidor) corriendo sobre la misma IP --> vamos, que el servidor está funcionando en esa IP (deberías con el administrador de tareas finalitar las tareas abiertas correspondientes a Java SE)
 

desof

Well-Known Member
Licensed User
Ahora dime una cosa y perdona por ser tan ignorante en este tema.
De que me sirve tener un servidor como este en java corriendo en mi PC ? A quien le puedo enviar notificaciones push ?
Mi intención es y siempre lo planteé es enviar a los usuarios de mi app que estan vaya a saber donde ...
Me entiendes?.
 

inakigarm

Well-Known Member
Licensed User
Lo pruebas en tu PC y si te funciona, lo subes a un VPS (por ejemplo Amazon con una instancia en Linux), a un servidor en tu casa configurado para responder a un puerto de tu IP pública de Internet, a una Raspberry Pi , etc...

De esa manera podrás enviar notificaciones a todos tus usuarios; el tema del PC es por comodidad para testear el entorno
 

desof

Well-Known Member
Licensed User
Lo pruebas en tu PC y si te funciona, lo subes a un VPS (por ejemplo Amazon con una instancia en Linux), a un servidor en tu casa configurado para responder a un puerto de tu IP pública de Internet, a una Raspberry Pi , etc...

De esa manera podrás enviar notificaciones a todos tus usuarios; el tema del PC es por comodidad para testear el entorno
Cool !!
Ahora esta mas claro !
Tengo raspberrerry pero donde vivo no tenemos Ip pública ni posibilidad de tenerlo.
Que opción me queda un servicio en mi web como php o amazón ? Verdad
 

cuellar

Member
Licensed User
Bueno, acabo de implementar las notificaciones push en mi aplicación y funciona correctamente a falta de probarlo en más dispositivos. Uff..lo tenía todo olvidado y me ha costado un poco pillar el concepto.
Aquí os dejo la función php para enviar mensajes al servidor de Google y que éste ya se apañe en entregarlo a los dispositivos correspondientes, jejeje.


PHP:
<?php
/**
*    Google Cloud Messenger
*    Ejemplo de HTTP POST REQUEST
*    Extraido de la documentacion de google: https://developers.google.com/cloud-messaging/
*
*
*    https://gcm-http.googleapis.com/gcm/send
*    Content-Type:application/json
*    Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
*   
*    { "data": {
*    "score": "5x1",
*    "time": "15:10"
*    },
*    "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
*    }
**/

function enviarMensajeGCM($GCMregid, $mensaje, $otrodato, $apiKey){


$GCMapiKey = $apiKey;

// Registro Id del dispositivo
$registrationIDs = $GCMregid;

// Se establecen las variables que se van a mandar por POST
$cty="Content-Type: application/json";

// URL para el envio de los mensajes
//$url = 'https://android.googleapis.com/gcm/send';   //Antigua URL
$url = 'https://gcm-http.googleapis.com/gcm/send';

$fields = array(
                'data' => array( "mensaje" => $mensaje , "dato" => $otrodato),
                'to'   => $registrationIDs
                );

$headers = array(
                    'Authorization: key=' . $apiKey,
                    'Content-Type: application/json'
                );

               
// Abre una conexión
$ch = curl_init();

// Establece el url, numero de variables Post y los datos del mensaje

curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $fields ) );

// Ejecuta el post
$res_GCM_funcion = curl_exec($ch);

if ($res_GCM_funcion === FALSE) {
    die('Curl failed: ' . curl_error($ch));
}
       
// Cierra la conexión
curl_close($ch);

//decodifica en el array $res la cadena Json que devuelve Google
$res = json_decode($res_GCM_funcion,true);

//Devuelve el array
return $res;

}

?>

Aunque todavía me queda pulir el código, para evitar que se muestre la notificación si el Activity ya está abierto y cosas así...a ver si no me atasco demasiado.

Un saludo
 

desof

Well-Known Member
Licensed User
Hola mañana lo probaré aunque seria bueno q expliques por favor un poco como es la implementación..
Donde va ese archivo ?
Que hay q modificarle?
No puedes :incluir el ejemplo completo.?

Algunos somos un poco novatos en esto .

Gracias!
 

cuellar

Member
Licensed User
seria bueno q expliques por favor un poco como es la implementación..
Para las notificaciones push intervienen tres partes: Cliente (Dispositivo) - Servidor de Google - Mi servidor.
Cliente y Servidor de Google digamos que es fijo. La parte que puede variar dependiendo de tus necesidades es "mi servidor". Yo uso un VPS donde tengo alojado un dominio, una base de datos MYSQL y PHP. Imagínate que por cada registro que se introduce en una tabla de mi BD yo quiero notificar a un dispositivo. Lo primero que hice fue crear una tabla que alberga cada uno de los dispositivos que intervienen con dos campos importantes entre otros:
- ID dispositivo (un identificador único creado por mi para cada dispositivo )
- ID Registro de Google (un identificador que facilita Google para cada dispositivo)

Un requisito obligatorio es que Google exige registrar la aplicación. Para ello Google te permite crear un proyecto API (API Proyect en https://console.developers.google.com) donde te dan un numero de proyecto que nosotros conocemos en B4A como SenderId en los ejemplos de Erel.
B4X:
Sub Process_Globals
    Public SenderId As String
       
    'Set this field to match the project ID in Google Console.
    SenderId = "123456789012"
End Sub

También te dan un API KEY que nos autoriza para acceder al servidor de Google. Esta API KEY la uso en la función PHP que puse arriba.

En la aplicación, registro con google y me devuelve "registration_id". Yo almaceno en mi tabla ese id enviando un PostString y ya lo tengo disponible para enviar el mensaje.

B4X:
Sub HandleRegistrationResult(Intent As Intent)
    If Intent.HasExtra("error") Then
        Log("Error: " & Intent.GetExtra("error"))
        ToastMessageShow("Error: " & Intent.GetExtra("error"), True)
    Else If Intent.HasExtra("unregistered") Then
        'No lo usamos
    Else If Intent.HasExtra("registration_id") Then
        Dim rid As String
        rid = Intent.GetExtra("registration_id")
        Dim j As HttpJob
        j.Initialize("RegisterTask", Me)
        j.PostString("http://miservidor.com/registro.php","codigoRegistro=" & rid)
    End If
End Sub

Donde va ese archivo ?
Ese archivo va en mi servidor

Que hay q modificarle?
Nada, es una función, sólo hay que pasarle los parámetros correspondientes

No puedes :incluir el ejemplo completo.?
No dispongo de un ejemplo generalizado, pero sea lo que sea donde te atasques no dudes en preguntar hasta que lo consigas.
 

dar2o3

Active Member
Licensed User
Como todo en esta vida lo primero es entender la teoría (lógica) de las cosas, después se puede implementar de varias maneras, me da la impresión que si alguien te pasa algo ya montado y funcionando, lo usarías sin entender como funciona, vale, pero luego seguro que te surgen problemas, problemas que no vas a poder resolver si no sabes lo que hace como lo hace y por que lo hace.

Si quieres vamos paso a paso, yo te ayudaré en lo que pueda (acabo de implementar otra vez push gcm en otra de mis app) enséñanos lo que tienes echo y lo que quieres hacer, si no quieres enseñar lo que tienes, tenemos algo ya con todo echo aquí: https://www.b4x.com/android/forum/threads/b4x-push-server.48560/
Descárgatelo y lo hacemos funcionar aquí entre todos, así puede valernos de tutorial para todos, por el camino aprenderemos lo que es b4j y todo lo necesario para hacer funcionar gcm, te parece?
 
Last edited:

desof

Well-Known Member
Licensed User
Como todo en esta vida lo primero es entender la teoría (lógica) de las cosas, después se puede implementar de varias maneras, me da la impresión que si alguien te pasa algo ya montado y funcionando, lo usarías sin entender como funciona, vale, pero luego seguro que te surgen problemas, problemas que no vas a poder resolver si no sabes lo que hace como lo hace y por que lo hace.

Si quieres vamos paso a paso, yo te ayudaré en lo que pueda (acabo de implementar otra vez push gcm en otra de mis app) enséñanos lo que tienes echo y lo que quieres hacer, si no quieres enseñar lo que tienes, tenemos algo ya con todo echo aquí: https://www.b4x.com/android/forum/threads/b4x-push-server.48560/
Descárgatelo y lo hacemos funcionar aquí entre todos, así puede valernos de tutorial para todos, por el camino aprenderemos lo que es b4j y todo lo necesario para hacer funcionar gcm, te parece?

Hola La verdad es que ya empece con ese link que me enviaste de ERel y morí en el intento! Me complica demasiado el Ingles y voy a ir poniendo el paso a paso de lo que hago basandome en el Php y la explicación que me ha dado Cuellar.
Agradezco mucho la ayuda de todos.
 

desof

Well-Known Member
Licensed User
Para las notificaciones push intervienen tres partes: Cliente (Dispositivo) - Servidor de Google - Mi servidor.
Cliente y Servidor de Google digamos que es fijo. La parte que puede variar dependiendo de tus necesidades es "mi servidor". Yo uso un VPS donde tengo alojado un dominio, una base de datos MYSQL y PHP. Imagínate que por cada registro que se introduce en una tabla de mi BD yo quiero notificar a un dispositivo. Lo primero que hice fue crear una tabla que alberga cada uno de los dispositivos que intervienen con dos campos importantes entre otros:
- ID dispositivo (un identificador único creado por mi para cada dispositivo )
- ID Registro de Google (un identificador que facilita Google para cada dispositivo)

Un requisito obligatorio es que Google exige registrar la aplicación. Para ello Google te permite crear un proyecto API (API Proyect en https://console.developers.google.com) donde te dan un numero de proyecto que nosotros conocemos en B4A como SenderId en los ejemplos de Erel.

Bien voy a paso a paso

1° He creado el PHP cuyo código está arriba colocado por Cuellar y lo subo a mi servidor www.miweb.com.ar/serverPUSH.php
(En el php dices que se colocas el ApiKey pero alli lo tienes en un bloque comentado [[* "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."]] .... donde precisamente va ?)


2° Coloco en mi app creada en B4A la linea en Procees Global SenderId = "123456789012"
(Esto es toda la modificacion que le tengo que hacer a la aplicacion que recibira las notificaciones ? colocar el SenderID ?)

Aguardo respuesta para avanzar otro poquito!!

Gracias
 

desof

Well-Known Member
Licensed User
Donde se pone la funcion
HandleRegistrationResult ?

Y cuando se la llama ?
 

cuellar

Member
Licensed User
pero luego seguro que te surgen problemas, problemas que no vas a poder resolver si no sabes lo que hace como lo hace y por que lo hace.
Absolutamente de acuerdo

Desof, antes de nada contéstame a unas preguntas:

1. Entiendo que vas a usar tu servidor como envío de mensajes a través de php.
2. ¿Tienes una base de datos?.
2. ¿Cómo piensas identificar a cada uno de los usuarios de la aplicación?.

Explícanos un poco qué es lo que quieres hacer.
 
Top