I have to download one large compressed file (contains multiple files) from an FTP server. During downloading, if it is interrupted/paused by the user or network, the broken downloaded file should be saved. Later, user can resume download the same file from where it is broken.
You can use DownloadManager class.
Download manager is a system service that handles long-running HTTP downloads.
Check http://developer.android.com/reference/android/app/DownloadManager.html
Above class available since API level 9.
One can set the range of bytes to download using the Range HTTP header. All you have to do is remember how many bytes you previously downloaded. Using the classes from apache, it would look like this :
DefaultHttpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(youSourceUri);
// That's the important part. Count represents the number of bytes already downloaded.
// We leave the range open, so it will download 'till the end of the file.
httpGet.addHeader(new BasicHeader("Range", "bytes=" + count + "-"));
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
// Then read from the input stream
Remember to add the appropriate try/catch/finally clauses to handle the streams safely and be sure to close them. They were omitted here for readability.
Related
Im coding a RESTful API & Android client at the same time as I go and im currently working on pulling the users profile from the server. I feel like this should definitely be a get request being that im only pulling existing data and im not adding/editing anything to my database, but I do need a user_id param to be able to query for the appropriate profile. Can I send just one tiny little variable along with my HttpGet some how or am i supposed to use a HttpPost in this situation regardless?
Android uses Apache's HTTPClient. So, copying their tutorial code:
public void sendStringTo(String remoteUrl, String myString) {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(remoteUrl+"?string1="+myString);
HttpResponse response1 = httpclient.execute(httpGet);
// The underlying HTTP connection is still held by the response object
// to allow the response content to be streamed directly from the network socket.
// In order to ensure correct deallocation of system resources
// the user MUST either fully consume the response content or abort request
// execution by calling HttpGet#releaseConnection().
try {
System.out.println(response1.getStatusLine());
HttpEntity entity1 = response1.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
EntityUtils.consume(entity1);
} finally {
httpGet.releaseConnection();
}
return;
}
GET can support adding variables/parameters. For example you could make a Url that looks like this:
http://yourwebsite.com/script.php?user_id=19898424
I could not post my good question document.
Because, I am new here, So I can't add any image on the post. It is so bad.
Anyway, I try to explain without the images.
I send image file like bottom source code from android. It sends to WCF as stream. There is no problem on it.
File file = new File(path);
FileBody bin = new FileBody(file);
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(this.SERVICE_URI);
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("imageData", bin);
postRequest.setEntity(reqEntity);
HttpResponse response = httpClient.execute(postRequest);
When I want to see the uploaded file on the server, The widows cannot open.
First, I open the original file property. And I can see all properties of image like width,height, dpi.
But when I open the uploaded image file property, I can see only size of the file.
And then I want to see the files on notepade.
There is difference between the original file and uploaded file.
That is
--kpKP7FRpS5aYCWRNH0NHd0tGRj7hs2QYhVai_
Content-Disposition: form-data; name="imageData"; filename="ty-uz.jpg"
Content-Type: application/octet-stream
And then I see a tag too on bottom of file as --kpKP7FRpS5aYCWRNH0NHd0tGRj7hs2QYhVai_--
Android adds the tags on the original image file before sending, And then I can't see it as image.
So What is the problem? I use same WCF on silverlight application, IT runs very well. No problem. Image files uploads orginialy.
But My android application adds the tags in the image file. What is the problem?
Thank you already now...
I have also a same problem. I've response to client size of file then see that size of file when upload to server is larger then file in client and it had been broken.
I think data had been modify in progress send data to server. So that, way to upload file to wcf service as you apply in client is incorrect. You can reference a same topic here
For the next step of my application, I need to add download functionality. The user chooses what they want to download and could select anything from 1 file to thousands of them if they could be bothered to select that many.
I want to use Android's built in DownloadManager to provide this downloading functionality, but unfortunately I cannot see how I could implement it for my scenario.
In order for the target server to authorize the download, I need to send some JSON along in the request body. Like this, if I was doing it manually:
DataOutputStream output = new DataOutputStream(connection.getOutputStream());
output.writeBytes(rawData);
output.flush();
Where rawData is the JSON string. The request body is always set to POST.
I can't seem to find any way to add this JSON string to the DownloadManager, and until I can do that, the server will always reject the download.
The only other solution that I can think of, which I desperately want to avoid, is writing a PHP script on my server to take some GET parameters, generate the JSON and then redirect the request.
Does anybody know of a way that I can send my JSON data along with the DownloadManager? Each file that I'm downloading needs its own, unique, JSON string.
you cannot do that in Android's Download manager, see Download Manager Issue,
I had a similar requirement and I ended up Using HttpClient (Xamarin).
Sample Code-
using(var httpClient = new HttpClient()) {
using(var request = new HttpRequestMessage(new HttpMethod("POST"), URL)) {
request.Headers.TryAddWithoutValidation("User-Agent", userAgent);
request.Headers.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
request.Headers.TryAddWithoutValidation("Accept-Language", "en-US,en;q=0.5");
request.Headers.TryAddWithoutValidation("Connection", "keep-alive");
request.Headers.TryAddWithoutValidation("Referer",RefererURL);
request.Content = new StringContent("YOUR_REQUEST_BODY_HERE");
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
var responser = await httpClient.SendAsync(request);
return responser;
}
I'm looking for simple and clean solution for HTTP multipart post, which will send some Strings (form data) and several files with streaming support. (files needs to be streamed to avoid out of memory error)
I'd like to achieve this with the built-in "org.apache.httpclient" if possible.
I was able to create a clean solution with HttpURLConnection.
Despite all my efforts with this solution strings were sent with 8859-x encoding instead of UTF-8.
EDIT: My code is available at MultiPart with HttpURLConnection source
I created an output stream with this code:
HttpURLConnection connection = setupConnection();
dataOutputStream = new DataOutputStream(connection.getOutputStream());
After this I just wrote the data with dataOutputStream.writeBytes
If i could get an outputstream from httpclient it would be great, however it seems it works a different way.
Any help is appreciated.
Thanks
I've just created a simple solution for this: android_multipart_entity.
It's free (including for commercial usage), however if this is possible please keep references to me inside of my classes.
It's designed to be used with the built in Android HttpClient. Sample usage code:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yourhost.com");
MultipartEntity entity = new MultipartEntity();
entity.addPart(new StringPart("name", "yourname"));
File imageFile = // .. get your image file
entity.addPart(new FilePart("picture", imageFile, null, "image/jpeg"));
httppost.setEntity(entity);
HttpResponse httpResponse = httpclient.execute(httppost);
EDIT:
I reviewed your MultiPart with HttpURLConnection code. You get UTF-8 issue because of DataOutputStream usage. API says for that class:
Wraps an existing OutputStream and writes big-endian typed data to it. Typically, this stream can be read in by DataInputStream.
This class just does not suit your needs. In order to read the data you would have to have its direct opposite - DataInputStream on the other end.
So my advice would be to use plain OutputStream. And write bytes to it. Smth like this:
outputStream.write(partSeparator.getBytes());
outputStream.write(("Content-Disposition: form-data; name=\"" + parameter.getKey() + "\"" + lineEnd).getBytes());
outputStream.write(("Content-Type: text/plain; charset=UTF-8" + lineEnd).getBytes());
outputStream.write(("Content-Transfer-Encoding: 8bit" + lineEnd).getBytes());
outputStream.write(lineEnd.getBytes());
outputStream.write(parameter.getValue().getBytes("UTF-8")); // <= this is it!
outputStream.write(lineEnd.getBytes());
outputStream.write(partSeparator.getBytes());
This is how my programme works:
1) Display a picture from the server
2) User change the picture and upload it to the server
3) Display the picture by re-downloading from the server
This is how I get the picture from the server:
String src = "http://www.getyourpicture.com/mypicture.jpg"
HttpGet httpRequest = new HttpGet(URI.create(src) );
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse)httpclient.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
InputStream instream = bufHttpEntity.getContent();
Bitmap dp = BitmapFactory.decodeStream(instream);
//display dp from here...
The problem here is, whenever I "re-download" the image, it still shows the old picture.
To confirm that I've uploaded the picture, I've checked the folder containing the picture on the server and even visited the link on a browser. Both approaches show that the picture is indeed been uploaded. So I've narrowed down to the possibility that Android might have a http caching manager that is not "refreshing" the image link.
So, if the answer to my question is "yes", how can I force the application to not use the cache?
If the answer is "no", what is the thing that I've overlooked?
I'm not sure about the undercovers working and the defaults of HTTP request caching on Android, but if it is decent, then it should in theory suffice to add a query string with a timestamp to the request URL to trigger a brand new and fullworthy HTTP request.
String src = "http://www.getyourpicture.com/mypicture.jpg?" + System.currentTimeMillis();