Android Download Binary File Problems

Android download binary file problems

I don't know if it's the only problem, but you've got a classic Java glitch in there: You're not counting on the fact that read() is always allowed to return fewer bytes than you ask for. Thus, your read could get less than 1024 bytes but your write always writes out exactly 1024 bytes possibly including bytes from the previous loop iteration.

Correct with:

 while ( (len1 = in.read(buffer)) > 0 ) {
f.write(buffer,0, len1);
}

Perhaps the higher latency networking or smaller packet sizes of 3G on Android are exacerbating the effect?

Retrofit fails to download binary file in an Android app – end result is a corrupted file that is larger than expected

Suppose problem is not with Retrofit, but with your OkHTTP3 interceptor, specifically here:

val bodyString = response.body()!!.string()

Here are string() contents:

  /**
* Returns the response as a string.
*
* If the response starts with a
* [Byte Order Mark (BOM)](https://en.wikipedia.org/wiki/Byte_order_mark), it is consumed and
* used to determine the charset of the response bytes.
*
* Otherwise if the response has a `Content-Type` header that specifies a charset, that is used
* to determine the charset of the response bytes.
*
* Otherwise the response bytes are decoded as UTF-8.
*
* This method loads entire response body into memory. If the response body is very large this
* may trigger an [OutOfMemoryError]. Prefer to stream the response body if this is a
* possibility for your response.
*/
@Throws(IOException::class)
fun string(): String = source().use { source ->
source.readString(charset = source.readBomAsCharset(charset()))
}

You can check ResponseBody source code for more details.

Suppose using body.source() instead would help.
(or just avoid intercepting binary files)

Good interceptor implementation example is here:
HTTPLoggingInterceptor.

Android: How to download binary files from the internet


String FileName = "/LocalDisk/jm";

This is absolute path so you have to use it like this

String FileName = Environment.getExternalStorageDirectory() + "/jm"; // /sdcard/jm

More info about getExternalStorageDirectory().
Also there is no good idea to download a file in UI thread cause it's blocking operation and may cause Activity Not Responding. The best way will be to use AsyncTask to handle this operation in background and notify the gui when you're done.

java google drive API unable to download binary file

The file.get method does return the file data, however only for binary file types. that is what this error message its telling you.

Only files with binary content can be downloaded. Use Export with Docs Editors files.

String fileId = "0BwwA4oUTeiV1UVNwOHItT0xfa2M";
OutputStream outputStream = new ByteArrayOutputStream();
driveService.files().get(fileId)
.executeMediaAndDownloadTo(outputStream);

All other file types those being google docs, google sheets. check this page for more: mimetype

Need to be exported from the google mime type to a standard mime type. If you check the manage-downloads#java page you will find a documented example of how to use this method.

String fileId = "1ZdR3L3qP4Bkq8noWLJHSr_iBau0DNT4Kli4SxNc2YEo";
OutputStream outputStream = new ByteArrayOutputStream();
driveService.files().export(fileId, "application/pdf")
.executeMediaAndDownloadTo(outputStream);

The trick with this method is to ensure you are setting the correct mimetype

How to download binary file

Use response.bodyBytes:

void downloadFile(File f) async {
var url = Uri.encodeFull('https://API_URL');
var response = await http.post(url, headers: {HttpHeaders.authorizationHeader: 'Bearer '},});
await f.writeAsBytes(response.bodyBytes);
}

I removed the Accept header as it made no sense. You're hinting the server that you'll expect JSON, whereas you really want a PDF.

Running binary files

That is not supported on modern versions of Android, for security reasons. Quoting the documentation:

Untrusted apps that target Android 10 cannot invoke exec() on files within the app's home directory. This execution of files from the writable app home directory is a W^X violation. Apps should load only the binary code that's embedded within an app's APK file.

Please note that what you are doing may also violate the terms of service of your desired app distribution channel.

Downloading a single file with AsyncTask

AsyncTask just runs your code in the background thread. To download a pdf file is like any other file.

You will require to use HttpUrlConnection, Create a FileOutputStream and write the inputstream. Refer this

Have the above code executed in doInBackground of AsyncTask class and better pass the url in the constructor and do everything inside the doInBackground method. Since you don't want to block the UI thread.



Related Topics



Leave a reply



Submit