Spanish Enviar notificaciones Push utilizando Google

desof

Well-Known Member
Licensed User
Longtime User
1 Si creo es la mejor opcion para mi caso!
2 No no tengo la Base de Datos creada ! (Si !se como hacerla) es necesario esto?
3 No entiendo por que querer identificar a cada usuario por que mi requerimiento no es segmentar la notificacion sino enviarsela absolutamente a todos los usuarios de mi app!
 

cuellar

Member
Licensed User
Longtime User
Vale, un par de cosas:

Google exige registrar cada uno de los dispositivos aunque después las notificaciones sean en grupo. El tratamiento de grupo es algo diferente que si lo haces de forma individual obviamente.
Te aconsejo que primero consigas enviar una notificación a un dispositivo para quedarte con el concepto, luego ya podrás evolucionar.

La base de datos va a ser útil para almacenar los ID de registro de cada dispositivo.
 

desof

Well-Known Member
Licensed User
Longtime User
Vale, un par de cosas:

Google exige registrar cada uno de los dispositivos aunque después las notificaciones sean en grupo. El tratamiento de grupo es algo diferente que si lo haces de forma individual obviamente.
Te aconsejo que primero consigas enviar una notificación a un dispositivo para quedarte con el concepto, luego ya podrás evolucionar.

La base de datos va a ser útil para almacenar los ID de registro de cada dispositivo.

A ver pero entonces eso implica que tengo que dotar a mi aplicacion de una forma de escribir el Id de cada dispositivo ?

Entonces supongo que debería crear una funcion que solo se conecte una vez si ese dispositivo no esta registrado no ?

De donde obtengo el Identificador de cada dispositivo?

Hasta ahora habia entendido que solo habia que poner el SenderId que me facilita google en mi aplicacion!
 

cuellar

Member
Licensed User
Longtime User
Verás, el SenderID lo manda el dispositivo a Google. Google lo registra y le devuelve el ID de registro. Ahora el dispositivo está registrado con google y tiene un token.
Después el dispositivo tiene que enviar ese token a nuestro servidor. Cuando queramos notificar algo a ese dispositivo, le mandamos a google su token y el mensaje.
Como yo en mi aplicación si quiero saber a quién le mando un mensaje, relaciono un id (en mi caso es el IMEI del dispositivo) con su token correspondiente.
 

desof

Well-Known Member
Licensed User
Longtime User
Verás, el SenderID lo manda el dispositivo a Google. Google lo registra y le devuelve el ID de registro. Ahora el dispositivo está registrado con google y tiene un token.
Después el dispositivo tiene que enviar ese token a nuestro servidor. Cuando queramos notificar algo a ese dispositivo, le mandamos a google su token y el mensaje.
Como yo en mi aplicación si quiero saber a quién le mando un mensaje, relaciono un id (en mi caso es el IMEI del dispositivo) con su token correspondiente.

Bien muchas gracias por tu paciencia entonces a ver si entendi! (y en el medio las dudas)

1- En mi aplicacion debo colocar el SenderID que es el Número del proyecto obtenido de la consola con un formato como este xx7940xxx
PReg. Con solo ponerlo se envia ? o requiere de una función especial
2- Creo la BD y almaceno los Token que devuelve Google en ella

3 - y hecho todo esto me falta crear una aplicacion que envie la notificacion que no pude encontrar una donde ver como hacerlo donde uno configura el contenido el texto o lo que se que diga.
 

cuellar

Member
Licensed User
Longtime User
Crea un módulo de Servicio y lo llamas PushService
B4X:
Sub Process_Globals

End Sub
Sub Service_Create
 
End Sub

Sub Service_Start (StartingIntent As Intent)
    Select StartingIntent.Action
        Case "com.google.android.c2dm.intent.REGISTRATION"
            HandleRegistrationResult(StartingIntent)
        Case "com.google.android.c2dm.intent.RECEIVE"
            MessageArrived(StartingIntent)
    End Select
End Sub
Sub MessageArrived (Intent As Intent)
    Dim From, CollapseKey, Data As String 'ignore
    If Intent.HasExtra("from") Then From = Intent.GetExtra("from")
    If Intent.HasExtra("data") Then Data = Intent.GetExtra("data")
    If Intent.HasExtra("collapse_key") Then CollapseKey = Intent.GetExtra("collapse_key")

    'Here you should handle the new message:
    Log("New message arrived: " & Data)
    ToastMessageShow("New message: " & Data, True)
End Sub


Sub RegisterDevice (Unregister As Boolean)
    Dim i As Intent
    If Unregister Then     
        i.Initialize("com.google.android.c2dm.intent.UNREGISTER", "")
    Else
        i.Initialize("com.google.android.c2dm.intent.REGISTER", "")
        i.PutExtra("sender", Main.SenderId)
    End If
    Dim r As Reflector
    Dim i2 As Intent
    i2 = r.CreateObject("android.content.Intent")
    Dim pi As Object
    pi = r.RunStaticMethod("android.app.PendingIntent", "getBroadcast", _
        Array As Object(r.GetContext, 0, i2, 0), _
        Array As String("android.content.Context", "java.lang.int", "android.content.Intent", "java.lang.int"))
    i.PutExtra("app", pi)
    StartService(i)
