いくつかのオンライン チュートリアルに従い、このコードを作成して、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 を返すため、コンテンツの長さを使用してファイル全体がダウンロードされたかどうかを確認できません。ファイルはオフラインのベクター マップであり、オフライン マップを表示するために必要です。破損したファイルにアクセスしようとすると、実行時例外が発生します。ファイルが正しくダウンロードされたことを確認する方法はありますか。
また、アプリ自体でデータを提供したいと思います。これをアプリのアセット フォルダに入れることはできますか。実行時にアセット フォルダー内のファイルにアクセスする最善の方法は何ですか。