Android Tutorial Embed an Http Server in your Android Application

Status
Not open for further replies.
The HttpServer library is a new library, based on an open source project named Jetty. This library allows you to easily embed an Http server in your application.

Http server means that you can point a browser to the device IP address (and relevant port) and communicate with your app.

It can be very useful in many applications.

Some of the benefits or reasons to use this library:
- No need to write any additional "client" app as the server can be accessed from any browser
- Much simpler to manage than raw sockets
- As the device plays the server role there are usually no firewall issues (when working in the local network)

The basics of this library are quite simple, though if you are not familiar with the Http protocol then it is recommended to first get familiarized with it.

How it works?
First you should initialize the server and call start with the chosen port. You should (usually) use a Service to handle the server.

Once the server is running, any external request will fire the HandleResponse event.

For example to create an interesting site that always returns a simple string you can write the following code:
B4X:
Sub Server_HandleRequest (Request As ServletRequest, Response As ServletResponse)
   Response.SendString("Hello")
End Sub

You can get more information from the Request object and then set the response accordingly.

The attached example demonstrates the features of this library.

Main page:

SS-2013-02-03_17.45.10.png


The code that builds this Html response, reads a template file and then replaces some of the fields as needed.
Note that the Greeting value is set in the main Activity.

The browser URL is made of the device local IP address and the chosen port.

This is the template text:

SS-2013-02-03_17.48.09.png


Pressing on the "List external storage files" link will take you to the "list" page:

SS-2013-02-03_17.50.25.png


The list page allows you to download or view the files, navigate to a different folder or to upload a file. Uploading a file is done with an "upload" call.

The server supports GET and POST requests. It will automatically handle multipart/form-data post requests (like is done with the uploading form).

The possibilities with this library are endless! You can pull reports from the device, export or import data, remotely control the device, handle multiple clients and many other options.

The library, which is quite large due to the Jetty library (1.5mb), can be downloaded here:
www.basic4ppc.com/android/files/HttpServer.zip

The example is attached.

Other examples:
Multi-chat: http://www.basic4ppc.com/forum/basic4android-getting-started-tutorials/25984-embed-http-server-your-android-application.html#post150462
Database reports: http://www.basic4ppc.com/forum/basic4android-getting-started-tutorials/25984-embed-http-server-your-android-application-2.html#post150723

A module that allows you to use No-IP.org service and access devices over the internet: http://www.basic4ppc.com/forum/basi...ess-your-device-over-internet.html#post153944
 

Attachments

  • HttpServerExample.zip
    58.1 KB · Views: 6,809
Last edited:

Ekcentrik

Member
Licensed User
Longtime User

KY Leng

Member
Licensed User
Longtime User
If you know the device ip address then you can connect to it with any valid connection. What I meant to say without a more complex solution it is not possible to access the server over the internet.

Good evening,

I know that this HttpServer library could not be accessed over internet.
However, If I want to convert my Android device to be a Webserver and can be accessed over internet, what should I do ? Do I need to have a public IP address for my device?

Looking forward to hearing from you soon?
 

DavideV

Active Member
Licensed User
Longtime User
i've done it using duckdns service: http://www.duckdns.org/about.jsp
this service does't expire monthly like no-ip does and it's completely free.
The router configuration could be the tricky part.
I've a full working b4a app (not yet published) based on both no-ip and duckdns that can handle your own webserver at home (example in my signature). i could share some pieces of code if someone need (not the entire app since i'm going to publish it)).

cheers
 

DavideV

Active Member
Licensed User
Longtime User
Hi Erel

it's possible to upload file to web server (android device 1) from job.postfile (android device 2).
The donwload job works fine with job1.download("http://XX.XX.XX.XX:5555/download/mnt/sdcard/namefile")
I have tried job1.postfile("http://XX.XX.XX.XX:5555/upload/mnt/sdcard/",File.DirInternalCache,"datastore") but I received SERVER ERROR.

Thanks.

