我想从 Android 中的服务器下载一个 zip 文件,为此我使用以下代码。它还需要授权,以便我在 URL 连接请求中传递用户名和密码。但我总是收到401-Response code(UNAUTHORIZED)。
代码 :-
protected String doInBackground(final String... params) {
int count;
try {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
/*Authenticator.setDefault(new Authenticator(){
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(Constants.USERNAME,Constants.PASSWORD.toCharArray());
}});*/
Log.i(TAG, "URL == " + params[0]);
final URL url = new URL(params[0]);
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
final String auth = new String(Constants.USERNAME + ":" + Constants.PASSWORD);
connection.setRequestProperty("Authorization", "Basic " + Base64.encodeToString(auth.getBytes(), Base64.URL_SAFE));
//connection.addRequestProperty("Authorization", "Basic " + Base64.encodeToString(auth.getBytes(), Base64.DEFAULT));
connection.setUseCaches(false);
connection.setConnectTimeout(5000);
connection.setDoOutput(true);
connection.connect();
Log.i(TAG, "Response == " + connection.getResponseMessage());
Log.i(TAG, "Response Code == " + connection.getResponseCode());
// download the file
final InputStream input = new BufferedInputStream(connection.getInputStream());
// Path to the just created empty db
// this will be useful so that you can show a tipical 0-100% progress bar
lenghtOfFile = connection.getContentLength();
lengthOfFileInMB = lenghtOfFile / 1048576;
Log.i(TAG, "File Size in MB = " + lengthOfFileInMB);
outFileName = Environment.getExternalStorageDirectory() + File.separator + ZIP_NAME;
final File file = new File(outFileName);
if (!file.exists()) {
file.createNewFile();
}
// Output stream
final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
final byte data[] = new byte[lenghtOfFile];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress("" + total);
bufferedOutputStream.write(data, 0, count);
}
bufferedOutputStream.flush();
bufferedOutputStream.close();
input.close();
} else {
Toast.makeText(DashboardActivity.this, "MEDIA IS NOT MOUNTED.", Toast.LENGTH_LONG).show();
}
} catch (final MalformedURLException e) {
flag = false;
Log.e(TAG, e.getMessage(), e);
} catch (final FileNotFoundException e) {
flag = false;
Log.e(TAG, e.getMessage(), e);
} catch (final IOException e) {
flag = false;
Log.e(TAG, e.getMessage(), e);
} catch (final Exception e) {
Log.e(TAG, e.getMessage(), e);
}
return null;
}
我在同一台服务器中拥有 Web 服务,并且为了获得 JSON/XML 响应,我使用了 DefaultHttpClient。这工作得很好,我也得到了响应代码。我不知道为什么它在 URLConnection 时没有授权。
这是它的代码。
String line = null;
try {
final URL urlObj = new URL(url);
final HttpHost host = new HttpHost(urlObj.getHost(), urlObj.getPort(), urlObj.getProtocol());
final HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
HttpConnectionParams.setConnectionTimeout(httpParameters, Constants.CONNECTION_TIME_OUT);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
HttpConnectionParams.setSoTimeout(httpParameters, Constants.CONNECTION_TIME_OUT);
final DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
final AuthScope scope = new AuthScope(urlObj.getHost(), urlObj.getPort());
final UsernamePasswordCredentials creds = new UsernamePasswordCredentials(Constants.USERNAME, Constants.PASSWORD);
final CredentialsProvider credentialProvider = new BasicCredentialsProvider();
credentialProvider.setCredentials(scope, creds);
final HttpContext credContext = new BasicHttpContext();
credContext.setAttribute(ClientContext.CREDS_PROVIDER, credentialProvider);
final HttpGet job = new HttpGet(url);
job.addHeader("USER-AGENT", userAgentString);
final HttpResponse httpResponse = httpClient.execute(host,job,credContext);
final HttpEntity httpEntity = httpResponse.getEntity();
try {
line = EntityUtils.toString(httpEntity);
} catch (final ParseException e) {
line = "Error";
Log.e("Parse Error", e.getMessage().toString());
} catch (final IOException e) {
line = "Error";
Log.e("IOException Error", e.getMessage().toString());
}
final StatusLine status = httpResponse.getStatusLine();
Log.d("Authentication Status = ", status.toString());
} catch (final ClientProtocolException e1) {
line = "Error";
Log.e("ClientPrtocol Error", e1.getMessage().toString());
} catch (final ConnectTimeoutException e1) {
line = "ConnectionTimeOut";
Log.e("Connection Error", e1.getMessage().toString());
} catch (final IOException e1) {
Log.e("IO Error", e1.getMessage().toString());
line = "Error";
}
我还尝试在 URLConnection 中添加以下代码以进行身份验证,但这对我也不起作用。
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(loginNameString, passwordString.toCharArray());
}
});
问题:-
1)是服务器端还是android端的问题?
2) 我可以使用我拥有的默认httpclient 代码下载文件吗?如果是的话,任何线索如何下载它,因为我认为我只能通过这种方式获取内容,而不是整个文件。