End Sub

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

Sub JobDone(Job As HttpJob)
    If Job.Success Then
        Select Job.JobName
            Case "RegisterTask"
                ToastMessageShow("Registration completed successfully.", False)
            Case "UnregisterTask"
                ToastMessageShow("Unregistration completed successfully.", False)
        End Select
    Else
        ToastMessageShow("Error sending request.", True)
        Log(Job.ErrorMessage)
    End If
    Job.Release
End Sub

Sub Service_Destroy

End Sub

En Main
B4X:
Sub Process_Globals
     
    'Set this field to match the project ID in Google Console.
    SenderId = "123456789012"
End Sub

Debes escribir el código que te haga el registro con google y que haga la llamada a RegisterDevice.
Si te das cuenta, en HandleRegistrationResult, si el registro con google ha tenido éxito Intent.HasExtra("registration_id") enviamos ese registration_id a nuestro servidor j.PostString("http://miservidor.com/registro.php","codigoRegistro=" & rid).
Tendrás que escribir registro.php para que tome el registration_id y lo almacene en la base de datos.
3 - y hecho todo esto me falta crear una aplicacion que envie la notificacion que no pude encontrar una donde ver como hacerlo donde uno configura el contenido el texto o lo que se que diga.
Si, pero primero intenta conseguir obtener el registro de google y almacenarlo en la tabla, luego hacemos el envío de mensajes
 
Last edited:

desof

Well-Known Member
Licensed User
Longtime User
y como y donde llamo a RegisterDevice ?

ya creado el modulo.

No tengo que modificar el Manifest ?
 

cuellar

Member
Licensed User
Longtime User
Llámalo así:
B4X:
CallSubDelayed2(PushService, "RegisterDevice", False)

Tienes que modificar el Manifest:
B4X:
'C2DM Permissions
AddManifestText(<permission android:name="$PACKAGE$.permission.C2D_MESSAGE" android:protectionLevel="signature" />)
AddPermission($PACKAGE$.permission.C2D_MESSAGE)
AddPermission(com.google.android.c2dm.permission.RECEIVE)
' Push Service Receiver Attribute
SetReceiverAttribute(PushService, android:permission, "com.google.android.c2dm.permission.SEND")
' Service Receiver Text
AddReceiverText(PushService,
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="$PACKAGE$" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="$PACKAGE$" />
</intent-filter>)
 

desof

Well-Known Member
Licensed User
Longtime User
Bien amigo ya lo pruebo pero recuerdo q pusiste en tu explicación q en el php se colocaba el ApiKey verdad?
Sin embargo en el php q pusiste las lineas estan con un asterisco delante x l q entiendo q estan comentadas..
Debo activar esas lineas y colocar mi ApiKey?
 

cuellar

Member
Licensed User
Longtime User
No, ese php es una función a la que tienes que llamar con sus parámetros. Se hace una llamada a esa función cuando quieras enviar el mensaje.

¿que tal andas de php?
 

desof

Well-Known Member
Licensed User
Longtime User
No, ese php es una función a la que tienes que llamar con sus parámetros. Se hace una llamada a esa función cuando quieras enviar el mensaje.

¿que tal andas de php?

Entonces no entiendo donde entra en juego el Apikey ?
De php bien poco lo mio siempre fue vb6 nada mas
 

cuellar

Member
Licensed User
Longtime User
El ApiKey entra en juego cuando vayas a enviar mensajes. Se mete el valor en una variable php ($miApiKey = "xxxxxx....xxx"; ) y luego se pasa como un parámetro a la función php junto con los demás parámetros.

enviarMensajeGCM($GCMregid, $mensaje, $otrodato, $miApiKey);

¿Has conseguido registrar los dispositivos con google y almacenar los ids en una base de datos? Eso es lo primero.
 

desof

Well-Known Member
Licensed User
Longtime User
Que opinas ?
B4X:
LogCat connected to: B4A-Bridge: motorola XT890
--------- beginning of /dev/log/main
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
** Service (service1) Create **
** Service (service1) Start **
** Activity (main) Pause, UserClosed = true **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** 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)
sending message to waiting queue (CallSubDelayed - UpdateStatus)
running waiting messages (2)
** 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 **
** Activity (main) Pause, UserClosed = true **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
** 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:guia.digital.sc
 

cuellar

Member
Licensed User
Longtime User
No sé que es
 

desof

Well-Known Member
Licensed User
Longtime User
y corri la aplicacion y me da eso el Log !!!
No hay error asi que supongo que funciono la comunicacion con el Server !

Como tengo certeza de esto ?
 

cuellar

Member
Licensed User
Longtime User
Te sale este mensaje en la pantalla del dispositivo?

ToastMessageShow("registration completed successfully.", False)
 

desof

Well-Known Member
Licensed User
Longtime User
Te sale este mensaje en la pantalla del dispositivo?

ToastMessageShow("registration completed successfully.", False)

no me sale esto ToastMessageShow("Error sending request.", True)
 

cuellar

Member
Licensed User
Longtime User
El registro te arroja un error.
¿Con qué nombre de paquete estás compilando?
 
Top