+// Copyright 2011 Google Inc. All Rights Reserved.\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+// http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+\r
package com.hughes.android.dictionary;\r
\r
+import java.io.File;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+import java.net.URL;\r
+import java.net.URLConnection;\r
import java.util.concurrent.Executor;\r
import java.util.concurrent.Executors;\r
+import java.util.concurrent.atomic.AtomicBoolean;\r
+import java.util.zip.ZipEntry;\r
+import java.util.zip.ZipFile;\r
\r
import android.app.Activity;\r
import android.content.Intent;\r
import android.os.Bundle;\r
import android.os.Handler;\r
import android.util.Log;\r
-import android.view.View;\r
import android.widget.ProgressBar;\r
import android.widget.TextView;\r
\r
\r
String source;\r
String dest;\r
- \r
+ long bytesProcessed = 0;\r
+ long contentLength = -1;\r
+\r
private final Executor downloadExecutor = Executors.newSingleThreadExecutor();\r
private final Handler uiHandler = new Handler();\r
\r
+ final AtomicBoolean stop = new AtomicBoolean(false);\r
+\r
/** Called when the activity is first created. */\r
@Override\r
public void onCreate(final Bundle savedInstanceState) {\r
+ //((DictionaryApplication)getApplication()).applyTheme(this);\r
+\r
super.onCreate(savedInstanceState);\r
final Intent intent = getIntent();\r
source = intent.getStringExtra(SOURCE);\r
if (source == null || dest == null) {\r
throw new RuntimeException("null source or dest.");\r
}\r
- setContentView(R.layout.download);\r
- \r
+ setContentView(R.layout.download_activity);\r
+\r
final TextView sourceTextView = (TextView) findViewById(R.id.source);\r
sourceTextView.setText(source);\r
- \r
+\r
final TextView destTextView = (TextView) findViewById(R.id.dest);\r
destTextView.setText(dest);\r
\r
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.downloadProgressBar);\r
progressBar.setIndeterminate(false);\r
progressBar.setMax(100);\r
+ \r
+ bytesProcessed = 0;\r
+ contentLength = 100;\r
+ setDownloadStatus(getString(R.string.openingConnection));\r
\r
final Runnable runnable = new Runnable() {\r
public void run() {\r
- \r
- for (int i = 0; i < 100; ++i) {\r
+\r
+ try {\r
+ final File destFile = new File(dest);\r
+ destFile.getParentFile().mkdirs();\r
+\r
+ final File destTmpFile = File.createTempFile("dictionaryDownload", "tmp", destFile\r
+ .getParentFile());\r
+ destTmpFile.deleteOnExit();\r
+\r
+ final URL uri = new URL(source);\r
+ final URLConnection connection = uri.openConnection();\r
+ contentLength = connection.getContentLength();\r
+ final InputStream in = connection.getInputStream();\r
+ if (in == null) {\r
+ throw new IOException("Unable to open InputStream from source: " + source);\r
+ }\r
+ final FileOutputStream out = new FileOutputStream(destTmpFile); \r
+ int bytesRead = copyStream(in, out, R.string.downloading);\r
+ \r
+ if (bytesRead == -1 && !stop.get()) {\r
+ destFile.delete();\r
+ destTmpFile.renameTo(destFile);\r
+ } else {\r
+ Log.d("THAD", "Stopped downloading file.");\r
+ }\r
+ \r
+ if (dest.toLowerCase().endsWith(".zip")) {\r
+ final ZipFile zipFile = new ZipFile(destFile);\r
+ final File destUnzipped = new File(dest.substring(0, dest.length() - 4));\r
+ final ZipEntry zipEntry = zipFile.getEntry(destUnzipped.getName());\r
+ if (zipEntry != null) {\r
+ destUnzipped.delete();\r
+ Log.d("THAD", "Unzipping entry: " + zipEntry.getName() + " to " + destUnzipped);\r
+ final InputStream zipIn = zipFile.getInputStream(zipEntry);\r
+ final OutputStream zipOut = new FileOutputStream(destUnzipped);\r
+ contentLength = zipEntry.getSize();\r
+ bytesRead = copyStream(zipIn, zipOut, R.string.unzipping);\r
+ }\r
+ }\r
+ \r
+ setDownloadStatus(String.format(getString(R.string.downloadFinished),\r
+ bytesProcessed));\r
\r
- final int progress = i;\r
+ // If all went well, we can exit this activity.\r
uiHandler.post(new Runnable() {\r
+ @Override\r
public void run() {\r
- Log.d("THAD", "Setting progress: " + progress);\r
- progressBar.setProgress(progress);\r
+ finish();\r
}\r
});\r
\r
- try {\r
- Thread.sleep(100);\r
- } catch (InterruptedException e) {\r
- e.printStackTrace();\r
- }\r
+ } catch (IOException e) {\r
+ Log.e("THAD", "Error downloading file", e);\r
+ setDownloadStatus(String.format(getString(R.string.errorDownloadingFile), e.getLocalizedMessage()));\r
}\r
- \r
- final TextView downloadComplete = (TextView) findViewById(R.id.downloadComplete);\r
- uiHandler.post(new Runnable() {\r
- public void run() {\r
- progressBar.setProgress(100);\r
- downloadComplete.setVisibility(View.VISIBLE);\r
+ }\r
+\r
+ private int copyStream(final InputStream in, final OutputStream out, final int messageId)\r
+ throws IOException {\r
+ bytesProcessed = 0;\r
+ int bytesRead;\r
+ final byte[] bytes = new byte[1024 * 16];\r
+ int count = 0;\r
+ while ((bytesRead = in.read(bytes)) != -1 && !stop.get()) {\r
+ out.write(bytes, 0, bytesRead);\r
+ bytesProcessed += bytesRead;\r
+ if (count++ % 20 == 0) {\r
+ setDownloadStatus(getString(messageId, bytesProcessed, contentLength));\r
}\r
- });\r
- \r
- }};\r
+ }\r
+ in.close();\r
+ out.close();\r
+ return bytesRead;\r
+ }\r
+ };\r
+\r
downloadExecutor.execute(runnable);\r
- \r
}\r
- \r
+\r
+ @Override\r
+ protected void onStop() {\r
+ stop.set(true);\r
+ super.onStop();\r
+ }\r
+\r
+ private void setDownloadStatus(final String status) {\r
+ uiHandler.post(new Runnable() {\r
+ public void run() {\r
+ final ProgressBar progressBar = (ProgressBar) findViewById(R.id.downloadProgressBar);\r
+ if (contentLength > 0) {\r
+ progressBar.setProgress((int) (bytesProcessed * 100 / contentLength));\r
+ }\r
+ \r
+ final TextView downloadStatus = (TextView) findViewById(R.id.downloadStatus);\r
+ downloadStatus.setText(status);\r
+ }\r
+ });\r
+ }\r
+\r
}\r