B4J Tutorial [Server] Data Collection Solution - Device, Desktop and Web reports

Not open for further replies.
This is an example of building a data collection solution. The solution is made of three components:
- (B4J) Server - Manages the data in a SQLite database.
- (B4A) Device client and (B4J) desktop client - Send new data to the server and show reports.

Note that you can also see the reports from any browser.

In this example we want to track animals. The following type is declared in all three projects:
Type Animal (Name As String, Age As Double, Location As String, Date As Long)


Animal objects are sent to the server. This is done with RandomAccessFile as explained here:
Send and receive objects

Both the server and the clients are pretty simple (check the code!).
As we are using SQLite database we set the handlers to be single threaded and thus avoid issues with concurrent transactions.

You can make the server accessible over the internet by following the steps described here:
Upload files from your B4A app to your B4J server over the internet

If you run it in the local network then you only need to open the firewall port (51042 in this example) to incoming connections.


  • DataCollectionServer.zip
    4.7 KB · Views: 1,643
  • DataCollectionDevice.zip
    8 KB · Views: 1,421
  • DataCollectionDesktop.zip
    2.1 KB · Views: 668
Last edited:


Well-Known Member
Licensed User
I did everything described above and also told the firewall to open the port 51042, but it doesn't work. Here is the message:
Program started.
org.apache.http.conn.HttpHostConnectException: Connection to refused
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:159)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
at anywheresoftware.b4a.http.HttpClientWrapper.executeWithTimeout(HttpClientWrapper.java:310)
at anywheresoftware.b4a.http.HttpClientWrapper.access$0(HttpClientWrapper.java:308)
at anywheresoftware.b4a.http.HttpClientWrapper$ExecuteHelper.run(HttpClientWrapper.java:207)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Error: org.apache.http.conn.HttpHostConnectException: Connection to refused
Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:75)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:157)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391)
at java.net.Socket.connect(Socket.java:579)
at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:123)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:133)
... 15 more
Connection to refused
I'm confused.


Well-Known Member
Licensed User
Thank you Erel!


Licensed User
hello Erel
the example works well is to select a command line in the webview to simply remove and empty the database you is it possible to support me

thank you


Licensed User
[Quote = "Erel, poste: 231375, membre: 1"]. Vous pouvez ajouter un nouveau gestionnaire dans le projet de serveur qui supprime les données dont vous avez besoin [/ quote]

exist there examples because my project is to add functions in DataCollectionDesktop (delete, Were)


Licensed User
[Quote = "Erel, poste: 231693, membre: 1"] Dans cet exemple, les données ne sont pas stockées dans le bureau. Elle est stockée dans le serveur. Cela signifie que vous aurez besoin d'envoyer une commande avec HttpUtils2 au serveur qui sera ensuite supprimer les données. [/ Quote]

Merci Erel


Licensed User
t [quote = "Erel, poste: 231693, membre: 1"] Dans cet exemple, les données ne sont pas stockées dans le bureau. Elle est stockée dans le serveur. Cela signifie que vous aurez besoin d'envoyer une commande wi h HttpUtils2 au serveur qui sera ensuite supprimer les données. [/ quote]

Mobile I wanted to send to the server located on the local network pc in an application to retrieve the desired data (=?) on my mobile

is it possible to have an example

thank you


Licensed User
hello Erel. I am new here, how to display images from SQL BLOB to HTML in an application server?


Licensed User
Hello. apart the view the database in webview in app Desktop. I can send the database in server to Desktop?


Well-Known Member
Licensed User
Hi @Erel,
I need to retreive a record passing the record ID in order to retreive the related name (I have an ID and Name fields).
So I have to create an handler (like /report example) in order to retreive the requested data.

In the example (/report handler) the caller job doesn't pass any parameter (request) and the handler execute a "select * ..." query in order to retreive the data.

My target is to pass a parameter (ID) to the request in order to execute a query using the id as where condition.
How do this using http job object ?


Well-Known Member
Licensed User
Passing "GET" parameters is very simple.

You add the parameters to the link:

In the server you can get the parameters with:
Note that it is better to use HttpJob.Download2 to build the link.

@Erel first of all, thanks for your fast and useful reply!
Another little question :)

Within the the class handler, how I can manage the SQLite constraints violations (ex. unique constraint raised by the db engine) in order to advice the user and handle the event in the client (app) ?
Not open for further replies.