[Reworked] Custom "push" notifications (server included)
So I have come up with a better(?) way of doing push notifications.
This time I will provide a usable server executable.
Download the server here: Filebeam - Beam up that File Scottie!
If you get an error from the server then please post it here and I will fix it.
Note: Scroll to the bottom to get the full code if you do not wish to read the tutorial.
Note2: The data cost for using this on the 3G network is really low, it would take around 162 days for it to use 1MB data, which makes this almost free to use.
I did not count the data used to receive packets tho, because those packets are always different in size, but they are virtually free to use aswell.
We start up by doing the layout.
You will need a layout named "main" with these controls:
*TextEdit; Name="txtIP"
*Button; Name="btnChange"
Next you need to add a service module with the name "getnotif".
Now let's start the coding!
Add these lines to Process_Globals:
HttpReq and hc is used to get the external IP address from whatismyip.com, the result is saved in res.
tmrIP adds a timer to the application, this will be used to send your IP to the server when the IP is updated.
Packet is the object you send to the server, you add data() to the packet to send something.
Change local to true if you wish to test this on a local network.
Use the designer to generate the code in Globals.
In Activity_Create you will need to add the following:
Activity.LoadLayout("main") will load the layout you have created in the Designer called "main".
tmrIP.Initialize("tmrIP", 6000) initializes the timer and sets the interval to 6 seconds, change to 600000 for a 10minute interval when you know that the code is working.
hc.Initialize("http") initializes the HttpClient.
ConIP = "10.54.12.248" adds the IP "10.54.12.248" to the ConIP variable that is used to direct the packet to a specific IP Address.
(this is not vital, and you can change it to your servers IP if you wish, makes it easier to debug)
StartService(getnotif) starts the service, the service is what we use to show the notification.
If local is false we will poll the whatismyip.com site for our external IP.
if local is true then we will send a packet to the server with our local IP, there is a way to get this IP automatically but my device does not like that way of doing it so I will not include that in this tutorial.
Change "10.54.12.201" to the local IP of your server.
data = str.GetBytes("UTF8") converts the string str to bytes and adds it to the data() byte variable.
Packet.Initialize(data, ConIP, 4444) adds the data() to the packet and points the packet to the IP located in ConIP and the port 4444
getnotif.Socket1.Send(Packet) sends the Packet we created.
Add this line to btnChange_Click:
This code changes the IP you use to send packets to the IP you write in the TextEdit object.
Add these lines to tmrIP_Tick:
This code is the same as the code above, thus I won't explain it again.
Last, add this to http_responsesuccess(Response As HttpResponse, TaskId As Int):
res = Response.GetString("UTF8") converts the response we got from whatismyip.com to the res variable.
IP = res changes the IP variable to the value of the res variable. This could be done differently, I chose to do it this way so that I can use res for other purposes later if I wish.
If IP <> OldIP Then if IP is not the same as OldIP then do the code below.
The code below has already been explained before, thus I will not do it again.
Now we will code the service module.
First add this in Process_Globals:
n is the notification object we will use to display the messages from the server.
Socket1 is the UDPSocket object we use to send and receive packets from and to the server.
Add this to Service_Create:
This is pretty self explanatory.
Add this to Service_Start (StartingIntent as Intent):
If it's the first time the service is started then initialize Socket1.
n.SetInfo("Network Test", "Waiting for server...", Main) set the title of the notification to "Network Test" and the message to "Waiting for server...".
Service.StartForeground(1, n) start the service in the foreground making the app stay alive and always show the notification.
Add this to Socket1_PacketArrived (Packet As UDPPacket):
msg = BytesToString(Packet.Data, Packet.Offset, Packet.Length, "UTF8") convert the bytes received in the packet from the server to string and add that to the msg variable.
n.SetInfo("Network Test", msg, Main) change the notification to include the message from the server.
n.Notify(1) update the notification so that the user can see the change.
Full code for the Main Module below:
Full code for the getnotif service module below:
So I have come up with a better(?) way of doing push notifications.
This time I will provide a usable server executable.
Download the server here: Filebeam - Beam up that File Scottie!
If you get an error from the server then please post it here and I will fix it.
Note: Scroll to the bottom to get the full code if you do not wish to read the tutorial.
Note2: The data cost for using this on the 3G network is really low, it would take around 162 days for it to use 1MB data, which makes this almost free to use.
I did not count the data used to receive packets tho, because those packets are always different in size, but they are virtually free to use aswell.
We start up by doing the layout.
You will need a layout named "main" with these controls:
*TextEdit; Name="txtIP"
*Button; Name="btnChange"
Next you need to add a service module with the name "getnotif".
Now let's start the coding!
Add these lines to Process_Globals:
B4X:
Dim HttpReq As HttpRequest
Dim hc As HttpClient
Dim tmrIP As Timer
Dim IP As String
Dim OldIP As String
Dim ConIP As String
Dim local As Boolean : local = True
Dim res As String
Dim Packet As UDPPacket
Dim data() As Byte
Dim str As String
HttpReq and hc is used to get the external IP address from whatismyip.com, the result is saved in res.
tmrIP adds a timer to the application, this will be used to send your IP to the server when the IP is updated.
Packet is the object you send to the server, you add data() to the packet to send something.
Change local to true if you wish to test this on a local network.
Use the designer to generate the code in Globals.
In Activity_Create you will need to add the following:
B4X:
Activity.LoadLayout("main")
tmrIP.Initialize("tmrIP", 6000)
tmrIP.Enabled = True
tmrIP.Initialize("tmrIP", 6000) initializes the timer and sets the interval to 6 seconds, change to 600000 for a 10minute interval when you know that the code is working.
B4X:
If FirstTime Then
hc.Initialize("http")
ConIP = "10.54.12.248"
StartService(getnotif)
ConIP = "10.54.12.248" adds the IP "10.54.12.248" to the ConIP variable that is used to direct the packet to a specific IP Address.
(this is not vital, and you can change it to your servers IP if you wish, makes it easier to debug)
StartService(getnotif) starts the service, the service is what we use to show the notification.
B4X:
If local = False Then
HttpReq.InitializeGet("http://automation.whatismyip.com/n09230945.asp")
hc.Execute(HttpReq, 1)
B4X:
Else
IP = "10.54.12.201"
str = "IP:" & IP
data = str.GetBytes("UTF8")
Packet.Initialize(data, ConIP, 4444)
getnotif.Socket1.Send(Packet)
End If
End If
Change "10.54.12.201" to the local IP of your server.
data = str.GetBytes("UTF8") converts the string str to bytes and adds it to the data() byte variable.
Packet.Initialize(data, ConIP, 4444) adds the data() to the packet and points the packet to the IP located in ConIP and the port 4444
getnotif.Socket1.Send(Packet) sends the Packet we created.
Add this line to btnChange_Click:
B4X:
ConIP = txtIP.Text
Add these lines to tmrIP_Tick:
B4X:
If local = False Then
HttpReq.InitializeGet("http://automation.whatismyip.com/n09230945.asp")
hc.Execute(HttpReq, 1)
Else
IP = "10.54.12.201"
str = "IP:" & IP
data = str.GetBytes("UTF8")
Packet.Initialize(data, ConIP, 4444)
getnotif.Socket1.Send(Packet)
End If
Last, add this to http_responsesuccess(Response As HttpResponse, TaskId As Int):
B4X:
res = Response.GetString("UTF8")
IP = res
If IP <> OldIP Then
OldIP = IP
str = "IP:" & IP
data = str.GetBytes("UTF8")
Packet.Initialize(data, ConIP, 4444)
getnotif.Socket1.Send(Packet)
End If
IP = res changes the IP variable to the value of the res variable. This could be done differently, I chose to do it this way so that I can use res for other purposes later if I wish.
If IP <> OldIP Then if IP is not the same as OldIP then do the code below.
The code below has already been explained before, thus I will not do it again.
Now we will code the service module.
First add this in Process_Globals:
B4X:
Dim n As Notification
Dim Socket1 As UDPSocket
Dim FirstTime As Boolean : FirstTime = True
Socket1 is the UDPSocket object we use to send and receive packets from and to the server.
Add this to Service_Create:
B4X:
n.Initialize
n.Icon = "icon"
n.Vibrate = False
Add this to Service_Start (StartingIntent as Intent):
B4X:
Dim Packet As UDPPacket
Dim data() As Byte
Dim str As String
If FirstTime = True Then
Socket1.Initialize("Socket1", 4444, 8000)
n.SetInfo("Network Test", "Waiting for server...", Main)
n.Sound = False
End If
Service.StartForeground(1, n)
FirstTime = False
n.SetInfo("Network Test", "Waiting for server...", Main) set the title of the notification to "Network Test" and the message to "Waiting for server...".
Service.StartForeground(1, n) start the service in the foreground making the app stay alive and always show the notification.
Add this to Socket1_PacketArrived (Packet As UDPPacket):
B4X:
Dim msg As String
msg = BytesToString(Packet.Data, Packet.Offset, Packet.Length, "UTF8")
n.SetInfo("Network Test", msg, Main)
n.Notify(1)
n.SetInfo("Network Test", msg, Main) change the notification to include the message from the server.
n.Notify(1) update the notification so that the user can see the change.
Full code for the Main Module below:
B4X:
Sub Process_Globals
Dim HttpReq As HttpRequest
Dim hc As HttpClient
Dim tmrIP As Timer
Dim IP As String
Dim OldIP As String
Dim ConIP As String
Dim local As Boolean : local = True
Dim res As String
Dim Packet As UDPPacket
Dim data() As Byte
Dim str As String
End Sub
Sub Globals
Dim btnChange As Button
Dim txtIP As EditText
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("main")
tmrIP.Initialize("tmrIP", 6000)
tmrIP.Enabled = True
If FirstTime Then
hc.Initialize("http")
ConIP = "10.54.12.248"
StartService(getnotif)
If local = False Then
HttpReq.InitializeGet("http://automation.whatismyip.com/n09230945.asp")
hc.Execute(HttpReq, 1)
Else
IP = "10.54.12.201"
str = "IP:" & IP
data = str.GetBytes("UTF8")
Packet.Initialize(data, ConIP, 4444)
getnotif.Socket1.Send(Packet)
End If
End If
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub btnChange_Click
ConIP = txtIP.Text
End Sub
Sub tmrIP_Tick
If local = False Then
HttpReq.InitializeGet("http://automation.whatismyip.com/n09230945.asp")
hc.Execute(HttpReq, 1)
Else
IP = "10.54.12.201"
str = "IP:" & IP
data = str.GetBytes("UTF8")
Packet.Initialize(data, ConIP, 4444)
getnotif.Socket1.Send(Packet)
End If
End Sub
Sub http_responsesuccess(Response As HttpResponse, TaskId As Int)
res = Response.GetString("UTF8")
IP = res
If IP <> OldIP Then
OldIP = IP
str = "IP:" & IP
data = str.GetBytes("UTF8")
Packet.Initialize(data, ConIP, 4444)
getnotif.Socket1.Send(Packet)
End If
End Sub
Full code for the getnotif service module below:
B4X:
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
Dim n As Notification
Dim Socket1 As UDPSocket
Dim FirstTime As Boolean : FirstTime = True
End Sub
Sub Service_Create
n.Initialize
n.Icon = "icon"
n.Vibrate = False
End Sub
Sub Service_Start (StartingIntent As Intent)
Dim Packet As UDPPacket
Dim data() As Byte
Dim str As String
If FirstTime = True Then
Socket1.Initialize("Socket1", 4444, 8000)
n.SetInfo("Network Test", "Waiting for server...", Main)
n.Sound = False
End If
Service.StartForeground(1, n)
FirstTime = False
End Sub
Sub Service_Destroy
End Sub
Sub Socket1_PacketArrived (Packet As UDPPacket)
Log("received packet")
Dim msg As String
msg = BytesToString(Packet.Data, Packet.Offset, Packet.Length, "UTF8")
n.SetInfo("Network Test", msg, Main)
n.Notify(1)
End Sub
Last edited: