1

For my Android app I need to download a file from a site requiring login. It is not basic http authentication but rather form emulation.

Being new to Android I really don't know how to get started, but in PHP it is easy with cUrl:

// Set standard options
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7) Gecko/20040803 Firefox/0.9.3");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, "somecookiejar");
curl_setopt($ch, CURLOPT_COOKIEFILE, "somecookiefile");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// Login
curl_setopt($ch, CURLOPT_URL, "https://example.com" );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, "username=myusername&password=mypassword");
curl_exec($ch);

// Get the file
curl_setopt($ch, CURLOPT_URL, "http://example.com/files/myfile.mp3");
curl_setopt($ch, CURLOPT_POST, 0 );
writefile(curl_exec($ch), "myfile.mp3");
curl_close($ch);

I would appreciate any help in getting this done in Android.

Note: I mention HttpURLConnection in the subject, but other suggestions are of course more than welcome :)

Edit: I think I should clarify a bit. In the first request to the login form the username and password is set. The server returns a set of cookies which is then handed over to the second request where the actual file download takes place. The code is actually a working example from PHP (albeit anonymized) and my specific problem is handling the cookies between the requests. In cUrl all this cookie stuff happens automatically. Thanks!

1
  • Sorry, misunderstood your questions. Commented Jun 22, 2011 at 21:49

2 Answers 2

4

This is what I came up with helped by S201's answer plus a lot of googling. The code is simplified and without try-catch constructions.

HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://example.com/login");
HttpResponse response = null;
List<NameValuePair> postFields = new ArrayList<NameValuePair>(2);

// Set the post fields
postFields.add(new BasicNameValuePair("username", "myusername"));
postFields.add(new BasicNameValuePair("password", "mypassword"));
post.setEntity(new UrlEncodedFormEntity(postFields, HTTP.UTF_8));

// Execute the POST request
response = client.execute(post);

// Now GET the file
HttpGet get = new HttpGet("http://example.com/files/myfile.mp3");
response = client.execute(get);

HttpEntity entity = response.getEntity();
InputStream in = entity.getContent();

// Save the file to SD
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
path.mkdirs();
File file = new File(path, "myfile.mp3");
FileOutputStream fos = new FileOutputStream(file);

byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
        fos.write(buffer, 0, len1);
}

fos.close();
Sign up to request clarification or add additional context in comments.

Comments

2

You going to want to use an HttpClient object in combination with HttpPost, HttpGet, and HttpResponse objects. It is probably easier to just look at an example.

HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(context.getString(R.string.loginURL));
HttpResponse response = null;
List<NameValuePair> postFields = new ArrayList<NameValuePair>(2);  

// Set the post fields
postFields.add(new BasicNameValuePair("username", settings.getString("username", "null")));
postFields.add(new BasicNameValuePair("password", settings.getString("password", "null")));
post.setEntity(new UrlEncodedFormEntity(postFields, HTTP.UTF_8));

// Execute the POST request
response = client.execute(post);

Assuming the login was successful, you can now execute GET and POST requests as an authenticated user as long as you execute them though the HttpClient that you executed the login through. It is this object that manages the cookies. Hope this helps!

EDIT: Forgot to mention that you can of course use the HttpRespose object to perform error checking.

4 Comments

Thanks for the example. I will try it out now.
It works so far! The cookies are managed and the server response is correct. I continue with: String url = "example.com/files/myfile.mp3"; HttpGet get = new HttpGet(url); response = client.execute(get); But how do I get the actually file's binary data? In other words, how do I get the contents out of the GET request?
Finally I got it right thanks to the basic info you provided! I have added my code in a new answer. I am not sure if this is the proper way to add my code or if I should just update my original question though ....
Glad to hear you got it working. I probably should have keep the code below what I posted which contained the HttpEntity object to get the content from the server, but it looks like you figured that out! And yes, adding your solution in another answer is always welcome.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.