Android Tutorial Android Http Multipart requests

Status
Not open for further replies.
For new projects it is recommended to use OkHttpUtils2: https://www.b4x.com/android/forum/threads/54723/#content

Multipart POST requests are usually used by Html Form components to upload files and pairs of name/values to the server.
The attached code module makes it easy to create such requests.

The following code demonstrates the usage of this code module:
B4X:
Sub Process_Globals
    Dim hc As HttpClient
End Sub

Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        hc.Initialize("hc")
    End If
    'Add files
    Dim files As List
    files.Initialize
    Dim FD As FileData
    fd.Initialize
    fd.Dir = File.DirRootExternal
    fd.FileName = "temp.apk"
    fd.KeyName = "upfile2"
    fd.ContentType = "application/octet-stream"
    files.Add(fd)
    'Add second file
    Dim fd As FileData
    fd.Initialize
    fd.Dir = File.DirAssets
    fd.FileName = "1.png"
    fd.KeyName = "upfile"
    fd.ContentType = "application/octet-stream"
    files.Add(fd)
    'Add name / values pairs (parameters)
    Dim NV As Map
    NV.Initialize
    NV.Put("note1", "abc")
    NV.Put("note2", "def")
    Dim req As HttpRequest
    req = MultipartPost.CreatePostRequest("http://www.example.com/1.php", NV, files)
    hc.Execute(req, 1)
End Sub
Sub hc_ResponseError (Response As HttpResponse, Reason As String, StatusCode As Int, TaskId As Int)
    Log("error: " & Response & " " & StatusCode)
    If response <> Null Then
        Log(Response.GetString("UTF8"))
        Response.Release
    End If
End Sub
Sub hc_ResponseSuccess (Response As HttpResponse, TaskId As Int)
    Msgbox(Response.GetString("UTF8"), "")
    Response.Release
End Sub
The method MultipartPost.CreatePostRequest does most of the job.
It accepts three parameters. The first is the URL (of the target, not the html page).
The second is a Map that contains the names and values pairs that will be sent to the server.
You can pass Null if it is not needed.
The third parameter is a List that holds FileData items.
Each FileData item represents a file that will be uploaded to the server.
Again, you can pass Null if it is not needed.
For example:
B4X:
    Dim fd As FileData
    fd.Initialize
    fd.Dir = File.DirAssets
    fd.FileName = "1.png"
    fd.KeyName = "upfile"
    fd.ContentType = "application/octet-stream"
The above code will upload a file named 1.png from the assets folder (Files tab). The file will be mapped to "upfile" key.
 

Attachments

  • MultipartPost.bas
    2 KB · Views: 2,047
Last edited:

iatall

Member
Licensed User
Longtime User
error: anywheresoftware.b4a.http.HttpClientWrapper$HttpResponeWrapper@41e0f258 405
What does this error indicate?
 

iatall

Member
Licensed User
Longtime User
Solved. i had written wrong file upload control name.
thanks for reply.
 

iatall

Member
Licensed User
Longtime User
i am getting this error :
Parsing code. 0.01
Compiling code. Error
Error compiling program.
Error description: Unknown member: createpostrequest
Occurred on line: 33
req = MultipartPost.CreatePostRequest("http://websitename.com/Default.aspx", NV , files )
Word: createpostrequest


activity file :

B4X:
Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        hc.Initialize("hc")       
    End If
    Dim files As List
    files.Initialize
    Dim fd As FileData
    fd.Initialize
    fd.Dir = File.DirRootExternal
    fd.FileName = "1.wav"
    fd.KeyName = "myFile1"
    fd.ContentType = "application/octet-stream"
    files.Add(fd)   
    Dim NV As Map
    NV.Initialize
    NV.Put("note1", "abc")
    NV.Put("note2", "def")
    Dim req As HttpRequest
    req = MultipartPost.CreatePostRequest("http://websitename.com/Default.aspx", NV , files )
    hc.Execute(req, 1)
End Sub

Sub hc_ResponseError (Response As HttpResponse, Reason As String, StatusCode As Int, TaskId As Int)
    Log("error: " & Response & " " & StatusCode)
    If Response <> Null Then
        Log(Response.GetString("UTF8"))
        Response.Release
    End If
End Sub
Sub hc_ResponseSuccess (Response As HttpResponse, TaskId As Int)
    Msgbox(Response.GetString("UTF8"), "")
    Response.Release
