I try to download a file using services in android... I was able to write the program and I can download what ever I want. but the problem is with the progress bar!!!
I'm not able to define the total file length (or size) and the current downloaded size.
I used this code to get the file lenght
URL url = new URL(urlToDownload);
URLConnection connection = url.openConnection();
connection.connect();
int fileLength = connection.getContentLength();
and I used this part of code to define the current downloaded size
InputStream input = new BufferedInputStream(connection.getInputStream());
OutputStream output = new FileOutputStream("/sdcard/BarcodeScanner-debug.apk");
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
int currentValue=(total * 100 / fileLength);
output.write(data, 0, count);
}
the problem is that at the end of download I got something like 241% instead of 100% (because the fileLength for ex was around 12226 and the total was 29349)
Do you have any idea about this topic.
checkout this links for your reference
Download a file with Android, and showing the progress in a ProgressDialog
http://www.java-samples.com/showtutorial.php?tutorialid=1521
http://www.androidhive.info/2012/04/android-downloading-file-by-showing-progress-bar/
http://www.androidbegin.com/tutorial/android-download-progress-bar/
Related
How to receive an image file through Rest APIs. There is an option of MULTIPART_FORM_DATA which looks like it will send files in parts as in more than one request.
I want to receive images very fast on server. around 2 images per second.
Simply read image in a File and use Response class to build the response.
Response.ok(new File("myimage.jpg"), "image/jpeg").build();
There are other variations of the same.
Read the image using following.
URL url = new URL("http://localhost:8080/myimage/1");
URLConnection connection = url.openConnection();
input = connection.getInputStream();
byte[] buffer = new byte[1024];
int n = - 1;
OutputStream fos = new FileOutputStream("Output.jpg" );
while ( (n = input.read(buffer)) != -1)
{
fos.write(buffer, 0, n);
}
fos.close();
You can use Apache HTTP client to make it prettier.
For a project I am working on I have a few MP4 video files sitting on a Server.
A Java based web app I am writing needs to play these files in the browser. Due to a security restriction, only the server hosting the web app has access to this server, the browsers using the web app do not have access, making it impossible to use HTML 5 for play back.
The solution I am working on, is having a servlet (sitting on the web app server), access the video file. Write the video as it's output, and have the servlet be the source for the HTML player.
However I seem to be unable to successfully output the video file as servlet output in a streaming fashion.
I've done a large amount of research. The closest thing I came to a solution is this:
private static final int BUFFER_LENGTH = 1024 * 16;
private static final long EXPIRE_TIME = 1000 * 60 * 60 * 24;
private static final Pattern RANGE_PATTERN = Pattern.compile("bytes=(?<start>\\d*)-(?<end>\\d*)");
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
URL video = new URL("http://localhost/App/Videos/FileSD.mp4");
URLConnection yc = video.openConnection();
yc.setDoOutput(true);
int length = yc.getContentLength();
int start = 0;
int end = length - 1;
int contentLength = end - start + 1;
response.reset();
response.setBufferSize(BUFFER_LENGTH);
response.setHeader("Accept-Ranges", "bytes");
response.setDateHeader("Last-Modified", yc.getLastModified());
response.setDateHeader("Expires", System.currentTimeMillis()
+ EXPIRE_TIME);
response.setContentType(yc.getContentType());
response.setHeader("Content-Range",
String.format("bytes %s-%s/%s", start, end, length));
response.setHeader("Content-Length", String.format("%s", contentLength));
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
ReadableByteChannel input = Channels.newChannel(yc.getInputStream());
int bytesRead;
int bytesLeft = contentLength;
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_LENGTH);
try (OutputStream output = response.getOutputStream()) {
while ((bytesRead = input.read(buffer)) != -1 && bytesLeft > 0) {
buffer.clear();
output.write(buffer.array(), 0,
bytesLeft < bytesRead ? bytesLeft : bytesRead);
bytesLeft -= bytesRead;
output.flush();
}
output.close();
input.close();
}
}
For the most part, this code works fine, it takes a URL as input, and streams it as Output. The problem is, it only works for HD video files. SD video files simply don't play. Was hoping anyone has any idea why that is, and how it can be fixed.
I am using GZIPInputStream to download PDF file. I want to show the download progress of the file on a UI button. But, I am not getting the actual size of the file, what I am getting is compressed size due to which I am unable to show the correct download progress. This download progress is exceeding 100 as the actual file size is greater than the compressed size of file.
Header content of file from server: Following info I receive from server, from which I am using content-length which is giving compressed file size.
1.Connection
2.Content-Encoding
3.Content-length
4.Content-Type
5.Keep-Alive
6.Server
7.Date
Here is my code. Is there any way to get original size of file?
long fileLength = httpResponse.getEntity().getContentLength();//
GZIPInputStream input = new GZIPInputStream(new BufferedInputStream(
httpResponse.getEntity().getContent()));
FileOutputStream output = new FileOutputStream(destinationFilePath);
byte data[] = new byte[1024];
long total = 0;
float percentage = 0;
int count;
currentDownloadingPercentage=0;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
// publishing the progress....
percentage = (float)total/(float)fileLength;
percentage *= 100;
if ((int)percentage > (int)currentDownloadingPercentage) {
currentDownloadingPercentage = percentage;
Bundle resultData = new Bundle();
resultData.putBoolean(DOWNLOAD_FAILED, false);
resultData.putInt(DOWNLOAD_PROGRESS ,(int)percentage);
receiver.send(processID, resultData);
resultData = null;
}
}
You're looking at it the wrong way. You should be counting the compressed bytes that you read and calculating the progress based on those. Instead, you're counting the decompressed bytes and comparing it with the compressed file size. In answer to your question, there's no (reliable) way to determine the size of a gzipped file without decompressing it.
Update: Here's one way you could count the uncompressed bytes coming in. Wrap the raw input stream with a TeeInputStream before wrapping it with the GZIPInputStream. Make the TeeInputStream branch to a CountingOutputStream. Then you'll always have a current count of the compressed bytes that have been downloaded via getByteCount()
This issue discuss result seems not way to avoid HttpURLConnection.getInputStream() automatically returned GZIPInputStream, once you let HttpURLConnection accept gzip compression, you won't calculate download progress accurately, the only one we can do just disable gzip as acceptable encoding :
HttpURLConnection.setRequestProperty("Accept-Encoding", "identity");
Another choice is use AndroidHttpClient, I had tested about this, even we present accept gzip encoding like this :
HttpUriRequest.addHeader("Accept-Encoding", "gzip");
the InputStream instance that return by HttpResponse.getEntity().getContent() will be EofSensorInputStream, an original InputStream is what we wanted, isn't GZIPInputStream, that make us possible to wrap it to GZIPInputStream by myself, we can use TeeInputStream and CountingOutputStream to finish calculating download progress.
HttpResponse response = ...;
HttpEntity entity = response.getEntity();
long fileSize = entity.getContentLength();
InputStream ins = entity.getContent(); // instance of EofSensorInputStream
CountingOutputStream coStrem = new CountingOutputStream(new ByteArrayOutputStream(100));
GZIPInputStream inStrem = new GZIPInputStream(new TeeInputStream(ins, coStrem, true));
byte[] buffer = new byte[6 * 1024]; // 6K buffer
int offset;
while ((offset = inStrem.read(buffer)) != -1) {
tmpFileRaf.write(buffer, 0, offset);
postDownloadProgress(fileSize, coStrem.getByteCount());
}
I think that's all we can do with this problem, I tried pick up android libcore source with my project so we can customize HttpURLConnectionImpl then suppress it return GZIPInputStream, but many errors makes trouble, I discard this effort.
In this post, Jesse Wilson suggested we the best choice client of Android is HttpURLConnection, so I'm looking for how to solve this problem always, I hope I can get a way soon.
I am transferring file from client to server. I dont know the amount of time it will take to transfer. But my UI will simple remain the same without any intimation to user. I need to keep a progress bar in such a way it should be progress till file is uploaded. How can i acheive this.
I am abit aware of this scenario in .net. but how can we do it in java?
trashgod's answer is correct for actions that are truly 'indeterminate'. Why do you think that your file transfer fits into this category? Haven't you ever downloaded a file on the internet with some sort of progress bar associated with it? Can you imagine not having that?
See the example below that was provided among the answers to How do I use JProgressBar to display file copy progress?
public OutputStream loadFile(URL remoteFile, JProgressBar progress) throws IOException
{
URLConnection connection = remoteFile.openConnection(); //connect to remote file
InputStream inputStream = connection.getInputStream(); //get stream to read file
int length = connection.getContentLength(); //find out how long the file is, any good webserver should provide this info
int current = 0;
progress.setMaximum(length); //we're going to get this many bytes
progress.setValue(0); //we've gotten 0 bytes so far
ByteArrayOutputStream out = new ByteArrayOutputStream(); //create our output steam to build the file here
byte[] buffer = new byte[1024];
int bytesRead = 0;
while((bytesRead = inputStream.read(buffer)) != -1) //keep filling the buffer until we get to the end of the file
{
out.write(buffer, current, bytesRead); //write the buffer to the file offset = current, length = bytesRead
current += bytesRead; //we've progressed a little so update current
progress.setValue(current); //tell progress how far we are
}
inputStream.close(); //close our stream
return out;
}
As shown in How to Use Progress Bars, you can specify indeterminate mode until you either have enough data to gauge progress or the download concludes. The exact implementation depends on how the transfer takes place. Ideally, the sender provides the length first, but it may also be possible to calculate the rate dynamically as data accumulates.
I am trying to download a text file in Android, i know how to load image file, how different is text file downloading from it?
Moerover how to retrive contents from the downloaded file?
You are asking a few things, this should give you an idea of how to get a remote file using urlconnection and associated classes
URL u = new URL(url);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
URLConnection conn = u.openConnection();
fs = conn.getContentLength();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
String PATH_op = Environment.getExternalStorageDirectory()
+"//"+ filename;
f = new FileOutputStream(new File(PATH_op));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = in.read(buffer)) > 0 ) {
f.write(buffer,0, len1);
completed += len1;
}
f.close();`enter code here`
There will be no difference in downloading the text file or image or XML. every thing is same. but the usage after getting the stream depends on the type of the content.
If its a Image we will decode the stream to convert it to an image.
If its a Text we need to read the content character by character until the whole content got read or got -1 as the character which denotes the end of the file.
When coming to the XML file file we will directly pass the input stream object to Parser.