18
18
import java .awt .event .ActionListener ;
19
19
import java .beans .PropertyChangeEvent ;
20
20
import java .beans .PropertyChangeListener ;
21
+ import java .io .File ;
22
+ import java .io .FileOutputStream ;
21
23
import java .io .IOException ;
24
+ import java .io .InputStream ;
22
25
import java .net .URL ;
26
+ import java .net .URLConnection ;
23
27
24
28
public class SDKDownloader extends JFrame implements PropertyChangeListener {
25
29
26
- private static final String URL_SDK_TOOLS_WINDOWS = "http://dl.google.com/android/android-sdk_r23-windows.zip" ;
27
- private static final String URL_SDK_TOOLS_MACOS = "http://dl.google.com/android/android-sdk_r23-macosx.zip" ;
28
- private static final String URL_SDK_TOOLS_LINUX = "http://dl.google.com/android/android-sdk_r23-linux.tgz" ;
29
-
30
30
private static final String URL_REPOSITORY = "https://dl-ssl.google.com/android/repository/repository-10.xml" ;
31
31
private static final String URL_REPOSITORY_FOLDER = "http://dl-ssl.google.com/android/repository/" ;
32
32
33
33
private static final String PLATFORM_API_LEVEL = "10" ;
34
34
35
+ public static final String PROPERTY_CHANGE_EVENT_TOTAL = "total" ;
36
+ private static final String PROPERTY_CHANGE_EVENT_DOWNLOADED = "downloaded" ;
37
+
38
+ JProgressBar progressBar ;
39
+ JLabel downloadedTextArea ;
40
+
41
+ private int totalSize = 0 ;
42
+
35
43
class SDKUrlHolder {
36
- public String platformToolsUrl , buildToolsUrl , platformUrl ;
44
+ public String platformToolsUrl , buildToolsUrl , platformUrl , toolsUrl ;
45
+ public String platformToolsFilename , buildToolsFilename , platformFilename , toolsFilename ;
46
+ public int totalSize = 0 ;
37
47
}
38
48
39
49
class SDKDownloadTask extends SwingWorker {
40
50
51
+ private int downloadedSize = 0 , totalSize = 0 ;
52
+ private int BUFFER_SIZE = 4096 ;
53
+
41
54
@ Override
42
55
protected Object doInBackground () throws Exception {
43
56
String hostOs = getOsString ();
57
+ File modeFolder = new File (Base .getSketchbookModesFolder () + "/AndroidMode" );
58
+
59
+ // creating sdk root folder
60
+ File sdkFolder = new File (modeFolder , "sdk" );
61
+ if (!sdkFolder .exists ()) sdkFolder .mkdir ();
62
+
63
+ // creating temp folder for downloaded zip packages
64
+ File tempFolder = new File (modeFolder , "temp" );
65
+ if (!tempFolder .exists ()) tempFolder .mkdir ();
66
+
67
+ // creating sdk folders
68
+ File toolsFolder = new File (sdkFolder , "tools" ); toolsFolder .mkdir ();
69
+ File platformToolsFolder = new File (sdkFolder , "platform-tools" ); platformToolsFolder .mkdir ();
70
+ File buildToolsFolder = new File (sdkFolder , "build-tools" ); buildToolsFolder .mkdir ();
71
+ File platformsFoolder = new File (sdkFolder , "platforms" ); platformsFoolder .mkdir ();
72
+ File platformFolder = new File (platformsFoolder , "android-10" ); platformFolder .mkdir ();
73
+
44
74
try {
45
75
SDKUrlHolder downloadUrls = getDownloadUrls (URL_REPOSITORY , hostOs );
76
+ firePropertyChange (PROPERTY_CHANGE_EVENT_TOTAL , 0 , downloadUrls .totalSize );
77
+ totalSize = downloadUrls .totalSize ;
78
+
79
+ // tools
80
+ File downloadedTools = new File (tempFolder , downloadUrls .toolsFilename );
81
+ downloadFile (downloadUrls .toolsUrl , downloadedTools );
82
+
83
+ // platform-tools
84
+ File downloadedPlatformTools = new File (tempFolder , downloadUrls .platformToolsFilename );
85
+ downloadFile (downloadUrls .platformToolsUrl , downloadedPlatformTools );
86
+
87
+ // build-tools
88
+ File downloadedBuildTools = new File (tempFolder , downloadUrls .buildToolsFilename );
89
+ downloadFile (downloadUrls .buildToolsUrl , downloadedBuildTools );
90
+
91
+ // platform
92
+ File downloadedPlatform = new File (tempFolder , downloadUrls .platformFilename );
93
+ downloadFile (downloadUrls .platformUrl , downloadedPlatform );
46
94
} catch (ParserConfigurationException e ) {
47
- // TODO Handle exceptions here somehow (ie show error message)
95
+ // TODO Handle exceptions here somehow (ie show error message) and handle at least mkdir() results (above)
48
96
e .printStackTrace ();
49
97
} catch (IOException e ) {
50
98
e .printStackTrace ();
@@ -59,6 +107,27 @@ protected void done() {
59
107
super .done ();
60
108
}
61
109
110
+ private void downloadFile (String urlString , File saveTo ) throws IOException {
111
+ URL url = new URL (urlString );
112
+ URLConnection conn = url .openConnection ();
113
+
114
+ InputStream inputStream = conn .getInputStream ();
115
+ FileOutputStream outputStream = new FileOutputStream (saveTo );
116
+
117
+ byte [] b = new byte [BUFFER_SIZE ];
118
+ int count ;
119
+ while ((count = inputStream .read (b )) >= 0 ) {
120
+ outputStream .write (b , 0 , count );
121
+ downloadedSize += count ;
122
+
123
+ firePropertyChange (PROPERTY_CHANGE_EVENT_DOWNLOADED , 0 , downloadedSize );
124
+ }
125
+ outputStream .flush (); outputStream .close (); inputStream .close ();
126
+
127
+ inputStream .close ();
128
+ outputStream .close ();
129
+ }
130
+
62
131
private String getOsString () {
63
132
if (Base .isWindows ()) {
64
133
return "windows" ;
@@ -84,6 +153,8 @@ private SDKUrlHolder getDownloadUrls(String repositoryUrl, String requiredHostOs
84
153
Node archiveListItem = ((Element ) platform ).getElementsByTagName ("sdk:archives" ).item (0 );
85
154
Node archiveItem = ((Element ) archiveListItem ).getElementsByTagName ("sdk:archive" ).item (0 );
86
155
urlHolder .platformUrl = ((Element ) archiveItem ).getElementsByTagName ("sdk:url" ).item (0 ).getTextContent ();
156
+ urlHolder .platformFilename = urlHolder .platformUrl .split ("/" )[urlHolder .platformUrl .split ("/" ).length -1 ];
157
+ urlHolder .totalSize += Integer .parseInt (((Element ) archiveItem ).getElementsByTagName ("sdk:size" ).item (0 ).getTextContent ());
87
158
}
88
159
}
89
160
@@ -95,9 +166,9 @@ private SDKUrlHolder getDownloadUrls(String repositoryUrl, String requiredHostOs
95
166
Node archive = archiveList .item (i );
96
167
String hostOs = ((Element ) archive ).getElementsByTagName ("sdk:host-os" ).item (0 ).getTextContent ();
97
168
if (hostOs .equals (requiredHostOs )) {
98
- String platformToolsUrl = (((Element ) archive ).getElementsByTagName ("sdk:url" ).item (0 ).getTextContent ());
99
- if (! platformToolsUrl . startsWith ( "http" )) platformToolsUrl = URL_REPOSITORY_FOLDER + platformToolsUrl ;
100
- urlHolder .platformToolsUrl = platformToolsUrl ;
169
+ urlHolder . platformToolsFilename = (((Element ) archive ).getElementsByTagName ("sdk:url" ).item (0 ).getTextContent ());
170
+ urlHolder . platformToolsUrl = URL_REPOSITORY_FOLDER + urlHolder . platformToolsFilename ;
171
+ urlHolder .totalSize += Integer . parseInt ((( Element ) archive ). getElementsByTagName ( "sdk:size" ). item ( 0 ). getTextContent ()) ;
101
172
break ;
102
173
}
103
174
}
@@ -110,9 +181,24 @@ private SDKUrlHolder getDownloadUrls(String repositoryUrl, String requiredHostOs
110
181
Node archive = archiveList .item (i );
111
182
String hostOs = ((Element ) archive ).getElementsByTagName ("sdk:host-os" ).item (0 ).getTextContent ();
112
183
if (hostOs .equals (requiredHostOs )) {
113
- String buildToolsUrl = (((Element ) archive ).getElementsByTagName ("sdk:url" ).item (0 ).getTextContent ());
114
- if (!buildToolsUrl .startsWith ("http" )) buildToolsUrl = URL_REPOSITORY_FOLDER + buildToolsUrl ;
115
- urlHolder .buildToolsUrl = buildToolsUrl ;
184
+ urlHolder .buildToolsFilename = (((Element ) archive ).getElementsByTagName ("sdk:url" ).item (0 ).getTextContent ());
185
+ urlHolder .buildToolsUrl = URL_REPOSITORY_FOLDER + urlHolder .buildToolsFilename ;
186
+ urlHolder .totalSize += Integer .parseInt (((Element ) archive ).getElementsByTagName ("sdk:size" ).item (0 ).getTextContent ());
187
+ break ;
188
+ }
189
+ }
190
+
191
+ // tools
192
+ Node toolsItem = doc .getElementsByTagName ("sdk:tool" ).item (0 );
193
+ archiveListItem = ((Element ) toolsItem ).getElementsByTagName ("sdk:archives" ).item (0 );
194
+ archiveList = ((Element ) archiveListItem ).getElementsByTagName ("sdk:archive" );
195
+ for (int i = 0 ; i < archiveList .getLength (); i ++) {
196
+ Node archive = archiveList .item (i );
197
+ String hostOs = ((Element ) archive ).getElementsByTagName ("sdk:host-os" ).item (0 ).getTextContent ();
198
+ if (hostOs .equals (requiredHostOs )) {
199
+ urlHolder .toolsFilename = (((Element ) archive ).getElementsByTagName ("sdk:url" ).item (0 ).getTextContent ());
200
+ urlHolder .toolsUrl = URL_REPOSITORY_FOLDER + urlHolder .toolsFilename ;
201
+ urlHolder .totalSize += Integer .parseInt (((Element ) archive ).getElementsByTagName ("sdk:size" ).item (0 ).getTextContent ());
116
202
break ;
117
203
}
118
204
}
@@ -123,7 +209,24 @@ private SDKUrlHolder getDownloadUrls(String repositoryUrl, String requiredHostOs
123
209
124
210
@ Override
125
211
public void propertyChange (PropertyChangeEvent evt ) {
212
+ if (evt .getPropertyName ().equals (PROPERTY_CHANGE_EVENT_TOTAL )) {
213
+ progressBar .setIndeterminate (false );
214
+ totalSize = (Integer ) evt .getNewValue ();
215
+ progressBar .setMaximum (totalSize );
216
+ } else if (evt .getPropertyName ().equals (PROPERTY_CHANGE_EVENT_DOWNLOADED )) {
217
+ downloadedTextArea .setText (humanReadableByteCount ((Integer ) evt .getNewValue (), true )
218
+ + " / " + humanReadableByteCount (totalSize , true ));
219
+ progressBar .setValue ((Integer ) evt .getNewValue ());
220
+ }
221
+ }
126
222
223
+ // http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java
224
+ public static String humanReadableByteCount (long bytes , boolean si ) {
225
+ int unit = si ? 1000 : 1024 ;
226
+ if (bytes < unit ) return bytes + " B" ;
227
+ int exp = (int ) (Math .log (bytes ) / Math .log (unit ));
228
+ String pre = (si ? "kMGTPE" : "KMGTPE" ).charAt (exp -1 ) + (si ? "" : "i" );
229
+ return String .format ("%.1f %sB" , bytes / Math .pow (unit , exp ), pre );
127
230
}
128
231
129
232
public SDKDownloader () {
@@ -152,12 +255,17 @@ private void createLayout() {
152
255
textarea .setAlignmentX (LEFT_ALIGNMENT );
153
256
pain .add (textarea );
154
257
155
- JProgressBar progressBar = new JProgressBar (0 , 100 );
258
+ progressBar = new JProgressBar (0 , 100 );
156
259
progressBar .setValue (0 );
157
260
progressBar .setStringPainted (true );
158
261
progressBar .setIndeterminate (true );
262
+ progressBar .setBorder (new EmptyBorder (10 , 10 , 10 , 10 ) );
159
263
pain .add (progressBar );
160
264
265
+ downloadedTextArea = new JLabel ("" );
266
+ downloadedTextArea .setAlignmentX (LEFT_ALIGNMENT );
267
+ pain .add (downloadedTextArea );
268
+
161
269
// buttons
162
270
JPanel buttons = new JPanel ();
163
271
// buttons.setPreferredSize(new Dimension(400, 35));
@@ -176,7 +284,7 @@ private void createLayout() {
176
284
// Box buttons = Box.createHorizontalBox();
177
285
buttons .setAlignmentX (LEFT_ALIGNMENT );
178
286
JButton cancelButton = new JButton ("Cancel download" );
179
- Dimension dim = new Dimension (Preferences .BUTTON_WIDTH ,
287
+ Dimension dim = new Dimension (Preferences .BUTTON_WIDTH * 2 ,
180
288
cancelButton .getPreferredSize ().height );
181
289
182
290
cancelButton .setPreferredSize (dim );
0 commit comments