End Sub
Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub


service file :

B4X:
Sub Process_Globals
    Type FileData (Dir As String, FileName As String, KeyName As String, ContentType As String)
End Sub

Sub CreatePostRequest(URL As String, NameValues As Map, Files As List) As HttpRequest
    Dim boundary As String
    boundary = "---------------------------1461124740692"
    Dim stream As OutputStream
    stream.InitializeToBytesArray(20)
    Dim EOL As String
    EOL = Chr(13) & Chr(10) 'CRLF constant matches Android end of line character which is chr(10).
    Dim b() As Byte
    If NameValues <> Null AND NameValues.IsInitialized Then
        'Write the name/value pairs
        Dim key, value As String
        For i = 0 To NameValues.Size - 1
            key = NameValues.GetKeyAt(i)
            value = NameValues.GetValueAt(i)
            b = ("--" & boundary & EOL & "Content-Disposition: form-data; name=" _
                & QUOTE & key & QUOTE & EOL & EOL & value & EOL).GetBytes("UTF8")
            stream.WriteBytes(b, 0, b.Length)
        Next
    End If
    If Files <> Null AND Files.IsInitialized Then
        'write the files
        Dim FD As FileData
        For i = 0 To Files.Size - 1
            FD = Files.Get(i)
            b = ("--" & boundary & EOL & "Content-Disposition: form-data; name=" _
                & QUOTE & FD.KeyName & QUOTE & "; filename=" & QUOTE & FD.FileName & QUOTE _
                & EOL & "Content-Type: "  & FD.ContentType & EOL & EOL).GetBytes("UTF8")
            stream.WriteBytes(b, 0, b.Length)
            Dim In As InputStream
            In = File.OpenInput(FD.Dir, FD.FileName)
            File.Copy2(In, stream) 'read the file and write it to the stream
            b = EOL.GetBytes("UTF8")
            stream.WriteBytes(b, 0, b.Length)
        Next
    End If
    b = (EOL & "--" & boundary & "--" & EOL).GetBytes("UTF8")
    stream.WriteBytes(b, 0, b.Length)
    b = stream.ToBytesArray
    'msgbox(b.Length, "")
    Dim request As HttpRequest
    request.InitializePost2(URL, b)
    request.SetContentType("multipart/form-data; boundary=" & boundary)
    request.SetContentEncoding("UTF8")
    Return request
End Sub

i am using HTTP library.
what is my mistake?
 

somed3v3loper

Well-Known Member
Licensed User
Longtime User
I am trying to upload a picture to Telegram using Bot api but with no luck
Here is my code:
B4X:
    Dim fd As FileData
    fd.Initialize
    fd.Dir = path
    fd.FileName = fname
    fd.KeyName = "photo"
    fd.ContentType = "multipart/form-data"
    Dim files As List
    files.Initialize
    files.Add(fd)
    hc.Initialize("hc")
    Dim req As HttpRequest
    Dim NV As Map
    NV.Initialize
    NV.Put("chat_id", chat_id)
    NV.Put("caption", caption)
    req=MultipartPost.CreatePostRequest(link&"/sendPhoto",NV,files)
    hc.Execute(req,  1)
and here is method documentation

https://core.telegram.org/bots/api#sendphoto

I get 415 status code means Unsupported Media Type .

Can any one please help me and tell what to change in the code to make it work .

By the way sending message is working correctly (using GET) which means there is no problems in api connection .
 

somed3v3loper

Well-Known Member
Licensed User
Longtime User
I've updated OkHttpUtils2 and it now supports multipart requests. Please use it instead of this code: https://www.b4x.com/android/forum/threads/okhttp-replaces-the-http-library.54723/#post-343758

If you still encounter an issue then start a new thread for this.
I am sorry .
I am using B4J and this is log


B4X:
Program started.
main._appstart (java line: 59)
java.lang.InstantiationError: anywheresoftware.b4a.BA
    at anywheresoftware.b4a.samples.httputils2.httpjob.innerInitialize(httpjob.java:13)
    at anywheresoftware.b4a.samples.httputils2.httpjob._initialize(httpjob.java:198)
    at smm.tel.bot.main._appstart(main.java:59)
    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 smm.tel.bot.main.start(main.java:36)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$163(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$176(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$174(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$175(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$149(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:745)
 
Status
Not open for further replies.
Top