]> gitweb.fperrin.net Git - Dictionary.git/blob - src/com/hughes/android/dictionary/DownloadActivity.java
go
[Dictionary.git] / src / com / hughes / android / dictionary / DownloadActivity.java
1 package com.hughes.android.dictionary;\r
2 \r
3 import java.io.File;\r
4 import java.io.FileOutputStream;\r
5 import java.io.IOException;\r
6 import java.io.InputStream;\r
7 import java.io.OutputStream;\r
8 import java.net.URL;\r
9 import java.net.URLConnection;\r
10 import java.util.concurrent.Executor;\r
11 import java.util.concurrent.Executors;\r
12 import java.util.concurrent.atomic.AtomicBoolean;\r
13 import java.util.zip.ZipEntry;\r
14 import java.util.zip.ZipFile;\r
15 \r
16 import android.app.Activity;\r
17 import android.content.Intent;\r
18 import android.os.Bundle;\r
19 import android.os.Handler;\r
20 import android.util.Log;\r
21 import android.widget.ProgressBar;\r
22 import android.widget.TextView;\r
23 \r
24 public class DownloadActivity extends Activity {\r
25 \r
26   public static final String SOURCE = "source";\r
27   public static final String DEST = "dest";\r
28 \r
29   String source;\r
30   String dest;\r
31   long bytesProcessed = 0;\r
32   long contentLength = -1;\r
33 \r
34   private final Executor downloadExecutor = Executors.newSingleThreadExecutor();\r
35   private final Handler uiHandler = new Handler();\r
36 \r
37   final AtomicBoolean stop = new AtomicBoolean(false);\r
38 \r
39   /** Called when the activity is first created. */\r
40   @Override\r
41   public void onCreate(final Bundle savedInstanceState) {\r
42     ((DictionaryApplication)getApplication()).applyTheme(this);\r
43 \r
44     super.onCreate(savedInstanceState);\r
45     final Intent intent = getIntent();\r
46     source = intent.getStringExtra(SOURCE);\r
47     dest = intent.getStringExtra(DEST);\r
48     if (source == null || dest == null) {\r
49       throw new RuntimeException("null source or dest.");\r
50     }\r
51     setContentView(R.layout.download_activity);\r
52 \r
53     final TextView sourceTextView = (TextView) findViewById(R.id.source);\r
54     sourceTextView.setText(source);\r
55 \r
56     final TextView destTextView = (TextView) findViewById(R.id.dest);\r
57     destTextView.setText(dest);\r
58 \r
59     final ProgressBar progressBar = (ProgressBar) findViewById(R.id.downloadProgressBar);\r
60     progressBar.setIndeterminate(false);\r
61     progressBar.setMax(100);\r
62     \r
63     bytesProcessed = 0;\r
64     contentLength = 100;\r
65     setDownloadStatus(getString(R.string.openingConnection));\r
66 \r
67     final Runnable runnable = new Runnable() {\r
68       public void run() {\r
69 \r
70         try {\r
71           final File destFile = new File(dest);\r
72           destFile.getParentFile().mkdirs();\r
73 \r
74           final File destTmpFile = File.createTempFile("dictionaryDownload", "tmp", destFile\r
75               .getParentFile());\r
76           destTmpFile.deleteOnExit();\r
77 \r
78           final URL uri = new URL(source);\r
79           final URLConnection connection = uri.openConnection();\r
80           contentLength = connection.getContentLength();\r
81           final InputStream in = connection.getInputStream();\r
82           if (in == null) {\r
83             throw new IOException("Unable to open InputStream from source: " + source);\r
84           }\r
85           final FileOutputStream out = new FileOutputStream(destTmpFile); \r
86           int bytesRead = copyStream(in, out, R.string.downloading);\r
87           \r
88           if (bytesRead == -1 && !stop.get()) {\r
89             destFile.delete();\r
90             destTmpFile.renameTo(destFile);\r
91           } else {\r
92            Log.d("THAD", "Stopped downloading file.");\r
93           }\r
94           \r
95           if (dest.toLowerCase().endsWith(".zip")) {\r
96             final ZipFile zipFile = new ZipFile(destFile);\r
97             final File destUnzipped = new File(dest.substring(0, dest.length() - 4));\r
98             final ZipEntry zipEntry = zipFile.getEntry(destUnzipped.getName());\r
99             if (zipEntry != null) {\r
100               destUnzipped.delete();\r
101               Log.d("THAD", "Unzipping entry: " + zipEntry.getName() + " to " + destUnzipped);\r
102               final InputStream zipIn = zipFile.getInputStream(zipEntry);\r
103               final OutputStream zipOut = new FileOutputStream(destUnzipped);\r
104               contentLength = zipEntry.getSize();\r
105               bytesRead = copyStream(zipIn, zipOut, R.string.unzipping);\r
106             }\r
107           }\r
108           \r
109           setDownloadStatus(String.format(getString(R.string.downloadFinished),\r
110               bytesProcessed));\r
111         } catch (IOException e) {\r
112           Log.e("THAD", "Error downloading file", e);\r
113           setDownloadStatus(String.format(getString(R.string.errorDownloadingFile), e.getLocalizedMessage()));\r
114         }\r
115       }\r
116 \r
117       private int copyStream(final InputStream in, final OutputStream out, final int messageId)\r
118           throws IOException {\r
119         bytesProcessed = 0;\r
120         int bytesRead;\r
121         final byte[] bytes = new byte[1024 * 16];\r
122         int count = 0;\r
123         while ((bytesRead = in.read(bytes)) != -1 && !stop.get()) {\r
124           out.write(bytes, 0, bytesRead);\r
125           bytesProcessed += bytesRead;\r
126           if (count++ % 20 == 0) {\r
127             setDownloadStatus(getString(messageId, bytesProcessed, contentLength));\r
128           }\r
129         }\r
130         in.close();\r
131         out.close();\r
132         return bytesRead;\r
133       }\r
134     };\r
135 \r
136     downloadExecutor.execute(runnable);\r
137   }\r
138 \r
139   @Override\r
140   protected void onStop() {\r
141     stop.set(true);\r
142     super.onStop();\r
143   }\r
144 \r
145   private void setDownloadStatus(final String status) {\r
146     uiHandler.post(new Runnable() {\r
147       public void run() {\r
148         final ProgressBar progressBar = (ProgressBar) findViewById(R.id.downloadProgressBar);\r
149         if (contentLength > 0) {\r
150           progressBar.setProgress((int) (bytesProcessed * 100 / contentLength));\r
151         }\r
152         \r
153         final TextView downloadStatus = (TextView) findViewById(R.id.downloadStatus);\r
154         downloadStatus.setText(status);\r
155       }\r
156     });\r
157   }\r
158 \r
159 }\r