Fix:port/android:Revert r4975 due to incomplete commit.
[profile/ivi/navit.git] / navit / navit / android / src / org / navitproject / navit / Navit.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.File;\r
23 import java.io.FileInputStream;\r
24 import java.io.FileOutputStream;\r
25 import java.io.InputStream;\r
26 import java.util.ArrayList;\r
27 import java.util.HashMap;\r
28 import java.util.List;\r
29 import java.util.Locale;\r
30 import java.util.Map;\r
31 import java.util.regex.Matcher;\r
32 import java.util.regex.Pattern;\r
33 \r
34 import android.app.Activity;\r
35 import android.app.AlertDialog;\r
36 import android.app.Dialog;\r
37 import android.app.Notification;\r
38 import android.app.NotificationManager;\r
39 import android.app.PendingIntent;\r
40 import android.content.Context;\r
41 import android.content.DialogInterface;\r
42 import android.content.Intent;\r
43 import android.content.SharedPreferences;\r
44 import android.content.res.Resources;\r
45 import android.media.AudioManager;\r
46 import android.net.Uri;\r
47 import android.os.Bundle;\r
48 import android.os.Message;\r
49 import android.os.PowerManager;\r
50 import android.text.SpannableString;\r
51 import android.text.method.LinkMovementMethod;\r
52 import android.text.util.Linkify;\r
53 import android.util.DisplayMetrics;\r
54 import android.util.Log;\r
55 import android.view.Display;\r
56 import android.view.Menu;\r
57 import android.view.MenuItem;\r
58 import android.view.inputmethod.InputMethodManager;\r
59 import android.widget.RelativeLayout;\r
60 import android.widget.TextView;\r
61 import android.widget.Toast;\r
62 \r
63 \r
64 public class Navit extends Activity\r
65 {\r
66         public static final class NavitAddress\r
67         {\r
68                 String  result_type;    // TWN,STR,SHN\r
69                 String  item_id;        // H<ddddd>L<ddddd> -> item.id_hi item.id_lo\r
70                 float   lat;\r
71                 float   lon;\r
72                 String  addr;\r
73         }\r
74 \r
75         public NavitDialogs              dialogs;\r
76         private PowerManager.WakeLock    wl;\r
77         private NavitActivityResult      ActivityResults[];\r
78         public static InputMethodManager mgr                            = null;\r
79         public static DisplayMetrics     metrics                        = null;\r
80         public static Boolean            show_soft_keyboard             = false;\r
81         public static Boolean            show_soft_keyboard_now_showing = false;\r
82         public static long               last_pressed_menu_key          = 0L;\r
83         public static long               time_pressed_menu_key          = 0L;\r
84         private static Intent            startup_intent                 = null;\r
85         private static long              startup_intent_timestamp       = 0L;\r
86         public static String             my_display_density             = "mdpi";\r
87         private boolean                  searchBoxShown                 = false;\r
88         public static final int          ADDRESS_RESULTS_DIALOG_MAX     = 10;\r
89         public static final int          NavitDownloaderPriSelectMap_id = 967;\r
90         public static final int          NavitDownloaderSecSelectMap_id = 968;\r
91         public static int                search_results_towns           = 0;\r
92         public static int                search_results_streets         = 0;\r
93         public static int                search_results_streets_hn      = 0;\r
94         public static final int          MAP_NUM_PRIMARY                = 11;\r
95         public static final int          NavitAddressSearch_id          = 70;\r
96         public static final int          NavitAddressResultList_id      = 71;\r
97 \r
98         public static List<NavitAddress> NavitAddressResultList_foundItems = new ArrayList<NavitAddress>();\r
99 \r
100         public static final int          MAP_NUM_SECONDARY              = 12;\r
101         static final String              MAP_FILENAME_PATH              = "/sdcard/navit/";\r
102         static final String              NAVIT_DATA_DIR                 = "/data/data/org.navitproject.navit";\r
103         static final String              NAVIT_DATA_SHARE_DIR           = NAVIT_DATA_DIR + "/share";\r
104         static final String              FIRST_STARTUP_FILE             = NAVIT_DATA_SHARE_DIR + "/has_run_once.txt";\r
105         public static final String       NAVIT_PREFS                    = "NavitPrefs";\r
106         \r
107         public static String get_text(String in)\r
108         {\r
109                 return NavitTextTranslations.get_text(in);\r
110         }\r
111 \r
112         private boolean extractRes(String resname, String result)\r
113         {\r
114                 int slash = -1;\r
115                 boolean needs_update = false;\r
116                 File resultfile;\r
117                 Resources res = getResources();\r
118                 Log.e("Navit", "Res Name " + resname);\r
119                 Log.e("Navit", "result " + result);\r
120                 int id = res.getIdentifier(resname, "raw", "org.navitproject.navit");\r
121                 Log.e("Navit", "Res ID " + id);\r
122                 if (id == 0) \r
123                         return false;\r
124 \r
125                 while ((slash = result.indexOf("/", slash + 1)) != -1)\r
126                 {\r
127                         if (slash != 0)\r
128                         {\r
129                                 Log.e("Navit", "Checking " + result.substring(0, slash));\r
130                                 resultfile = new File(result.substring(0, slash));\r
131                                 if (!resultfile.exists())\r
132                                 {\r
133                                         Log.e("Navit", "Creating dir");\r
134                                         if (!resultfile.mkdir())\r
135                                                 return false;\r
136                                         needs_update = true;\r
137                                 }\r
138                         }\r
139                 }\r
140 \r
141                 resultfile = new File(result);\r
142                 if (!resultfile.exists()) \r
143                         needs_update = true;\r
144 \r
145                 if (!needs_update)\r
146                 {\r
147                         try\r
148                         {\r
149                                 InputStream resourcestream = res.openRawResource(id);\r
150                                 FileInputStream resultfilestream = new FileInputStream(resultfile);\r
151                                 byte[] resourcebuf = new byte[1024];\r
152                                 byte[] resultbuf = new byte[1024];\r
153                                 int i = 0;\r
154                                 while ((i = resourcestream.read(resourcebuf)) != -1)\r
155                                 {\r
156                                         if (resultfilestream.read(resultbuf) != i)\r
157                                         {\r
158                                                 Log.e("Navit", "Result is too short");\r
159                                                 needs_update = true;\r
160                                                 break;\r
161                                         }\r
162                                         for (int j = 0; j < i; j++)\r
163                                         {\r
164                                                 if (resourcebuf[j] != resultbuf[j])\r
165                                                 {\r
166                                                         Log.e("Navit", "Result is different");\r
167                                                         needs_update = true;\r
168                                                         break;\r
169                                                 }\r
170                                         }\r
171                                         if (needs_update) break;\r
172                                 }\r
173                                 if (!needs_update && resultfilestream.read(resultbuf) != -1)\r
174                                 {\r
175                                         Log.e("Navit", "Result is too long");\r
176                                         needs_update = true;\r
177                                 }\r
178 \r
179                         }\r
180                         catch (Exception e)\r
181                         {\r
182                                 Log.e("Navit", "Exception " + e.getMessage());\r
183                                 return false;\r
184                         }\r
185                 }\r
186                 if (needs_update)\r
187                 {\r
188                         Log.e("Navit", "Extracting resource");\r
189 \r
190                         try\r
191                         {\r
192                                 InputStream resourcestream = res.openRawResource(id);\r
193                                 FileOutputStream resultfilestream = new FileOutputStream(resultfile);\r
194                                 byte[] buf = new byte[1024];\r
195                                 int i = 0;\r
196                                 while ((i = resourcestream.read(buf)) != -1)\r
197                                 {\r
198                                         resultfilestream.write(buf, 0, i);\r
199                                 }\r
200                         }\r
201                         catch (Exception e)\r
202                         {\r
203                                 Log.e("Navit", "Exception " + e.getMessage());\r
204                                 return false;\r
205                         }\r
206                 }\r
207                 return true;\r
208         }\r
209 \r
210         private void showInfos()\r
211         {\r
212                 SharedPreferences settings = getSharedPreferences(NAVIT_PREFS, MODE_PRIVATE);\r
213                 boolean firstStart = settings.getBoolean("firstStart", true);\r
214                 \r
215                 \r
216                 if (firstStart)\r
217                 {\r
218                         AlertDialog.Builder infobox = new AlertDialog.Builder(this);\r
219                         infobox.setTitle(NavitTextTranslations.INFO_BOX_TITLE); // TRANS\r
220                         infobox.setCancelable(false);\r
221                         final TextView message = new TextView(this);\r
222                         message.setFadingEdgeLength(20);\r
223                         message.setVerticalFadingEdgeEnabled(true);\r
224                         // message.setVerticalScrollBarEnabled(true);\r
225                         RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);\r
226         \r
227                         message.setLayoutParams(rlp);\r
228                         final SpannableString s = new SpannableString(NavitTextTranslations.INFO_BOX_TEXT); // TRANS\r
229                         Linkify.addLinks(s, Linkify.WEB_URLS);\r
230                         message.setText(s);\r
231                         message.setMovementMethod(LinkMovementMethod.getInstance());\r
232                         infobox.setView(message);\r
233         \r
234                         // TRANS\r
235                         infobox.setPositiveButton(Navit.get_text("Ok"), new DialogInterface.OnClickListener() {\r
236                                 public void onClick(DialogInterface arg0, int arg1) {\r
237                                         Log.e("Navit", "Ok, user saw the infobox");\r
238                                 }\r
239                         });\r
240         \r
241                         \r
242                         // TRANS\r
243                         infobox.setNeutralButton(NavitTextTranslations.NAVIT_JAVA_MENU_MOREINFO, new DialogInterface.OnClickListener() {\r
244                                 public void onClick(DialogInterface arg0, int arg1) {\r
245                                         Log.e("Navit", "user wants more info, show the website");\r
246                                         String url = "http://wiki.navit-project.org/index.php/Navit_on_Android";\r
247                                         Intent i = new Intent(Intent.ACTION_VIEW);\r
248                                         i.setData(Uri.parse(url));\r
249                                         startActivity(i);\r
250                                 }\r
251                         });\r
252                         infobox.show();\r
253                         SharedPreferences.Editor edit_settings = settings.edit();\r
254                         edit_settings.putBoolean("firstStart", false);\r
255                         edit_settings.commit();\r
256                 }\r
257         }\r
258 \r
259         /** Called when the activity is first created. */\r
260         @Override\r
261         public void onCreate(Bundle savedInstanceState)\r
262         {\r
263                 super.onCreate(savedInstanceState);\r
264 \r
265                 dialogs = new NavitDialogs(this);\r
266 \r
267                 // only take arguments here, onResume gets called all the time (e.g. when screenblanks, etc.)\r
268                 Navit.startup_intent = this.getIntent();\r
269                 // hack! remeber timstamp, and only allow 4 secs. later in onResume to set target!\r
270                 Navit.startup_intent_timestamp = System.currentTimeMillis();\r
271                 Log.e("Navit", "**1**A " + startup_intent.getAction());\r
272                 Log.e("Navit", "**1**D " + startup_intent.getDataString());\r
273 \r
274                 // init translated text\r
275                 NavitTextTranslations.init();\r
276                 \r
277                 // Setup a notification in the android notification bar, remove it in the exit() function\r
278                 NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);\r
279                 Notification notification = new Notification(R.drawable.icon,"Navit is running",0);\r
280                 notification.flags = Notification.FLAG_NO_CLEAR;\r
281                 PendingIntent appIntent = PendingIntent.getActivity(getApplicationContext(), 0, getIntent(), 0);\r
282                 notification.setLatestEventInfo(getApplicationContext(), "Navit running", "Navit still running", appIntent);\r
283                 nm.notify(R.string.app_name, notification);\r
284                 \r
285                 // get the local language -------------\r
286                 Locale locale = java.util.Locale.getDefault();\r
287                 String lang = locale.getLanguage();\r
288                 String langu = lang;\r
289                 String langc = lang;\r
290                 Log.e("Navit", "lang=" + lang);\r
291                 int pos = langu.indexOf('_');\r
292                 if (pos != -1)\r
293                 {\r
294                         langc = langu.substring(0, pos);\r
295                         langu = langc + langu.substring(pos).toUpperCase(locale);\r
296                         Log.e("Navit", "substring lang " + langu.substring(pos).toUpperCase(locale));\r
297                         // set lang. for translation\r
298                         NavitTextTranslations.main_language = langc;\r
299                         NavitTextTranslations.sub_language = langu.substring(pos).toUpperCase(locale);\r
300                 }\r
301                 else\r
302                 {\r
303                         String country = locale.getCountry();\r
304                         Log.e("Navit", "Country1 " + country);\r
305                         Log.e("Navit", "Country2 " + country.toUpperCase(locale));\r
306                         langu = langc + "_" + country.toUpperCase(locale);\r
307                         // set lang. for translation\r
308                         NavitTextTranslations.main_language = langc;\r
309                         NavitTextTranslations.sub_language = country.toUpperCase(locale);\r
310                 }\r
311                 Log.e("Navit", "Language " + lang);\r
312                 // get the local language -------------\r
313 \r
314 \r
315                 // make sure the new path for the navitmap.bin file(s) exist!!\r
316                 File navit_maps_dir = new File(MAP_FILENAME_PATH);\r
317                 navit_maps_dir.mkdirs();\r
318 \r
319                 // make sure the share dir exists\r
320                 File navit_data_share_dir = new File(NAVIT_DATA_SHARE_DIR);\r
321                 navit_data_share_dir.mkdirs();\r
322 \r
323 \r
324                 // hardcoded strings for now, use routine down below later!!\r
325                 if (lang.compareTo("de") == 0)\r
326                 {\r
327                         NavitTextTranslations.NAVIT_JAVA_MENU_download_first_map = NavitTextTranslations.NAVIT_JAVA_MENU_download_first_map_de;\r
328                         NavitTextTranslations.NAVIT_JAVA_MENU_download_second_map = NavitTextTranslations.NAVIT_JAVA_MENU_download_second_map_de;\r
329                         NavitTextTranslations.INFO_BOX_TITLE = NavitTextTranslations.INFO_BOX_TITLE_de;\r
330                         NavitTextTranslations.INFO_BOX_TEXT = NavitTextTranslations.INFO_BOX_TEXT_de;\r
331                         NavitTextTranslations.NAVIT_JAVA_MENU_MOREINFO = NavitTextTranslations.NAVIT_JAVA_MENU_MOREINFO_de;\r
332                         NavitTextTranslations.NAVIT_JAVA_MENU_ZOOMIN = NavitTextTranslations.NAVIT_JAVA_MENU_ZOOMIN_de;\r
333                         NavitTextTranslations.NAVIT_JAVA_MENU_ZOOMOUT = NavitTextTranslations.NAVIT_JAVA_MENU_ZOOMOUT_de;\r
334                         NavitTextTranslations.NAVIT_JAVA_MENU_EXIT = NavitTextTranslations.NAVIT_JAVA_MENU_EXIT_de;\r
335                         NavitTextTranslations.NAVIT_JAVA_MENU_TOGGLE_POI = NavitTextTranslations.NAVIT_JAVA_MENU_TOGGLE_POI_de;\r
336                         NavitTextTranslations.NAVIT_JAVA_OVERLAY_BUBBLE_DRIVEHERE = NavitTextTranslations.NAVIT_JAVA_OVERLAY_BUBBLE_DRIVEHERE_de;\r
337                 }\r
338                 else if (lang.compareTo("fr") == 0)\r
339                 {\r
340                         NavitTextTranslations.NAVIT_JAVA_MENU_download_first_map = NavitTextTranslations.NAVIT_JAVA_MENU_download_first_map_fr;\r
341                         NavitTextTranslations.NAVIT_JAVA_MENU_download_second_map = NavitTextTranslations.NAVIT_JAVA_MENU_download_second_map_fr;\r
342                         NavitTextTranslations.INFO_BOX_TITLE = NavitTextTranslations.INFO_BOX_TITLE_fr;\r
343                         NavitTextTranslations.INFO_BOX_TEXT = NavitTextTranslations.INFO_BOX_TEXT_fr;\r
344                         NavitTextTranslations.NAVIT_JAVA_MENU_MOREINFO = NavitTextTranslations.NAVIT_JAVA_MENU_MOREINFO_fr;\r
345                         NavitTextTranslations.NAVIT_JAVA_MENU_ZOOMIN = NavitTextTranslations.NAVIT_JAVA_MENU_ZOOMIN_fr;\r
346                         NavitTextTranslations.NAVIT_JAVA_MENU_ZOOMOUT = NavitTextTranslations.NAVIT_JAVA_MENU_ZOOMOUT_fr;\r
347                         NavitTextTranslations.NAVIT_JAVA_MENU_EXIT = NavitTextTranslations.NAVIT_JAVA_MENU_EXIT_fr;\r
348                         NavitTextTranslations.NAVIT_JAVA_MENU_TOGGLE_POI = NavitTextTranslations.NAVIT_JAVA_MENU_TOGGLE_POI_fr;\r
349                         NavitTextTranslations.NAVIT_JAVA_OVERLAY_BUBBLE_DRIVEHERE = NavitTextTranslations.NAVIT_JAVA_OVERLAY_BUBBLE_DRIVEHERE_fr;\r
350                 }\r
351                 else if (lang.compareTo("nl") == 0)\r
352                 {\r
353                         NavitTextTranslations.NAVIT_JAVA_MENU_download_first_map = NavitTextTranslations.NAVIT_JAVA_MENU_download_first_map_nl;\r
354                         NavitTextTranslations.NAVIT_JAVA_MENU_download_second_map = NavitTextTranslations.NAVIT_JAVA_MENU_download_second_map_nl;\r
355                         NavitTextTranslations.INFO_BOX_TITLE = NavitTextTranslations.INFO_BOX_TITLE_nl;\r
356                         NavitTextTranslations.INFO_BOX_TEXT = NavitTextTranslations.INFO_BOX_TEXT_nl;\r
357                         NavitTextTranslations.NAVIT_JAVA_MENU_MOREINFO = NavitTextTranslations.NAVIT_JAVA_MENU_MOREINFO_nl;\r
358                         NavitTextTranslations.NAVIT_JAVA_MENU_ZOOMIN = NavitTextTranslations.NAVIT_JAVA_MENU_ZOOMIN_nl;\r
359                         NavitTextTranslations.NAVIT_JAVA_MENU_ZOOMOUT = NavitTextTranslations.NAVIT_JAVA_MENU_ZOOMOUT_nl;\r
360                         NavitTextTranslations.NAVIT_JAVA_MENU_EXIT = NavitTextTranslations.NAVIT_JAVA_MENU_EXIT_nl;\r
361                         NavitTextTranslations.NAVIT_JAVA_MENU_TOGGLE_POI = NavitTextTranslations.NAVIT_JAVA_MENU_TOGGLE_POI_nl;\r
362                         NavitTextTranslations.NAVIT_JAVA_OVERLAY_BUBBLE_DRIVEHERE = NavitTextTranslations.NAVIT_JAVA_OVERLAY_BUBBLE_DRIVEHERE_nl;\r
363                 }\r
364 \r
365                 Display display_ = getWindowManager().getDefaultDisplay();\r
366                 int width_ = display_.getWidth();\r
367                 int height_ = display_.getHeight();\r
368                 metrics = new DisplayMetrics();\r
369                 display_.getMetrics(Navit.metrics);\r
370                 int densityDpi = (int)(( Navit.metrics.density*160)+.5f);\r
371                 Log.e("Navit", "Navit -> pixels x=" + width_ + " pixels y=" + height_);\r
372                 Log.e("Navit", "Navit -> dpi=" + densityDpi);\r
373                 Log.e("Navit", "Navit -> density=" + Navit.metrics.density);\r
374                 Log.e("Navit", "Navit -> scaledDensity=" + Navit.metrics.scaledDensity);\r
375 \r
376                 ActivityResults = new NavitActivityResult[16];\r
377                 setVolumeControlStream(AudioManager.STREAM_MUSIC);\r
378                 PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);\r
379                 wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE,"NavitDoNotDimScreen");\r
380 \r
381                 if (!extractRes(langc, NAVIT_DATA_DIR + "/locale/" + langc + "/LC_MESSAGES/navit.mo"))\r
382                 {\r
383                         Log.e("Navit", "Failed to extract language resource " + langc);\r
384                 }\r
385 \r
386                 if (densityDpi <= 120)\r
387                 {\r
388                         my_display_density = "ldpi";\r
389                 }\r
390                 else if (densityDpi <= 160)\r
391                 {\r
392                         my_display_density = "mdpi";\r
393                 }\r
394                 else if (densityDpi < 320)\r
395                 {\r
396                         my_display_density = "hdpi";\r
397                 }\r
398                 else\r
399                 {\r
400                         Log.e("Navit", "found xhdpi device, this is not fully supported!!");\r
401                         Log.e("Navit", "using hdpi values");\r
402                         my_display_density = "hdpi";\r
403                 }\r
404 \r
405                 if (!extractRes("navit" + my_display_density, NAVIT_DATA_DIR + "/share/navit.xml"))\r
406                 {\r
407                         Log.e("Navit", "Failed to extract navit.xml for " + my_display_density);\r
408                 }\r
409 \r
410                 // --> dont use android.os.Build.VERSION.SDK_INT, needs API >= 4\r
411                 Log.e("Navit", "android.os.Build.VERSION.SDK_INT=" + Integer.valueOf(android.os.Build.VERSION.SDK));\r
412                 NavitMain(this, langu, Integer.valueOf(android.os.Build.VERSION.SDK), my_display_density, NAVIT_DATA_DIR+"/bin/navit");\r
413 \r
414                 showInfos();\r
415 \r
416                 Navit.mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);\r
417 \r
418                 // unpack some localized Strings\r
419                 // a test now, later we will unpack all needed string for java, here at this point!!\r
420                 String x = NavitGraphics.getLocalizedString("Austria");\r
421                 Log.e("Navit", "x=" + x);\r
422         }\r
423 \r
424         @Override\r
425         public void onResume()\r
426         {\r
427                 super.onResume();\r
428                 Log.e("Navit", "OnResume");\r
429                 //InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);\r
430                 // DEBUG\r
431                 // intent_data = "google.navigation:q=Wien Burggasse 27";\r
432                 // intent_data = "google.navigation:q=48.25676,16.643";\r
433                 // intent_data = "google.navigation:ll=48.25676,16.643&q=blabla-strasse";\r
434                 // intent_data = "google.navigation:ll=48.25676,16.643";\r
435                 if (startup_intent != null)\r
436                 {\r
437                         if (System.currentTimeMillis() <= Navit.startup_intent_timestamp + 4000L)\r
438                         {\r
439                                 Log.e("Navit", "**2**A " + startup_intent.getAction());\r
440                                 Log.e("Navit", "**2**D " + startup_intent.getDataString());\r
441                                 String navi_scheme = startup_intent.getScheme();\r
442                                 if ( navi_scheme != null && navi_scheme.equals("google.navigation")) {\r
443                                         parseNavigationURI(startup_intent.getData().getSchemeSpecificPart());\r
444                                 }\r
445                         }\r
446                         else {\r
447                                 Log.e("Navit", "timestamp for navigate_to expired! not using data");\r
448                         }\r
449                 }\r
450         }\r
451 \r
452         private void parseNavigationURI(String schemeSpecificPart) {\r
453                 String naviData[]= schemeSpecificPart.split("&");\r
454                 Pattern p = Pattern.compile("(.*)=(.*)");\r
455                 Map<String,String> params = new HashMap<String,String>();\r
456                 for (int count=0; count < naviData.length; count++) {\r
457                         Matcher m = p.matcher(naviData[count]);\r
458                         \r
459                         if (m.matches()) {\r
460                                 params.put(m.group(1), m.group(2));\r
461                         }\r
462                 }\r
463                 \r
464                 // d: google.navigation:q=blabla-strasse # (this happens when you are offline, or from contacts)\r
465                 // a: google.navigation:ll=48.25676,16.643&q=blabla-strasse\r
466                 // c: google.navigation:ll=48.25676,16.643\r
467                 // b: google.navigation:q=48.25676,16.643\r
468                 \r
469                 Float lat;\r
470                 Float lon;\r
471                 Bundle b = new Bundle();\r
472                 \r
473                 String geoString = params.get("ll");\r
474                 if (geoString != null) {\r
475                         String address = params.get("q");\r
476                         if (address != null) b.putString("q", address);\r
477                 }\r
478                 else {\r
479                         geoString = params.get("q");\r
480                 }\r
481                 \r
482                 if ( geoString != null) {\r
483                         if (geoString.matches("^[+-]{0,1}\\d+(|\\.\\d*),[+-]{0,1}\\d+(|\\.\\d*)$")) {\r
484                                 String geo[] = geoString.split(",");\r
485                                 if (geo.length == 2) {\r
486                                         try {\r
487                                                 lat = Float.valueOf(geo[0]);\r
488                                                 lon = Float.valueOf(geo[1]);\r
489                                                 b.putFloat("lat", lat);\r
490                                                 b.putFloat("lon", lon);\r
491                                                 Message msg = Message.obtain(N_NavitGraphics.callback_handler, NavitGraphics.msg_type.CLB_SET_DESTINATION.ordinal());\r
492 \r
493                                                 msg.setData(b);\r
494                                                 msg.sendToTarget();\r
495                                                 Log.e("Navit", "target found (b): " + geoString);\r
496                                         } catch (NumberFormatException e) { } // nothing to do here\r
497                                 }\r
498                         }\r
499                         else {\r
500                                 start_targetsearch_from_intent(geoString);\r
501                         }\r
502                 }\r
503         }\r
504 \r
505         public void setActivityResult(int requestCode, NavitActivityResult ActivityResult)\r
506         {\r
507                 //Log.e("Navit", "setActivityResult " + requestCode);\r
508                 ActivityResults[requestCode] = ActivityResult;\r
509         }\r
510 \r
511         @Override\r
512         public boolean onPrepareOptionsMenu(Menu menu)\r
513         {\r
514                 super.onPrepareOptionsMenu(menu);\r
515                 //Log.e("Navit","onPrepareOptionsMenu");\r
516                 // this gets called every time the menu is opened!!\r
517                 // change menu items here!\r
518                 menu.clear();\r
519 \r
520                 // group-id,item-id,sort order number\r
521                 menu.add(1, 1, 100, get_text("zoom in")); //TRANS\r
522                 menu.add(1, 2, 200, get_text("zoom out")); //TRANS\r
523 \r
524                 menu.add(1, 3, 300, NavitTextTranslations.NAVIT_JAVA_MENU_download_first_map); //TRANS\r
525                 menu.add(1, 5, 400, NavitTextTranslations.NAVIT_JAVA_MENU_TOGGLE_POI); //TRANS\r
526 \r
527                 menu.add(1, 6, 500, get_text("address search")); //TRANS\r
528 \r
529                 menu.add(1, 4, 600, NavitTextTranslations.NAVIT_JAVA_MENU_download_second_map); //TRANS\r
530                 menu.add(1, 88, 800, "--");\r
531                 menu.add(1, 99, 900, get_text("exit navit")); //TRANS\r
532                 return true;\r
533         }\r
534 \r
535         // define callback id here\r
536         public static NavitGraphics N_NavitGraphics = null;\r
537 \r
538         // callback id gets set here when called from NavitGraphics\r
539         public static void setKeypressCallback(int kp_cb_id, NavitGraphics ng)\r
540         {\r
541                 //Log.e("Navit", "setKeypressCallback -> id1=" + kp_cb_id);\r
542                 //Log.e("Navit", "setKeypressCallback -> ng=" + String.valueOf(ng));\r
543                 //N_KeypressCallbackID = kp_cb_id;\r
544                 N_NavitGraphics = ng;\r
545         }\r
546 \r
547         public static void setMotionCallback(int mo_cb_id, NavitGraphics ng)\r
548         {\r
549                 //Log.e("Navit", "setKeypressCallback -> id2=" + mo_cb_id);\r
550                 //Log.e("Navit", "setKeypressCallback -> ng=" + String.valueOf(ng));\r
551                 //N_MotionCallbackID = mo_cb_id;\r
552                 N_NavitGraphics = ng;\r
553         }\r
554 \r
555         //public native void KeypressCallback(int id, String s);\r
556 \r
557         public void start_targetsearch_from_intent(String target_address)\r
558         {\r
559                 NavitDialogs.Navit_last_address_partial_match = false;\r
560                 NavitDialogs.Navit_last_address_search_string = target_address;\r
561 \r
562                 // clear results\r
563                 Navit.NavitAddressResultList_foundItems.clear();\r
564 \r
565                 if (NavitDialogs.Navit_last_address_search_string.equals(""))\r
566                 {\r
567                         // empty search string entered\r
568                         Toast.makeText(getApplicationContext(), Navit.get_text("No address found"), Toast.LENGTH_LONG).show(); //TRANS\r
569                 }\r
570                 else\r
571                 {\r
572                         // show dialog\r
573                         dialogs.obtainMessage(NavitDialogs.MSG_SEARCH).sendToTarget();\r
574                 }\r
575         }\r
576 \r
577         @Override\r
578         public boolean onOptionsItemSelected(MenuItem item)\r
579         {\r
580                 // Handle item selection\r
581                 switch (item.getItemId())\r
582                 {\r
583                         case 1 :\r
584                                 // zoom in\r
585                                 Message.obtain(N_NavitGraphics.callback_handler, NavitGraphics.msg_type.CLB_ZOOM_IN.ordinal()).sendToTarget();\r
586                                 // if we zoom, hide the bubble\r
587                                 Log.e("Navit", "onOptionsItemSelected -> zoom in");\r
588                                 break;\r
589                         case 2 :\r
590                                 // zoom out\r
591                                 Message.obtain(N_NavitGraphics.callback_handler, NavitGraphics.msg_type.CLB_ZOOM_OUT.ordinal()).sendToTarget();\r
592                                 // if we zoom, hide the bubble\r
593                                 Log.e("Navit", "onOptionsItemSelected -> zoom out");\r
594                                 break;\r
595                         case 3 :\r
596                                 // map download menu for primary\r
597                                 Intent map_download_list_activity = new Intent(this, NavitDownloadSelectMapActivity.class);\r
598                                 startActivityForResult(map_download_list_activity, Navit.NavitDownloaderPriSelectMap_id);\r
599                                 break;\r
600                         case 4 :\r
601                                 // map download menu for second map\r
602                                 Intent map_download_list_activity2 = new Intent(this, NavitDownloadSelectMapActivity.class);\r
603                                 startActivityForResult(map_download_list_activity2, Navit.NavitDownloaderSecSelectMap_id);\r
604                                 break;\r
605                         case 5 :\r
606                                 // toggle the normal POI layers (to avoid double POIs)\r
607                                 Message msg = Message.obtain(N_NavitGraphics.callback_handler, NavitGraphics.msg_type.CLB_CALL_CMD.ordinal());\r
608                                 Bundle b = new Bundle();\r
609                                 b.putString("cmd", "toggle_layer(\"POI Symbols\");");\r
610                                 msg.setData(b);\r
611                                 msg.sendToTarget();\r
612 \r
613                                 // toggle full POI icons on/off\r
614                                 msg = Message.obtain(N_NavitGraphics.callback_handler, NavitGraphics.msg_type.CLB_CALL_CMD.ordinal());\r
615                                 b = new Bundle();\r
616                                 b.putString("cmd", "toggle_layer(\"Android-POI-Icons-full\");");\r
617                                 msg.setData(b);\r
618                                 msg.sendToTarget();\r
619 \r
620                                 break;\r
621                         case 6 :\r
622                                 // ok startup address search activity\r
623                                 Intent search_intent = new Intent(this, NavitAddressSearchActivity.class);\r
624                                 search_intent.putExtra("title", Navit.get_text("Enter: City and Street")); //TRANS\r
625                                 search_intent.putExtra("address_string", NavitDialogs.Navit_last_address_search_string);\r
626                                 search_intent.putExtra("partial_match", NavitDialogs.Navit_last_address_partial_match);\r
627                                 this.startActivityForResult(search_intent, NavitAddressSearch_id);\r
628                                 break;\r
629                         case 88 :\r
630                                 // dummy entry, just to make "breaks" in the menu\r
631                                 break;\r
632                         case 99 :\r
633                                 // exit\r
634                                 this.onStop();\r
635                                 this.exit();\r
636                                 break;\r
637                 }\r
638                 return true;\r
639         }\r
640 \r
641         void setDestination(float latitude, float longitude, String address) {\r
642                 Toast.makeText( getApplicationContext(),Navit.get_text("setting destination to") + "\n" + address, Toast.LENGTH_LONG).show(); //TRANS\r
643 \r
644                 Message msg = Message.obtain(N_NavitGraphics.callback_handler, NavitGraphics.msg_type.CLB_SET_DESTINATION.ordinal());\r
645                 Bundle b = new Bundle();\r
646                 b.putFloat("lat", latitude);\r
647                 b.putFloat("lon", longitude);\r
648                 b.putString("q", address);\r
649                 msg.setData(b);\r
650                 msg.sendToTarget();\r
651         }\r
652 \r
653         protected void onActivityResult(int requestCode, int resultCode, Intent data)\r
654         {\r
655                 switch (requestCode)\r
656                 {\r
657                 case Navit.NavitDownloaderPriSelectMap_id :\r
658                 case Navit.NavitDownloaderSecSelectMap_id :\r
659                         if (resultCode == Activity.RESULT_OK)\r
660                         {\r
661                                 Message msg = dialogs.obtainMessage(NavitDialogs.MSG_START_MAP_DOWNLOAD\r
662                                                 , data.getIntExtra("selected_id", -1)\r
663                                                 , requestCode == Navit.NavitDownloaderSecSelectMap_id ? 2 : 0);\r
664                                 msg.sendToTarget();\r
665                         }\r
666                         break;\r
667                 case NavitAddressSearch_id :\r
668                         if (resultCode == Activity.RESULT_OK) {\r
669                                 Boolean addr_selected = data.getBooleanExtra("addr_selected", false);\r
670                                 \r
671                                 // address already choosen, or do we have to search?\r
672                                 if (addr_selected) {\r
673                                         setDestination( NavitAddressResultList_foundItems .get(0).lat\r
674                                                       , NavitAddressResultList_foundItems.get(0).lon\r
675                                                       , NavitAddressResultList_foundItems.get(0).addr);\r
676                                 } else {\r
677                                         String addr = data.getStringExtra("address_string");\r
678                                         Boolean partial_match = data.getBooleanExtra("partial_match", false);\r
679                                         String country = data.getStringExtra("country");\r
680         \r
681                                         NavitDialogs.Navit_last_address_partial_match = partial_match;\r
682                                         NavitDialogs.Navit_last_address_search_string = addr;\r
683                                         NavitDialogs.Navit_last_country = country;\r
684         \r
685                                         // clear results\r
686                                         Navit.NavitAddressResultList_foundItems.clear();\r
687                                         Navit.search_results_towns = 0;\r
688                                         Navit.search_results_streets = 0;\r
689                                         Navit.search_results_streets_hn = 0;\r
690         \r
691                                         if (addr.equals("")) {\r
692                                                 // empty search string entered\r
693                                                 Toast.makeText(getApplicationContext(),Navit.get_text("No search string entered"), Toast.LENGTH_LONG).show(); //TRANS\r
694                                         } else {\r
695                                                 // show dialog, and start search for the results\r
696                                                 // make it indirect, to give our activity a chance to startup\r
697                                                 // (remember we come straight from another activity and ours is still paused!)\r
698                                                 dialogs.obtainMessage(NavitDialogs.MSG_SEARCH).sendToTarget();\r
699                                         }\r
700                                 }\r
701                         }\r
702                         break;\r
703                 case Navit.NavitAddressResultList_id :\r
704                         try\r
705                         {\r
706                                 if (resultCode == Activity.RESULT_OK)\r
707                                 {\r
708                                         int destination_id = data.getIntExtra("selected_id", 0);\r
709                                         \r
710                                         setDestination( NavitAddressResultList_foundItems .get(destination_id).lat\r
711                                                       , NavitAddressResultList_foundItems.get(destination_id).lon\r
712                                                       , NavitAddressResultList_foundItems.get(destination_id).addr);\r
713                                 }\r
714                         }\r
715                         catch (Exception e)\r
716                         {\r
717                                 Log.d("Navit", "error on onActivityResult");\r
718                         }\r
719                         break;\r
720                 default :\r
721                         //Log.e("Navit", "onActivityResult " + requestCode + " " + resultCode);\r
722                         ActivityResults[requestCode].onActivityResult(requestCode, resultCode, data);\r
723                         break;\r
724                 }\r
725         }\r
726 \r
727         protected Dialog onCreateDialog(int id)\r
728         {\r
729                 return dialogs.createDialog(id);\r
730         }\r
731 \r
732         @Override\r
733         public void onDestroy()\r
734         {\r
735                 super.onDestroy();\r
736                 Log.e("Navit", "OnDestroy");\r
737                 // TODO next call will kill our app the hard way. This should not be necessary, but ensures navit is\r
738                 // properly restarted and no resources are wasted with navit in background. Remove this call after \r
739                 // code review\r
740                 NavitDestroy();\r
741         }\r
742 \r
743         public void disableSuspend()\r
744         {\r
745                 wl.acquire();\r
746                 wl.release();\r
747         }\r
748 \r
749         public void exit()\r
750         {\r
751                 NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);\r
752                 nm.cancel(R.string.app_name);\r
753                 NavitVehicle.removeListener();\r
754                 finish();\r
755         }\r
756 \r
757         public native void NavitMain(Navit x, String lang, int version, String display_density_string, String path);\r
758         public native void NavitDestroy();\r
759 \r
760         /*\r
761          * this is used to load the 'navit' native library on\r
762          * application startup. The library has already been unpacked at\r
763          * installation time by the package manager.\r
764          */\r
765         static\r
766         {\r
767                 System.loadLibrary("navit");\r
768         }\r
769 \r
770         /*\r
771          * Show a search activity with the string "search" filled in\r
772          */\r
773         private void executeSearch(String search)\r
774         {\r
775                 Intent search_intent = new Intent(this, NavitAddressSearchActivity.class);\r
776                 search_intent.putExtra("title", Navit.get_text("Enter: City and Street")); //TRANS\r
777                 search_intent.putExtra("address_string", search);\r
778                 search_intent.putExtra("partial_match", NavitDialogs.Navit_last_address_partial_match);\r
779                 this.startActivityForResult(search_intent, NavitAddressSearch_id);\r
780         }\r
781 }\r