Download binary file from OKHTTP
Getting ByteStream from OKHTTP
I've been digging around in the Documentation of OkHttp you need to go this way
use this method :
response.body().byteStream() wich will return an InputStream
so you can simply use a BufferedReader or any other alternative
OkHttpClient client = new OkHttpClient();
request = new Request.Builder().url("URL string here")
.addHeader("X-CSRFToken", csrftoken)
.addHeader("Content-Type", "application/json")
.build();
response = getClient().newCall(request).execute();
InputStream in = response.body().byteStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String result, line = reader.readLine();
result = line;
while((line = reader.readLine()) != null) {
result += line;
}
System.out.println(result);
response.body().close();
Binary File Download using OkHTTP Client get corrupted
If your BUFFER_SIZE is not full at the last read then you will have wrong data written in file:
You have
fileOutputStream.write(BUFFER_SIZE);
you should have:
fileOutputStream.write(BUFFER_SIZE, 0, byteRead);
EDIT1: I would also sugest to replace this part of the code:
while (true) {
int byteRead = inputStream.read(BUFFER_SIZE);
if (byteRead == -1) {
break;
}
With a better approach:
int byteRead;
while ( (byteRead = inputStream.read(BUFFER_SIZE)) > 0 ) {
Upload binary file with okhttp from resources
You might not be able to do it directly using the library but you could create a little utility class which would do it for you. You could then simply re-use it everywhere you need it.
public class RequestBodyUtil {
public static RequestBody create(final MediaType mediaType, final InputStream inputStream) {
return new RequestBody() {
@Override
public MediaType contentType() {
return mediaType;
}
@Override
public long contentLength() {
try {
return inputStream.available();
} catch (IOException e) {
return 0;
}
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(inputStream);
sink.writeAll(source);
} finally {
Util.closeQuietly(source);
}
}
};
}
}
Then simply use it like so
OkHttpClient client = new OkHttpClient();
MediaType MEDIA_TYPE_MARKDOWN
= MediaType.parse("text/x-markdown; charset=utf-8");
InputStream inputStream = getAssets().open("README.md");
RequestBody requestBody = RequestBodyUtil.create(MEDIA_TYPE_MARKDOWN, inputStream);
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful())
throw new IOException("Unexpected code " + response);
Log.d("POST", response.body().string());
This example code was based on this code. Replace the Assets
file name and the MediaType
with your own.
How can I more efficently download large files over http?
As of version 11, Java has a built-in HttpClient which implements
asynchronous streams of data with non-blocking back pressure
and that's what you need if you want your code to run only when there's data to process.
If you can afford to upgrade to Java 11, you'll be able to solve your problem out of the box, using the HttpResponse.BodyHandlers.ofFile body handler. You won't have to implement any data transfer logic on your own.
Kotlin example:
fun main(args: Array<String>) {
val client = HttpClient.newHttpClient()
val request = HttpRequest.newBuilder()
.uri(URI.create("https://www.google.com"))
.GET()
.build()
println("Starting download...")
client.send(request, HttpResponse.BodyHandlers.ofFile(Paths.get("google.html")))
println("Done with download.")
}
Why okhttp internal package source file name start with -?
It's a convention taken from Okio https://github.com/square/okio/blob/master/okio/src/jvmMain/kotlin/okio/-JvmPlatform.kt
Effectively makes these completely inaccessible to Java code.
Related Topics
How to Make Links in a Textview Clickable
Maintain/Save/Restore Scroll Position When Returning to a Listview
Sending and Receiving Sms and Mms in Android (Pre Kit Kat Android 4.4)
Open Another Application from Your Own (Intent)
How Do We Use Runonuithread in Android
How to Detect When an Android App Goes to the Background and Come Back to the Foreground
Get Real Path from Uri, Android Kitkat New Storage Access Framework
How to Get Current Time and Date in Android
How to Send Emails from My Android Application
How to Start My App When the Phone Starts on Android
Android Asynctask Sending Callbacks to Ui
How to Change an Application Icon Programmatically in Android