1 // Copyright 2011 Google Inc. All Rights Reserved.
\r
3 // Licensed under the Apache License, Version 2.0 (the "License");
\r
4 // you may not use this file except in compliance with the License.
\r
5 // You may obtain a copy of the License at
\r
7 // http://www.apache.org/licenses/LICENSE-2.0
\r
9 // Unless required by applicable law or agreed to in writing, software
\r
10 // distributed under the License is distributed on an "AS IS" BASIS,
\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
12 // See the License for the specific language governing permissions and
\r
13 // limitations under the License.
\r
15 package com.hughes.android.dictionary;
\r
17 import android.app.Activity;
\r
18 import android.content.Intent;
\r
19 import android.os.Bundle;
\r
20 import android.os.Handler;
\r
21 import android.util.Log;
\r
22 import android.widget.ProgressBar;
\r
23 import android.widget.TextView;
\r
25 import java.io.File;
\r
26 import java.io.FileOutputStream;
\r
27 import java.io.IOException;
\r
28 import java.io.InputStream;
\r
29 import java.io.OutputStream;
\r
30 import java.net.URL;
\r
31 import java.net.URLConnection;
\r
32 import java.util.concurrent.Executor;
\r
33 import java.util.concurrent.Executors;
\r
34 import java.util.concurrent.atomic.AtomicBoolean;
\r
35 import java.util.zip.ZipEntry;
\r
36 import java.util.zip.ZipFile;
\r
38 public class DownloadActivity extends Activity {
\r
40 public static final String SOURCE = "source";
\r
41 public static final String DEST = "dest";
\r
42 public static final String MESSAGE = "message";
\r
47 long bytesProcessed = 0;
\r
48 long contentLength = -1;
\r
50 private final Executor downloadExecutor = Executors.newSingleThreadExecutor();
\r
51 private final Handler uiHandler = new Handler();
\r
53 final AtomicBoolean stop = new AtomicBoolean(false);
\r
55 public static Intent getLaunchIntent(final String source, final String dest, final String message) {
\r
56 final Intent intent = new Intent();
\r
57 intent.setClassName(DownloadActivity.class.getPackage().getName(), DownloadActivity.class.getName());
\r
58 intent.putExtra(SOURCE, source);
\r
59 intent.putExtra(DEST, dest);
\r
60 intent.putExtra(MESSAGE, message);
\r
64 /** Called when the activity is first created. */
\r
66 public void onCreate(final Bundle savedInstanceState) {
\r
67 setTheme(((DictionaryApplication)getApplication()).getSelectedTheme().themeId);
\r
69 super.onCreate(savedInstanceState);
\r
70 final Intent intent = getIntent();
\r
71 source = intent.getStringExtra(SOURCE);
\r
72 dest = intent.getStringExtra(DEST);
\r
73 message = intent.getStringExtra(MESSAGE);
\r
74 if (source == null || dest == null) {
\r
75 throw new RuntimeException("null source or dest.");
\r
77 setContentView(R.layout.download_activity);
\r
79 final TextView sourceTextView = (TextView) findViewById(R.id.source);
\r
80 sourceTextView.setText(source);
\r
82 final TextView destTextView = (TextView) findViewById(R.id.dest);
\r
83 destTextView.setText(dest);
\r
85 final TextView messageTextView = (TextView) findViewById(R.id.downloadMessage);
\r
86 messageTextView.setText(message);
\r
88 final ProgressBar progressBar = (ProgressBar) findViewById(R.id.downloadProgressBar);
\r
89 progressBar.setIndeterminate(false);
\r
90 progressBar.setMax(100);
\r
93 contentLength = 100;
\r
94 setDownloadStatus(getString(R.string.openingConnection));
\r
96 final Runnable runnable = new Runnable() {
\r
100 final File destFile = new File(dest);
\r
101 if (destFile.getAbsoluteFile().getParent() != null) {
\r
102 destFile.getAbsoluteFile().getParentFile().mkdirs();
\r
105 final File destTmpFile = File.createTempFile("dictionaryDownload", "tmp", destFile
\r
107 destTmpFile.deleteOnExit();
\r
109 final URL uri = new URL(source);
\r
110 final URLConnection connection = uri.openConnection();
\r
111 contentLength = connection.getContentLength();
\r
112 final InputStream in = connection.getInputStream();
\r
114 throw new IOException("Unable to open InputStream from source: " + source);
\r
116 final FileOutputStream out = new FileOutputStream(destTmpFile);
\r
117 int bytesRead = copyStream(in, out, R.string.downloading);
\r
119 if (bytesRead == -1 && !stop.get()) {
\r
121 destTmpFile.renameTo(destFile);
\r
123 Log.d("THAD", "Stopped downloading file.");
\r
126 if (dest.toLowerCase().endsWith(".zip")) {
\r
127 final ZipFile zipFile = new ZipFile(destFile);
\r
128 final File destUnzipped = new File(dest.substring(0, dest.length() - 4));
\r
129 final ZipEntry zipEntry = zipFile.getEntry(destUnzipped.getName());
\r
130 if (zipEntry != null) {
\r
131 destUnzipped.delete();
\r
132 Log.d("THAD", "Unzipping entry: " + zipEntry.getName() + " to " + destUnzipped);
\r
133 final InputStream zipIn = zipFile.getInputStream(zipEntry);
\r
134 final OutputStream zipOut = new FileOutputStream(destUnzipped);
\r
135 contentLength = zipEntry.getSize();
\r
136 bytesRead = copyStream(zipIn, zipOut, R.string.unzipping);
\r
141 setDownloadStatus(String.format(getString(R.string.downloadFinished),
\r
144 // If all went well, we can exit this activity.
\r
145 uiHandler.post(new Runnable() {
\r
147 public void run() {
\r
152 } catch (IOException e) {
\r
153 Log.e("THAD", "Error downloading file", e);
\r
154 setDownloadStatus(String.format(getString(R.string.errorDownloadingFile), e.getLocalizedMessage()));
\r
158 private int copyStream(final InputStream in, final OutputStream out, final int messageId)
\r
159 throws IOException {
\r
160 bytesProcessed = 0;
\r
162 final byte[] bytes = new byte[1024 * 16];
\r
164 while ((bytesRead = in.read(bytes)) != -1 && !stop.get()) {
\r
165 out.write(bytes, 0, bytesRead);
\r
166 bytesProcessed += bytesRead;
\r
167 if (count++ % 20 == 0) {
\r
168 setDownloadStatus(getString(messageId, bytesProcessed, contentLength));
\r
177 downloadExecutor.execute(runnable);
\r
181 protected void onStop() {
\r
186 private void setDownloadStatus(final String status) {
\r
187 uiHandler.post(new Runnable() {
\r
188 public void run() {
\r
189 final ProgressBar progressBar = (ProgressBar) findViewById(R.id.downloadProgressBar);
\r
190 if (contentLength > 0) {
\r
191 progressBar.setProgress((int) (bytesProcessed * 100 / contentLength));
\r
194 final TextView downloadStatus = (TextView) findViewById(R.id.downloadStatus);
\r
195 downloadStatus.setText(status);
\r