我遵循了一些在线教程并创建了此代码来下载我在 Dropbox 中托管的文件
我正在使用异步任务来执行此操作
// AsyncTask to download a file
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
public DownloadTask(Context context) {
this.context = context;
}
@Override
protected String doInBackground(String... sUrl) {
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
wl.acquire();
try {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
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();
// TODO
File file = new File(Environment
.getExternalStorageDirectory().getPath()
+ "/kathmandu.map");
if (file.exists()) {
Log.i("File Exists", "Code Gets here, file exists");
return "exists";
// if (connection.getResponseCode() ==
// HttpURLConnection.HTTP_NOT_MODIFIED) {
//
// return null;
// }
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
Log.i("Length", String.valueOf(fileLength));
// download the file
input = connection.getInputStream();
output = new FileOutputStream(Environment
.getExternalStorageDirectory().getPath()
+ "/kathmandu.map");
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled())
return null;
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
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;
}
单击下载选项菜单时,我会调用下载代码。
final DownloadTask downloadTask = new DownloadTask(MapActivity.this);
downloadTask
.execute("https://dl.dropboxusercontent.com/u/95497883/kathmandu-2013-8-12.map");
mProgressDialog
.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
downloadTask.cancel(true);
}
});
该代码工作正常,但有时输出流不会写入完整文件并退出。一切看起来都很好。文件已下载,但已损坏。
getContentLength() 也返回 -1,因此我无法检查整个文件是否已使用内容长度下载。该文件是离线矢量地图,我需要它来显示离线地图。损坏的文件在尝试访问它时会导致运行时异常。有什么方法可以确保文件已正确下载。
我也想通过应用程序本身提供数据。我可以把它放在我的应用程序的资产文件夹中吗?在运行时访问资产文件夹中文件的最佳方法是什么。