I am working in an android application and I am downloading a file from an url. Every thing works fine, but when the internet connection goes in between(After opening a connection) the downloading time out never occurs and the connection never ends.
Suggest me a solution to solve this issue
**URL url = new URL("fileURL");
URLConnection connection = url.openConnection();
connection.setConnectTimeout(5000);
File file = new File(context.getFilesDir(), "" + filename);
// getting file length
int lenghtOfFile = connection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream(file);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
int status = (int) ((total * 100) / lenghtOfFile);
publishProgress("" + status);
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close()**
You can use Retrofit Library to download files from server,
Retrofit uses OkHttp internally
Please refer below URL,
https://futurestud.io/tutorials/retrofit-2-how-to-download-files-from-server
final FileDownloadService downloadService =
ServiceGenerator.createService(FileDownloadService.class);
Call<ResponseBody> call =
downloadService.downloadFileWithDynamicUrlSync(fileUrl);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, final Response<ResponseBody>
response) {
if (response.isSuccessful()) {
Log.d(TAG, "server contacted and has file");
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
boolean writtenToDisk = writeResponseBodyToDisk(FileDownloadActivity.this, response.body(), null);
Log.d(TAG, "file download was a success? " + writtenToDisk);
return null;
}
}.execute();
} else {
Log.d(TAG, "server contact failed");
}
}
And you can also use #Streaming annotation for large files. Retrofit will handle the large file download also
Related
I'm trying to have users submit files on discord that are then uploaded to a site for processing. However, there seem to be something wrong wiht my code.
When i upload a file i get respone code 400 (bad request) but the site should accept files of w3g format.
private static void onFileUpload(Message.Attachment attachment, TextChannel channel) {
// api.wc3stats.com/upload
String fileName = attachment.getFileName();
if (fileName.substring(fileName.length() - 3).equals("w3g")) {
File file = new File(attachment.getFileName());
attachment.downloadToFile(file);
try {
HttpHelper.postFile(file, "https://api.wc3stats.com/upload");
channel.sendMessage("Uploading: " + file.toString()).queue();
} catch (IOException e) {
e.printStackTrace();
channel.sendMessage(e.getMessage()).queue();
}
System.out.println("Deleted");
file.delete();
} else {
channel.sendMessage("Invalid file type.").queue();
}
}
public static void postFile(File file, String url) throws IOException {
HttpURLConnection connection = null;
FileInputStream fis = null;
BufferedInputStream bis = null;
BufferedOutputStream out = null;
try {
URL urlForPostRequest = new URL(url);
connection = (HttpURLConnection) urlForPostRequest.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
//if (responseCode == HttpURLConnection.HTTP_OK) {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
out = new BufferedOutputStream(connection.getOutputStream());
byte[] buffer = new byte[8192];
int i;
while ((i = bis.read(buffer)) > 0) {
out.write(buffer, 0, i);
}
//}
int responseCode = connection.getResponseCode();
System.out.println("Response: " + connection.getResponseMessage());
System.out.println(responseCode);
} finally {
if (fis != null) fis.close();
if (bis != null) bis.close();
if (out != null) out.close();
System.out.println("closed");
}
}
The current exception it's throwing me is that the file cannot be found. But I can clearly see it in the program directory after it's been attached to discord and downloaded. This also only happens the first time I upload the file. The second time i upload the same file it just gives me the bad request response.
First upload attempt LastReplay.w3g output:
java.io.FileNotFoundException: lol.w3g
C:\SomePath\lol.w3g
cannot be read
closed
Deleted
I can also note that the file now exists in the program directory. Though it should've been removed after everything is complete.
Second upload attempt of LastReplay.w3g output
C:\SomePath\lol.w3g
Can be read
Response: Bad Request
closed
Deleted
I managed to do it using Javascript with help using request-promise, as for java i did not...
if (msg.attachments.size > 0) {
let attached = msg.attachments.array()[0];
const request = require('request-promise');
let formData = {
file: request (attached.url)
};
request.post('https://api.wc3stats.com/upload', {formData, json: true})
.then(function (json) {
// on success handle response json
})
.catch(function (err) {
console.log(err);
});
}
I am using a link when I open that link in the browser it generates a json.txt file and downloads it. I want to fetch this txt file in an android application and want to get JSON data from this txt file.
new DownloadFileFromURL().execute("your_file_downloadable_url");
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
System.out.println("Starting download");
}
/**
* Downloading file in background thread
* */
#Override
protected String doInBackground(String... f_url) {
int count;
try {
String root = Environment.getExternalStorageDirectory().toString();
System.out.println("Downloading");
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream(root+"/downloadedfile.txt");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
/**
* After completing background task
* **/
#Override
protected void onPostExecute(String file_url) {
System.out.println("Downloaded");
pDialog.dismiss();
}
}
I'm trying to download a binary file using:
URL url = new URL(urlStr);
HttpURLConnection ucon = (HttpURLConnection) url.openConnection();
ucon.connect();
InputStream is = new BufferedInputStream(ucon.getInputStream());
When run via mobile data (on Samsung Galaxy 4, Android 5.0.1) I receive the following response
j���UFEHLER��6ERROR��`Заявеното съдържание не може да бъде заредено ��&Wrong MIME-Type���Fback��2
Which means "The content requested cannot be loaded" in Bulgarian (the server I download from is Bulgaria). But more informative seems "Wrong MIME-Type" at the end of the response.
I tried the same using HttpGet with no result.
The weird thing is everything is ok when I execute the same request via Wifi.
Also I can download the file from the brower on mobile data, but not for the code. Also I've tested on Lenovo with Android 4.4.2 via mobile data and is also worked.
I noticed I'm getting Content-Type: application/vnd.wap.wmlc (logged ucon.getResponseCode()) when connected via mobile data and nothing set as content type when via WiFi.
Any ideas? :/
Here's my working code for file downloading. You can have a look to check if you're missing something.
public class ImageDownloaderAsyncTask extends
AsyncTask<Void, Integer, Integer> {
private static File f;
protected void doInBackground() throws IOException {
File dir = new File(Constants.FILE_PATH);
if (!dir.exists()) dir.mkdir();
f = new File(Constants.FILE_PATH + Constants.FILE_NAME);
if (f != null && !f.exists()) {
f.createNewFile();
}
try {
URL url = new URL(fileUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
String data1 = f.getPath();
FileOutputStream stream = new FileOutputStream(data1);
byte data[] = new byte[4096];
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
}
stream.write(data, 0, count);
}
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected Integer doInBackground(Void... params) {
try {
doInBackground();
} catch (IOException e) {
e.printStackTrace();
}
return 1;
}
protected void onPostExecute(Integer result) {}
}
This question is a little bit long, so there might be confusions and in any case if you have, please don't hesitate to let me know..
I was trying to make a code to upload a video to the web server. In order to do so, I split the code's roles into three (in general, not including the details):
an activity that uploads a video and an inner class called VideoUploader that extends AsyncTask to execute the upload process,
a manager class called VideoManager.java that deals with uploading a video with the POST method,
and the PHP part that takes the POST video and stores it in the server.
Here is the uploadVideo() method inside the activity.
public void uploadVideo(final String stringPath) {
class VideoUploader extends AsyncTask<Void, Void, String> {
ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(UploadVideoActivity.this);
pDialog.setMessage("Uploading");
pDialog.setIndeterminate(true);
pDialog.setProgress(0);
pDialog.show();
final int totalProgressTime = 100;
final Thread thread = new Thread() {
#Override
public void run() {
int jumpTime = 0;
while(jumpTime < totalProgressTime) {
try {
sleep(200);
jumpTime += 5;
pDialog.setProgress(jumpTime);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
};
thread.start();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
pDialog.dismiss();
}
#Override
protected String doInBackground(Void... params) {
VideoManager videoManager = new VideoManager(getApplicationContext());
final String msg = videoManager.getUploadVideoResponse(stringPath);
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
});
return msg;
}
}
VideoUploader uv = new VideoUploader();
uv.execute();
}
The following code is the VideoManager.java class.
public class VideoManager {
private Context context;
private int serverResponseCode;
private String urlUploadVideo = ServerURL.UPLOAD_VIDEO;
public VideoManager(Context context) {
this.context = context;
}
public String getUploadVideoResponse(String filePath) {
HttpURLConnection conn = null;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
/*
* a buffer is a temporary memory area in which data is stored while it is being processed
* or transferred, especially one used while streaming video or downloading audio.
* here the maximum buffer size is 1024 bytes * 1024 bytes = 1048576 bytes ≈ 1.05 megabytes.
*/
int maxBufferSize = 1 * 1024 * 1024;
File sourceFile = new File(filePath);
// check if the source file is a proper file.
if (!sourceFile.isFile()) {
Toast.makeText(context, "File does not exist.", Toast.LENGTH_SHORT).show();
return null;
}
try {
// an input stream that reads bytes from a file
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL(urlUploadVideo);
conn = (HttpURLConnection) url.openConnection();
// allow the url connection input
conn.setDoInput(true);
// allow the url connection output
conn.setDoOutput(true);
// not allow the url connection to use cache
conn.setUseCaches(false);
conn.setRequestMethod("POST");
// set the value of the requested header field
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("myFile", filePath);
// a data output stream lets an application write primitive Java data types to an output stream in a portable way.
// an application can then use a data input stream to read the data back in.
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"myFile\";filename=\"" + filePath + "\"" + lineEnd);
dos.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
Log.i("Huzza", "Initial .available : " + bytesAvailable);
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
serverResponseCode = conn.getResponseCode();
fileInputStream.close();
// flush the data output stream.
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (Exception e) {
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
}
// if the server responds OK
String response;
if (serverResponseCode == 200) {
StringBuilder sb = new StringBuilder();
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
bufferedReader.close();
} catch (IOException e) {
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
}
response = sb.toString();
return response;
} else {
response = "An error occurred while uploading the video.";
return response;
}
}
}
And finally this is the PHP side that takes the video and stores it in the server.
<?php
$base_location = dirname(__FILE__);
$directory = '/uploaded_videos/';
$location = $base_location . $directory;
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$file_name = $_FILES['video']['name'];
$file_size = $_FILES['video']['size'];
$file_type = $_FILES['video']['type'];
$temp_name = $_FILES['video']['tmp_name'];
move_uploaded_file($temp_name, $location.$file_name);
} else {
echo $location;
}
?>
If I run the programme and execute the uploadVideo() method, I manage to get the string value from the public String getUploadVideoResponse(String filePath) method like below.
From my diagnosis, now that I get the string response, the server response code is 200, which means that the request was successful. But I still fail to have the video file itself in the server. Can any superman find out the real matter here?
am writing a downloadManager and i need a hint. there i could create an event an fire it when ever i wanted. but i cant seem to find how to do that in java. what i want to do is i want to create an event for my class and then fire it inside one of the classes' member methods. now when ever this Class is called and sees that the download is finish(i.e. some variable has reached 100 for example) it fires an event indicating the situation. how can i create that in java?
public class DownloadManager
{
static Queue<AvailableGame> downloadQueue;
static Integer currenProgress;
static String currentDownload;
static Boolean isRunning;
/**
* Start download
*/
public void startDownloading()
{
AsyncTask task = new AsyncTask()
{
#Override
protected Object doInBackground(Object[] objects)
{
downloadNextFile();
return null;
private static String downloadFile(String downloadUrl)
{
String toDownload = downloadUrl;
String fileName = getFileNameFromUrl(toDownload);
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager)
MainActivity.getContext().getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"DownloadManager");
wl.acquire();
try
{
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try
{
URL url = new URL(toDownload);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
{
return "Server returned HTTP " + connection.getResponseCode() + " "
+ connection.getResponseMessage();
}
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream("/sdcard/" + fileName);
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1)
{
total += count;
// publishing the progress....
if (fileLength > 0)
{
currenProgress = ((int) (total * 100 / fileLength));
currentDownload = "Downloading " + fileName;
}
output.write(data, 0, count);
}
}
catch (Exception e)
{
return e.toString();
}
finally
{
try
{
if (output != null)
{
output.close();
}
if (input != null)
{
input.close();
}
}
catch (IOException ignored)
{
}
if (connection != null)
{
connection.disconnect();
}
}
}
finally
{
wl.release();
}
return null;
}
}
How can i save information when my download is finish,the second probleem is how to a
First I think you should be using Android's DownloadManager for this. If you are, you can register a BroadcastReceiver that detects when a download is finished.
There is a full example you can download and run on your phone with full source code for you to see how this can be done: https://github.com/commonsguy/cw-omnibus/tree/master/EmPubLite/T16-Update
Check specifically the files DownloadCheckService.java and DownloadCompleteReceiver.java.
Hope it helps.