Hi,
i was able to upload files from an android app (device1) to an android webserver at home (device2) using this:
https://www.b4x.com/android/forum/threads/android-http-multipart-requests.8411/#content

Bye
 

opus

Active Member
Licensed User
Longtime User
Hi,
could anybody show how this WebServer could be able to read the credentials that are sent to the server by another app using:
B4X:
HTTPClient.ExecuteCredentials( job.GetRequest, taskCounter, job.Username, job.Password)
The other app is using the httpUtils2-lib within the AppUpdating-Lib.
It is working without the credentials (connection over internet and all that...).
I can't find a way the see any part of the credentials that are set and send(at least I think it is sending them:().

Thanks
 

DonManfred

Expert
Licensed User
Longtime User
I can't find a way the see any part of the credentials that are set
Credentials which are set are not used if the Server does not request them. In a normal webserver you need to use a .htaccess file. I dont know if this lib supports this.

But you could use random Headers which you send with the request.

B4X:
    Dim job As HttpJob
    job.Initialize("getuser",Me)
    job.Download("http://192.168.192.24:5555/") 'http://donmanfred.basic4android.de/req.php
    job.GetRequest.SetHeader("Username", "MyUsername")
    job.GetRequest.SetHeader("Password", "mypass")

and in server app

B4X:
Sub Server_HandleRequest (Request As ServletRequest, Response As ServletResponse)
    Try
        Log("Request: Username="&Request.GetHeader("Username"))
        Log("Request: Password="&Request.GetHeader("Password"))
        Log("Client: " & Request.RemoteAddress)
        Log(Request.RequestURI) 'handle the request based on the URL
 

opus

Active Member
Licensed User
Longtime User
Credentials which are set are not used if the Server does not request them. In a normal webserver you need to use a .htaccess file. I dont know if this lib supports this.
I guess that is the reason I couldn't get anything.

On the server-side I already used your posted Log-Lines, however no result so far.

Which lib is this one from?
B4X:
job.GetRequest.SetHeader("Username", "MyUsername")
The IDE tells me its not in httpUtils2.


Thanks
 

opus

Active Member
Licensed User
Longtime User
OK, found that and I got my UserName and Password now.
Dankeschön
 

Jean Pierre MALOBERTI

Member
Licensed User
Hi,

I'm testing B4A for two days and i'm trying to run the httpserver examples (HttpServer and HttpServerDB). The compilation is ok and the app starts on the device (or the emulator) but the command "server.Start(port)" throw the following error :

java.lang.RuntimeException: Unable to create service b4a.example.serverservice: java.lang.RuntimeException: java.lang.ExceptionInInitializerError
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3272)
at android.app.ActivityThread.access$1900(ActivityThread.java:181)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1557)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6117)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.RuntimeException: java.lang.ExceptionInInitializerError
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:165)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
at b4a.example.serverservice.onCreate(serverservice.java:53)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3262)
... 9 more
Caused by: java.lang.ExceptionInInitializerError
at anywheresoftware.b4a.objects.HttpServer.Start(HttpServer.java:54)
at b4a.example.serverservice._service_create(serverservice.java:230)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:697)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:336)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:246)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
... 12 more
Caused by: java.util.MissingResourceException: Can't find resource for bundle 'javax.servlet.LocalStrings_fr_FR', key ''
at java.util.ResourceBundle.missingResourceException(ResourceBundle.java:238)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:230)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:139)
at javax.servlet.GenericServlet.<clinit>(GenericServlet.java:65)
... 22 more

Any idea ?

Thanks
 

Jean Pierre MALOBERTI

Member
Licensed User
Thanks for the quick reply but now the error is :

Caused by: java.util.MissingResourceException: Can't find resource for bundle 'javax.servlet.LocalStrings_en_US', key ''
at java.util.ResourceBundle.missingResourceException(ResourceBundle.java:238)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:230)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:139)
at javax.servlet.GenericServlet.<clinit>(GenericServlet.java:65)
... 22 more
 
Status
Not open for further replies.
Top