- Android app http headers
- Android OkHttp Example
- OkHttp Supports Http/2
- Features of OkHttp.
- Add Library to Project
- Add Permission to Manifest
- Android OkHttp Examples
- Android OkHttp Get Example
- Android OkHttp Get Request With Query String Example
- Android OkHttp Post Example
- Android OkHttp POST JSON Example
- Android OkHttp Headers Example
- Android OkHttp Async Call
- Android OkHttp Multipart Example
- Android OkHttp Example Code
- Activity
- Layout
- About
- Android and the HTTP download file headers
- The cause
- And the solution
- How to create the headers [UPDATE 20110623]
- Testing Different Headers [UPDATE 20111025]
- GET, POST, REST [UPDATE 20120208]
- Authentication? [UPDATE 20120223]
- Help to make it better
Android app http headers
Android OkHttp Example
May 27, 2017 by Srinivas
Android apps rely on rest services running on server for authentication & authorization, getting and posting data. Since the services on the web run on http protocol, in order to network with servers, android apps need http client. While there are several http client libraries and frameworks including volley which can be used in Android, OkHttp, an Http & Http/2 client, is widely used in android and java applications.
In this article, I am going to explain features of OkHttp and show how to use OkHttp in android to make http get, post, multipart, json and asynchronous request calls with examples.
OkHttp Supports Http/2
Below are some of the features of http/2
- Http/2 is a binary protocol which is more efficient compared to text protocol Http.
- Http/2 supports multiplexing meaning multiple requests and responses can be in flight at the same time on a connection.
- Http/2 supports header compression leading to reduced network round trips.
- Http/2 provides improved security.
Features of OkHttp.
OkHttp supports below features which make OkHttp an efficient http client with fast loading and reduced network bandwidth.
- OkHttp supports Http/2 protocol.
- Connection pooling can used for http protocol connections.
- GZIP compression shrinks network data size.
- Cache eliminates network round trip for repeating requests.
- OkHttp silently recovers from network problems.
- If your server is load balanced, OkHttp tries to connect other nodes when it fails to connect one of the nodes in load balancer.
- OkHttp supports both synchronous and asynchronous calls.
- You can use OkHttp on Android 2.3 and Java 7 versions onwards.
Add Library to Project
You can add OkHttp library to your project by adding below line to your module gradle property file.
Add Permission to Manifest
As below examples access rest services on server, internet permission is required. Add below permission to manifest xml file.
Android OkHttp Examples
In the below examples, the process of making reset service calls and updating UI with responses is executed in the background thread using AsyncTask. I provided below detailed explanation of each type of http request and complete android OkHttp example code.
Android OkHttp Get Example
Below code shows how to send http get request using OkHttp. To make an http get request call using OkHttp, you need to create Request object by using Request.Builder. Then call newCall method on OkHttpClient object passing the Request object. Finally, call execute() method on Call object to make http get request and receive response.
Above service call returns response in JSON format. Once you get JSON string from response by calling response.body().string(), you can use JSONOjbect or gson for parsing it. If you need more information on how to parse json in android, you can view my previous posts parsing JSON using JSONObject and parsing Json using gson library.
Android OkHttp Get Request With Query String Example
To make http get request call with query parameter using OkHttp, you need to use HttpUrl.Builder and add query parameter to it by calling addQueryParameter on HttpUrl.Builder as shown in below code.
Android OkHttp Post Example
To add post data to Request as key value pairs like data from html forms, you need to use FormBody.Builder, add post parameters to it, and create RequestBody as shown below.
Android OkHttp POST JSON Example
You can post json string to server using OkHttp. To do that, you need to create RequestBody object using create method on RequestBody passing json MediaType and json string as show below.
Android OkHttp Headers Example
You can add headers to request when request object is created or in intercepters by calling addHeader method on Request.Builder object.
Android OkHttp Async Call
In our examples, as UI needs to be updated with response after service call, entire process of making service calls and updating UI is done in the background using AsyncTask. But if you don’t need to use AsyncTask but only want to make http call asynchronously, you can do so by calling enqueue method on Call object passing Callback instead of execute method which makes http call synchronously.
Android OkHttp Multipart Example
To upload files or send multiple parts to http server, you need to send http multipart request. You can create multipart requests in OkHttp by building RequestBody using MultipartBody.Builder shown below. MultipartBody.Builder allows you to add data parts using addFormDataPart method.
Android OkHttp Example Code
Activity
Layout
About
Android app development tutorials and web app development tutorials with programming examples and code samples.
Источник
Android and the HTTP download file headers
I lately had to create a complex download repository for a customer. Multiple files could be selected and were compressed on the fly into a single ZIP file before being transfered to the client. After everything worked fine with IE, FF and Chrome, I checked with Android 2.1 and the download failed. Here is why, and how to cure it…
I faced a whole bunch of problems like the browser not reacting at all, the browsers reporting that “The content being downloaded is not supported by the phone”, the download taking place but the content of the file being empty or some HTML garbage, or the browser downloading the file but ignoring my file name and trying to save the file under the name of the script that generated it. (I guess not many users would know how to handle a ZIP file that is downloaded with the name “index.php” or similar. *sigh*)
The cause
Actually there are two show stoppers at work here (see section “GET, POST, REST” below for the second pitfall, connected to POST requests).
The first problem I found is that the Android browsers are extremely picky about two of the usual HTTP download headers. As I experienced this behavior with several browsers on a Motorola Defy running Android 2.1 (Eclair) but not after an update to 2.2 (Froyo), I conclude that this is an Android problem and not a browser issue.
Here are some header lines that did not work on Android 2.1 – just to show how NOT to do it.
ATTENTION:
If you use any of the lines below your download will probably NOT WORK on Android 2.1.
And the solution
To make it work in Android’s stock browser and in Dolphin browser you have to use:
Please mind the double-quotes around the filename parameter and the uppercase .ZIP extension of the filename. Both are absolutely necessary for ZIP files on Android 2.1 to download correctly! From my web research it looks like it is possible that the uppercase extension is only required for ZIP files and only for Android versions up to 2.1. I am not sure of that and did not do any further testing. If you create other downloadable file types (e.g. PDF), please test yourself and leave a comment below.
[UPDATE 20120530, thanks to Rachel for reporting this]:
Please also make sure that there are no trailing semicolons behind any of these headers. Otherwise especially Content-Disposition will not be parsed properly by the Android stock browser (up to and including Android 4, Ice Cream Sandwich). Example:
…will not work correctly because of the semicolon at the end. Such trailing semicolons are reportedly generated by some eCommerce packages that provide download links. With such a header the download will still happen, but the desired filename will be lost. Android will replace it with the name of the script that generates the download (e.g. index.php), or with the generic name downloadfile.bin (if the URL of the script contains additional parameters like in index.php?id=321).
How to create the headers [UPDATE 20110623]
How you create those headers largely depends on your scenario and your programming language.
In PHP it would look like this:
If you are dealing with static downloadable files on an Apache webspace and you only want to link to them from some web page, you have to inform Apache to use the right headers, e.g. by appropriate statements in an .htaccess file somewhere up in the path of your downloadable file. If we would not have to include the filename in the Content-Disposition header this would be simple:
But to include the filename on the fly we have to do some more magic:
And don’t forget to store your ZIP files with uppercase extensions, as Apache will not change your lyrics for you!
Fortunately the above headers will also work for all major desktop browsers, so they are a good general solution. And let’s just hope that future Android versions will be less pesky.
Testing Different Headers [UPDATE 20111025]
Here is a little script to quickly test the reaction of your Android gadget with different header combinations:
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=”digiblog.ZIP”
TRY DOWNLOAD (Should work on all versions of Android!)
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=”digiblog.zip”
TRY DOWNLOAD (May NOT work on older versions of Android – lowercase filename extension!)
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=digiblog.ZIP
TRY DOWNLOAD (May NOT work on older versions of Android – filename not quoted!)
Content-Type: application/force-download
Content-Disposition: attachment; filename=”digiblog.ZIP”
TRY DOWNLOAD (May NOT work on older versions of Android – wrong Content-Type!)
To create your own tests you may use this URL syntax:
http://www.digilog.de/pub/blog/android_download_header_test.php/param1/param2/param3/…/
where paramX may be any of the following strings (headers are sent in order of parameters):
ctaos = Content-Type: application/octet-stream
ctafd = Content-Type: application/force-download
cdafqXXX (XXX may be GIF, PDF, ZIP, gif, pdf, zip)
= Content-Disposition: attachment; filename=”digiblog.XXX”
cdafXXX (XXX may be GIF, PDF, ZIP, gif, pdf, zip)
= Content-Disposition: attachment; filename=digiblog.XXX
Examples:
the four preconfigured tests above use these links…
– http://www.digilog.de/pub/blog/android_download_header_test.php/ctaos/cdafqZIP/
– http://www.digilog.de/pub/blog/android_download_header_test.php/ctaos/cdafqzip/
– http://www.digilog.de/pub/blog/android_download_header_test.php/ctaos/cdafZIP/
– http://www.digilog.de/pub/blog/android_download_header_test.php/ctafd/cdafqZIP/
When you use this testing feature please leave a comment and tell us about your Android version and your results! Also, if you need additional headers for your testing, drop a comment and I will add them.
GET, POST, REST [UPDATE 20120208]
Over the course of comments to this article, a second possible pitfall showed up its ugly head. While all my testing examples carry their control parameters encoded into their URLs, many applications that you write out there will not. They will often use GET or POST requests to transfer data that is needed to create the downloadable document on the fly. If you are using POST for this transfer, you’re in trouble:
As several commenters (special thanks to Juan and Ralf) have pointed out, there is a problem with POST requests on many Android devices. It looks like POST does work as expected when the result of the POST request is again a web page, but the POST data gets completely lost when the request initiates a file download.
A possible reason for this weird behavior could be that Android (or the browser in use) forwards the URL for the file download to some helper application (Android Download Manager?) that executes the actual download. In this process the POST data is either not transferred, or gets lost, or maybe the complete session context incl. any POST data gets lost and the bare POST URL is used to request the file. This results in a file download with a zero file size, or incorrect file content, or even some HTML garbage in the file (if the server application does return a page content when the POST parameters are missing).
But careful: I have to admit that my knowledge of the exact HTTP handshake in the process of a file download is rather limited. So forgive me if my speculations are bending or breaking some fundamental laws of HTTP physics.
As Ralf has pointed out in his comment, the problem exists at least up to Android 3.2.1 and is heavily browser dependant. POSTed downloads seem to work on Opera and Firefox but fail on Dolphin and the Android stock browser.
To avoid this trap you have to use GET requests or RESTful URLs (keeping all needed data for an HTTP request within the URL itself, as I did in my examples above)!
More research on the POST problem can be found in the detailed answer by Steve Payne to this StackOverflow question.
[SUB-UPDATE 20120209]: The above speculation seems to be dead on. I found issues 1780 and 3948 in the Android forum, which describe the inability of the stock browser and the Android Download Manager to correctly handle downloads that are initiated through POST requests. Both reports have been acknowledged by forum moderators, but labelled as “enhancements” instead of as bugs. So they are probably handled as feature requests. 1780 is over 3 years old, starred by +100 visitors and there is still no indication that it has been resolved, not even in the latest Android version (being 4.0.4 at the time of this writing).
Authentication? [UPDATE 20120223]
Another defect of the Android Download Manager is its inability to handle basic authentication. If you use authentication to control access to your download script, your downloads will fail with all browsers that make use of the ADM (e.g. Android stock browser and Dolphin). The reason is surely the same as for the POST issue mentioned above: The ADM receives the download URL from the browser, but any further information (e.g. authentication session, POST parameters) are simply not transferred. So the ADM gets blocked out by the authentication mechanism, even if the browser has successfully authenticated.
There are multiple strategies to solve the authentication problem:
Depending on how much you need to protect (the whole web page content or only the download file content) you could remove the basic auth and implement a normal password form field in the page that initiates the download. The password check would then be done by the script that receives the form and delivers the download.
Another option is to check the user agent of the application requesting the download and unblocking all access that has a UA of “AndroidDownloadManager”. This can be done on server level (e.g. using .htaccess rewrite rules on Apache). But this is by no means a strong protection. Anybody who is aware of the details can fake the UA and access the download with any normal desktop browser. The pro is that this allows you to keep basic auth in place and protect a whole section of your website, including web pages and files. The con is that you should only use this technique if a data leak would not get you fired.
Help to make it better
One important hint about a part of the problem (quoting the filename) came from this Android bug report:
The POST part of the problem (see section “GET, POST, REST” above) is described in this bug report:
The authentication problem (see section “Authentication?” above) is described in this bug report (kudos to Vladimir for finding it):
If you have also been struggling with the problems mentioned in this article and if you found a solution here, I propose that you fuel the above bug reports (especially the second one) by clicking the vote star at the bottom of the reporting page (above the comment field).
Источник