Fix:Android:activate a newly downloaded map (works perfect now)
[profile/ivi/navit.git] / navit / navit / android / src / org / navitproject / navit / NavitMapDownloader.java
1 /**\r
2  * Navit, a modular navigation system.\r
3  * Copyright (C) 2005-2008 Navit Team\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * version 2 as published by the Free Software Foundation.\r
8  *\r
9  * This program is distributed in the hope that it will be useful,\r
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12  * GNU General Public License for more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License\r
15  * along with this program; if not, write to the\r
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\r
17  * Boston, MA  02110-1301, USA.\r
18  */\r
19 \r
20 package org.navitproject.navit;\r
21 \r
22 import java.io.BufferedInputStream;\r
23 import java.io.BufferedOutputStream;\r
24 import java.io.File;\r
25 import java.io.FileOutputStream;\r
26 import java.io.IOException;\r
27 import java.io.InputStream;\r
28 import java.net.HttpURLConnection;\r
29 import java.net.URL;\r
30 import java.text.DecimalFormat;\r
31 import java.text.NumberFormat;\r
32 \r
33 import android.os.Bundle;\r
34 import android.os.Handler;\r
35 import android.os.Message;\r
36 import android.util.Log;\r
37 \r
38 public class NavitMapDownloader\r
39 {\r
40         public static class osm_map_values\r
41         {\r
42                 String  lon1;\r
43                 String  lat1;\r
44                 String  lon2;\r
45                 String  lat2;\r
46                 String  map_name                        = "";\r
47                 int             est_size_bytes  = 0;\r
48 \r
49                 public osm_map_values(String mapname, String lon_1, String lat_1, String lon_2, String lat_2,\r
50                                 int bytes_est)\r
51                 {\r
52                         this.map_name = mapname;\r
53                         this.lon1 = lon_1;\r
54                         this.lat1 = lat_1;\r
55                         this.lon2 = lon_2;\r
56                         this.lat2 = lat_2;\r
57                         this.est_size_bytes = bytes_est;\r
58                 }\r
59         }\r
60 \r
61         /*\r
62          * coords for predefined maps:\r
63          * \r
64          * <a onclick='predefined(5.18,46.84,15.47,55.64)'>Germany</a>\r
65          * <a onclick='predefined(2.08,48.87,7.78,54.52)'>BeNeLux</a>\r
66          * <a onclick='predefined(9.4,46.32,17.21,49.1)'>Austria</a> 209 MBytes = 219152384 Bytes\r
67          */\r
68         //\r
69         // define the maps here\r
70         //                                                          name     , lon1 , lat1   , lon2   , lat2, est. size in bytes\r
71         public static osm_map_values            austria                                                         = new osm_map_values("Austria",\r
72                                                                                                                                                                                                 "9.4", "46.32", "17.21",\r
73                                                                                                                                                                                                 "49.1", 222000000);\r
74         public static osm_map_values            benelux                                                         = new osm_map_values("BeNeLux",\r
75                                                                                                                                                                                                 "2.08", "48.87", "7.78",\r
76                                                                                                                                                                                                 "54.52", 530000000);\r
77         public static osm_map_values            germany                                                         = new osm_map_values("Germany",\r
78                                                                                                                                                                                                 "5.18", "46.84", "15.47",\r
79                                                                                                                                                                                                 "55.64", 943000000);\r
80         public static osm_map_values[]  OSM_MAPS                                                                = new osm_map_values[]{\r
81                         NavitMapDownloader.austria, NavitMapDownloader.germany, NavitMapDownloader.benelux};\r
82         public static String[]                          OSM_MAP_NAME_LIST                                       = new String[]{\r
83                         NavitMapDownloader.OSM_MAPS[0].map_name, NavitMapDownloader.OSM_MAPS[1].map_name,\r
84                         NavitMapDownloader.OSM_MAPS[2].map_name                                         };\r
85 \r
86         public Boolean                                                  stop_me                                                         = false;\r
87         static final int                                                SOCKET_CONNECT_TIMEOUT                  = 6000;\r
88         static final int                                                SOCKET_READ_TIMEOUT                             = 6000;\r
89         static final int                                                MAP_WRITE_FILE_BUFFER                   = 1024 * 64;\r
90         static final int                                                MAP_WRITE_MEM_BUFFER                            = 1024 * 64;\r
91         static final int                                                MAP_READ_FILE_BUFFER                            = 1024 * 64;\r
92         static final int                                                UPDATE_PROGRESS_EVERY_CYCLE     = 2;\r
93 \r
94 \r
95         public class ProgressThread extends Thread\r
96         {\r
97                 Handler                 mHandler;\r
98                 osm_map_values  map_values;\r
99 \r
100                 ProgressThread(Handler h, osm_map_values map_values)\r
101                 {\r
102                         this.mHandler = h;\r
103                         this.map_values = map_values;\r
104                 }\r
105 \r
106                 public void run()\r
107                 {\r
108                         stop_me = false;\r
109                         int exit_code = download_osm_map(mHandler, map_values);\r
110 \r
111                         // ok, remove dialog\r
112                         Message msg = mHandler.obtainMessage();\r
113                         Bundle b = new Bundle();\r
114                         msg.what = 0;\r
115                         b.putInt("dialog_num", Navit.MAPDOWNLOAD_DIALOG);\r
116                         b.putInt("exit_code", exit_code);\r
117                         msg.setData(b);\r
118                         mHandler.sendMessage(msg);\r
119                 }\r
120 \r
121                 public void stop_thread()\r
122                 {\r
123                         stop_me = true;\r
124                         Log.d("NavitMapDownloader", "stop_me -> true");\r
125                 }\r
126         }\r
127 \r
128         public Navit    navit_jmain     = null;\r
129 \r
130         public NavitMapDownloader(Navit main)\r
131         {\r
132                 this.navit_jmain = main;\r
133         }\r
134 \r
135         public int download_osm_map(Handler handler, osm_map_values map_values)\r
136         {\r
137                 int exit_code = 1;\r
138 \r
139                 Message msg = handler.obtainMessage();\r
140                 Bundle b = new Bundle();\r
141                 msg.what = 1;\r
142                 b.putInt("max", map_values.est_size_bytes);\r
143                 b.putInt("cur", 0);\r
144                 b.putString("title", "Mapdownload");\r
145                 b.putString("text", "downloading: " + map_values.map_name);\r
146                 msg.setData(b);\r
147                 handler.sendMessage(msg);\r
148                 try\r
149                 {\r
150                         // little pause here\r
151                         Thread.sleep(10);\r
152                 }\r
153                 catch (InterruptedException e1)\r
154                 {\r
155                 }\r
156 \r
157                 // output filename\r
158                 String fileName = "navitmap.tmp";\r
159                 String final_fileName = "navitmap.bin";\r
160                 // output path for output filename\r
161                 // String PATH = Environment.getExternalStorageDirectory() + "/download/";\r
162                 String PATH = "/sdcard/";\r
163                 Log.v("log_tag", "mapfilename tmp: " + PATH + fileName);\r
164 \r
165                 try\r
166                 {\r
167                         URL url = new URL("http://maps.navit-project.org/api/map/?bbox=" + map_values.lon1 + ","\r
168                                         + map_values.lat1 + "," + map_values.lon2 + "," + map_values.lat2);\r
169                         HttpURLConnection c = (HttpURLConnection) url.openConnection();\r
170                         c.setRequestMethod("GET");\r
171                         c.setDoOutput(true);\r
172                         c.setReadTimeout(SOCKET_READ_TIMEOUT);\r
173                         c.setConnectTimeout(SOCKET_CONNECT_TIMEOUT);\r
174                         int real_size_bytes = c.getContentLength();\r
175                         c.connect();\r
176 \r
177                         if (real_size_bytes > 0)\r
178                         {\r
179                                 // change the estimated filesize to reported filesize\r
180                                 map_values.est_size_bytes = real_size_bytes;\r
181                         }\r
182 \r
183                         File file = new File(PATH);\r
184                         File outputFile = new File(file, fileName);\r
185                         File final_outputFile = new File(file, final_fileName);\r
186                         // tests have shown that deleting the file first is sometimes faster -> so we delete it (who cares)\r
187                         outputFile.delete();\r
188                         // seems this command overwrites the output file anyway\r
189                         FileOutputStream fos = new FileOutputStream(outputFile);\r
190                         BufferedOutputStream buf = new BufferedOutputStream(fos, MAP_WRITE_FILE_BUFFER); // buffer\r
191 \r
192                         InputStream is = c.getInputStream();\r
193                         BufferedInputStream bif = new BufferedInputStream(is, MAP_READ_FILE_BUFFER); // buffer\r
194 \r
195                         byte[] buffer = new byte[MAP_WRITE_MEM_BUFFER]; // buffer\r
196                         int len1 = 0;\r
197                         int already_read = 0;\r
198                         int alt = UPDATE_PROGRESS_EVERY_CYCLE; // show progress about every xx cylces\r
199                         int alt_cur = 0;\r
200                         String kbytes_per_second = "";\r
201                         //long last_timestamp = 0;\r
202                         long start_timestamp = System.currentTimeMillis();\r
203                         //int last_bytes = 0;\r
204                         NumberFormat formatter = new DecimalFormat("00000.0");\r
205                         String eta_string = "";\r
206                         float per_second_overall = 0f;\r
207                         int bytes_remaining = 0;\r
208                         int eta_seconds = 0;\r
209                         //while ((len1 = is.read(buffer)) != -1)\r
210                         while ((len1 = bif.read(buffer)) != -1)\r
211                         {\r
212                                 if (stop_me)\r
213                                 {\r
214                                         // ok we need to be stopped! close all files and end\r
215                                         Log.d("NavitMapDownloader", "stop_me 1");\r
216                                         buf.flush();\r
217                                         buf.close();\r
218                                         fos.close();\r
219                                         bif.close();\r
220                                         is.close();\r
221                                         Log.d("NavitMapDownloader", "stop_me 2");\r
222                                         c.disconnect();\r
223                                         Log.d("NavitMapDownloader", "stop_me 3");\r
224                                         return 2;\r
225                                 }\r
226                                 already_read = already_read + len1;\r
227                                 alt_cur++;\r
228                                 if (alt_cur > alt)\r
229                                 {\r
230                                         alt_cur = 0;\r
231 \r
232                                         msg = handler.obtainMessage();\r
233                                         b = new Bundle();\r
234                                         msg.what = 1;\r
235                                         b.putInt("max", map_values.est_size_bytes);\r
236                                         b.putInt("cur", already_read);\r
237                                         b.putString("title", "Map download");\r
238                                         //                                      if (last_timestamp == 0)\r
239                                         //                                      {\r
240                                         //                                              kbytes_per_second = "--";\r
241                                         //                                      }\r
242                                         //                                      else\r
243                                         //                                      {\r
244                                         //                                              //float temp = (((already_read - last_bytes) / 1024f) / ((System\r
245                                         //                                              //              .currentTimeMillis() - last_timestamp) / 1000f));\r
246                                         //                                              //kbytes_per_second = formatter.format(temp);\r
247                                         //                                      }\r
248                                         //last_timestamp = System.currentTimeMillis();\r
249                                         //last_bytes = already_read;\r
250                                         per_second_overall = (float) already_read\r
251                                                         / (float) ((System.currentTimeMillis() - start_timestamp) / 1000);\r
252                                         kbytes_per_second = formatter.format((per_second_overall / 1024f));\r
253                                         // Log.d("NavitMapDownloader", "k " + kbytes_per_second);\r
254                                         bytes_remaining = map_values.est_size_bytes - already_read;\r
255                                         eta_seconds = (int) ((float) bytes_remaining / (float) per_second_overall);\r
256                                         if (eta_seconds > 60)\r
257                                         {\r
258                                                 eta_string = (int) (eta_seconds / 60f) + " m";\r
259                                         }\r
260                                         else\r
261                                         {\r
262                                                 eta_string = eta_seconds + " s";\r
263                                         }\r
264                                         b.putString("text", "downloading: " + map_values.map_name + "\n" + " "\r
265                                                         + (int) (already_read / 1024f / 1024f) + "Mb / "\r
266                                                         + (int) (map_values.est_size_bytes / 1024f / 1024f) + "Mb" + "\n" + " "\r
267                                                         + kbytes_per_second + "kb/s" + " ETA: " + eta_string);\r
268                                         msg.setData(b);\r
269                                         handler.sendMessage(msg);\r
270                                         //                                      try\r
271                                         //                                      {\r
272                                         //                                              // little pause here\r
273                                         //                                              Thread.sleep(50);\r
274                                         //                                      }\r
275                                         //                                      catch (InterruptedException e1)\r
276                                         //                                      {\r
277                                         //                                      }\r
278                                 }\r
279                                 //fos.write(buffer, 0, len1);\r
280                                 buf.write(buffer, 0, len1);\r
281                         }\r
282                         buf.flush();\r
283 \r
284                         buf.close();\r
285                         fos.close();\r
286 \r
287                         bif.close();\r
288                         is.close();\r
289 \r
290                         c.disconnect();\r
291 \r
292                         // delete an already final filename, first\r
293                         final_outputFile.delete();\r
294                         // rename file to final name\r
295                         outputFile.renameTo(final_outputFile);\r
296                 }\r
297                 catch (IOException e)\r
298                 {\r
299                         msg = handler.obtainMessage();\r
300                         b = new Bundle();\r
301                         msg.what = 2;\r
302                         b.putString("text", "Error downloading map!");\r
303                         msg.setData(b);\r
304                         handler.sendMessage(msg);\r
305 \r
306                         Log.d("NavitMapDownloader", "Error: " + e);\r
307                         exit_code = 3;\r
308                 }\r
309                 catch (Exception e)\r
310                 {\r
311                         msg = handler.obtainMessage();\r
312                         b = new Bundle();\r
313                         msg.what = 2;\r
314                         b.putString("text", "Error downloading map!");\r
315                         msg.setData(b);\r
316                         handler.sendMessage(msg);\r
317 \r
318                         Log.d("NavitMapDownloader", "gerneral Error: " + e);\r
319                         exit_code = 4;\r
320                 }\r
321 \r
322                 msg = handler.obtainMessage();\r
323                 b = new Bundle();\r
324                 msg.what = 1;\r
325                 b.putInt("max", map_values.est_size_bytes);\r
326                 b.putInt("cur", map_values.est_size_bytes);\r
327                 b.putString("title", "Mapdownload");\r
328                 b.putString("text", map_values.map_name + " ready");\r
329                 msg.setData(b);\r
330                 handler.sendMessage(msg);\r
331 \r
332 \r
333                 Log.d("NavitMapDownloader", "success");\r
334                 exit_code = 0;\r
335                 return exit_code;\r
336         }\r
337 }\r