rhodes 3.3.2.beta.5 → 3.3.2.beta.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/CHANGELOG +1 -0
  2. data/Rakefile +4 -0
  3. data/doc/configuration.txt +2 -2
  4. data/doc/device-caps.txt +30 -17
  5. data/doc/ui.txt +24 -0
  6. data/lib/build/jake.rb +85 -2
  7. data/lib/framework/rho/rhoapplication.rb +14 -2
  8. data/platform/android/Rhodes/res/layout/datetime.xml +5 -5
  9. data/platform/android/Rhodes/src/com/rhomobile/rhodes/datetime/DateTimePickerScreen.java +2 -2
  10. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mapview/AnnotationsOverlay.java +8 -2
  11. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mapview/CalloutOverlay.java +88 -24
  12. data/platform/android/build/android.rake +27 -9
  13. data/platform/iphone/Classes/GeoLocation/LocationController.m +3 -0
  14. data/platform/iphone/rbuild/iphone.rake +6 -2
  15. data/platform/shared/common/RhodesApp.cpp +6 -1
  16. data/platform/shared/common/ThreadQueue.cpp +7 -1
  17. data/platform/shared/common/ThreadQueue.h +5 -1
  18. data/platform/shared/logging/RhoLog.cpp +4 -1
  19. data/platform/shared/logging/RhoLogConf.cpp +25 -11
  20. data/platform/shared/logging/RhoLogConf.h +4 -2
  21. data/platform/shared/logging/RhoLogSink.cpp +21 -15
  22. data/platform/shared/logging/RhoLogSink.h +17 -8
  23. data/platform/shared/net/AsyncHttp.cpp +16 -10
  24. data/platform/shared/net/AsyncHttp.h +3 -2
  25. data/platform/wm/build/wm.rake +27 -2
  26. data/platform/wm/tools/detool/detool.cpp +4 -8
  27. data/platform/wp7/build/wp.rake +2 -34
  28. data/rakefile.rb +4 -0
  29. data/res/build-tools/detool.exe +0 -0
  30. data/res/generators/templates/spec/app/spec_runner.rb +8 -2
  31. data/spec/framework_spec/app/spec_runner.rb +22 -6
  32. data/version +1 -1
  33. metadata +4 -4
data/CHANGELOG CHANGED
@@ -1,5 +1,6 @@
1
1
  ## 3.3.2
2
2
  * iPhone: fix AppStore sumbit issue. Now all files stored in Private Documents, only database and user files in Documents
3
+ * Fix issues with Ruby 1.9.2 on Mac
3
4
  * Android: fix issue with database encryption on OS 4.0
4
5
  * Android: disable zooming by default
5
6
  * iPhone: fix issue with creating Event
data/Rakefile CHANGED
@@ -303,6 +303,10 @@ namespace "config" do
303
303
  make_application_build_capabilities_header_file
304
304
  end
305
305
 
306
+ $rhologhostport = $config["log_host_port"]
307
+ $rhologhostport = 52363 unless $rhologhostport
308
+ $rhologhostaddr = Jake.localip()
309
+
306
310
  end
307
311
 
308
312
  task :qt do
@@ -113,9 +113,9 @@ Sync server url, typically this will look like 'http://<hostname>:<port>/applica
113
113
 
114
114
  syncserver = 'http://localhost:9292/application'
115
115
 
116
- Geo location update period (in seconds). Used as default value for third parameter of GeoLocation.set_notification method. This value is passed to OS API and behaviour is OS dependent (it should be used by system as a tip how often call notification back).
116
+ Geo location update period (in seconds). Used as default value for third parameter of GeoLocation.set_notification method. This value is passed to OS API and behaviour is OS dependent (it should be used by system as a tip how often call notification back). Ignored on iOS.
117
117
 
118
- gps_ping_timeout_sec = 30
118
+ gps_ping_timeout_sec = 30
119
119
 
120
120
  Geo location inactivity timeout (in seconds). This parameter controls the time after that location service is switched off in case no calls to the service. It also used as time period to drop cached location value.
121
121
 
data/doc/device-caps.txt CHANGED
@@ -199,7 +199,7 @@ Rhodes will update location using network data until the GPS signal has been rec
199
199
  There are two ways to use GeoLocation.
200
200
 
201
201
  * Syncronous call to GeoLocation module for particular value.
202
- * Set GeoLocation notification and track location by call back. In this case all location values passed to notification as parameters.
202
+ * Set GeoLocation notification and track location by call back. In this case all location values are passed to notification as parameters.
203
203
 
204
204
  Note that GeoLocation is switched off automatically when the application goes into the background, and is switched on as the application goes back to foreground.
205
205
  However it is possible to switch on location services as usual while the application is in background.
@@ -237,7 +237,7 @@ Test if the location system is up and acquired position:
237
237
  :::ruby
238
238
  GeoLocation.known_position?
239
239
 
240
- Set callback to track location changes.
240
+ Set callback to track location changes.
241
241
 
242
242
  :::ruby
243
243
  GeoLocation.set_notification(
@@ -245,13 +245,26 @@ Set callback to track location changes.
245
245
 
246
246
  * callback - callback url; after the callback has been called once, it will be automatically called repeatedly with the current location coordinates passed to the callback as parameters. (You need not reset the callback within the callback.)
247
247
  * ping_gpssystem_timeout - optional, if 0 system timeout used, use to redefine timeout in sec for gps system reading
248
- * callback params: known_position, latitude, longitude, available, status('error', 'ok'), error_code(from RhoError), accuracy
248
+ * callback params: known_position, latitude, longitude, available, status('error', 'ok'), error_code(from RhoError), accuracy(horizontal radius in meters; iOS and Android)
249
249
 
250
- Turn off GeoLocation.
250
+ Also there are two parameters you can set in rhoconfig.txt:
251
+
252
+ Geo location update period (in seconds). Used as the default value for the third parameter (ping_gpssystem_timeout) of GeoLocation.set_notification method. This value is passed to OS API and behaviour and is OS dependent (it should be used by system as a tip on how often to call notification back). Ignored on iOS.
253
+
254
+ gps_ping_timeout_sec = 30
255
+
256
+ Geo location inactivity timeout (in seconds). This parameter controls the time after that location service is switched off in case there are no calls to the service. It is also used as the time period to drop cached location value.
257
+
258
+ geo_location_inactivity_timeout = gps_ping_timeout_sec * 10
259
+
260
+
261
+ Turn off GeoLocation.
251
262
 
252
263
  :::ruby
253
264
  GeoLocation.turnoff
254
265
 
266
+ **NOTE: GeoLocation.turnoff - after GPS is switched off, you might still receive a few callbacks (this depends on the platform; iOS does not receive callbacks after turnoff).**
267
+
255
268
  **NOTE: The current behavior of the geolocation callback is that it will be called forever until it is stopped; you need to call `GeoLocation.turnoff` to stop it. Previous behavior was that the callback was called once and needed to be reset.**
256
269
 
257
270
  Get the distance between two points in miles.
@@ -261,6 +274,8 @@ Get the distance between two points in miles.
261
274
 
262
275
  GeoCoding: You can use any free web service for direct and reverse geocoding. See our complete example of using Google geocoding web service in [Rhodes-System-Api-Samples example](http://github.com/rhomobile/rhodes-system-api-samples/tree/master/app/GeoCoding).
263
276
 
277
+ **NOTE: On iOS, real GPS starts working after the first access to the GeoLocation module. Real GPS hardware is switched off after a call to GeoLocation.turnoff. But keep in mind - any call to GeoLocation, such as getting latitude, starts the hardware GPS again!**
278
+
264
279
  #### Testing GeoLocation
265
280
 
266
281
  While developing your application on Windows Mobile emulator, you may find the [FakeGPS](http://msdn.microsoft.com/en-us/library/bb158722.aspx) utility useful.
@@ -311,17 +326,14 @@ Callback points to the `geo_callback` in the Settings controller.rb:
311
326
 
312
327
  def geo_callback
313
328
  # navigate to `show_location` page if GPS receiver acquire position
314
- if @params['known_position'].to_i != 0 && @params['status'] =='ok'
315
- WebView.navigate url_for(:action => :show_location)
316
- end
317
- # show error if timeout expired and GPS receiver didn't acquire position
318
- if @params['available'].to_i == 0 || @params['status'] !='ok'
319
- WebView.navigate url_for(:action => :show_location_error)
329
+ if @params['known_position'].to_i != 0 && @params['status'] =='ok'
330
+
331
+ GeoLocation.set_notification '', '', 2
332
+ WebView.navigate url_for(:action => :map_all)
320
333
  end
321
- # do nothing, still wait for location
322
334
  end
323
335
 
324
- ##### Turning off GeoLocation as soon as the app goes of the device front page
336
+ ##### Turning off GeoLocation as soon as the app goes off the device front page
325
337
 
326
338
  In this code sample, /GeoLocation/ has to be replaced with an appropriate regular expression to detect the controller. This code is called from geo_callback. This decision allows you to switch off GeoLocation from a single code point in case geo_callback is set.
327
339
 
@@ -336,7 +348,7 @@ In this code sample, /GeoLocation/ has to be replaced with an appropriate regula
336
348
  end
337
349
  end
338
350
 
339
- If the app does not need location updates, and GeoLocation should still remian active, you can send an empty notification.
351
+ If the app does not need location updates, and GeoLocation should still remain active, you can send an empty notification.
340
352
 
341
353
  :::ruby
342
354
  GeoLocation.set_notification "", "", 30
@@ -1621,10 +1633,11 @@ Before Rhodes 3.3.2 all files stored in /Documents/ but Apple require do not pla
1621
1633
  Now all files except databases stored in /Library/Caches/Private Documents/ - files in this folder do not bakup.
1622
1634
  If you want make any files should be bakup - use "user folder" for it - Rho::RhoApplication::get_user_path. All you files created in old version in Rho::RhoApplication::get_base_app_path now should be open in Rho::RhoApplication::get_user_path.
1623
1635
 
1624
- Also there are few additional parameters in build.yml (use it only if you want tune iOS specific folder scheme for some reason):
1625
- * iphone_db_in_approot - if 1 then place databases files into <rhodes root>
1626
- * iphone_set_approot - set <rhodes root> to one of the three folders (property value - folder): "Documents" - /Documents/, "Library_Caches" - /Library/Caches/Private Documents/, "Library_Private_Documents" - /Library/Private Documents/
1627
- * iphone_userpath_in_approot - is 1 then <rhodes user root> will be in the same place with <rhodes root>
1636
+ Also there are few additional parameters in build.yml (use it only if you want tune iOS specific folder scheme for some reason).
1637
+
1638
+ * iphone_db_in_approot - if 1 then place databases files into <rhodes root>
1639
+ * iphone_set_approot - set <rhodes root> to one of the three folders (property value - folder): "Documents" - /Documents/, "Library_Caches" - /Library/Caches/Private Documents/, "Library_Private_Documents" - /Library/Private Documents/
1640
+ * iphone_userpath_in_approot - is 1 then <rhodes user root> will be in the same place with <rhodes root>
1628
1641
 
1629
1642
  ### change low level parameters in build.yml example
1630
1643
  iphone_db_in_approot: 1
data/doc/ui.txt CHANGED
@@ -591,6 +591,30 @@ For the tabbar:
591
591
  end
592
592
  end
593
593
 
594
+ Also you can use Hash instead of Array for additional parameters (the same with call runtime functionality) :
595
+ :::ruby
596
+ class AppApplication < Rho::RhoApplication
597
+ def initialize
598
+ # Tab items are loaded left->right, @tabs[0] is leftmost tab in the tab-bar
599
+ @tabs = {
600
+ :background_color => 0x0000FF,
601
+ :tabs => [
602
+ { :label => "Dashboard", :action => '/app',
603
+ :icon => "/public/images/tabs/dashboard.png", :reload => true, :web_bkg_color => 0x7F7F7F },
604
+ { :label => "Accounts", :action => '/app/Account',
605
+ :icon => "/public/images/tabs/accounts.png" },
606
+ { :label => "Contacts", :action => '/app/Contact',
607
+ :icon => "/public/images/tabs/contacts.png" },
608
+ { :label => "Options", :action => '/app/Settings',
609
+ :icon => "/public/images/tabs/options.png" }
610
+ ]
611
+ }
612
+ # Important to call super _after_ you define @tabs!
613
+ super
614
+ end
615
+ end
616
+
617
+
594
618
  Each tabbar item defined in the above sample defines the following tab elements:
595
619
 
596
620
  * :label - Visible label to display on the tabbar (required)
data/lib/build/jake.rb CHANGED
@@ -141,8 +141,8 @@ class Jake
141
141
  end
142
142
 
143
143
  def self.run_local_server(port = 0)
144
- addr = localip
145
- server = WEBrick::HTTPServer.new :BindAddress => addr, :Port => port
144
+ addr = localip #:BindAddress => addr,
145
+ server = WEBrick::HTTPServer.new :Port => port
146
146
  port = server.config[:Port]
147
147
  puts "LOCAL SERVER STARTED ON #{addr}:#{port}"
148
148
  Thread.new { server.start }
@@ -574,6 +574,89 @@ class Jake
574
574
  Dir.chdir currentdir
575
575
 
576
576
  end
577
+
578
+ def self.run_rho_log_server(app_path)
579
+
580
+ confpath_content = File.read($srcdir + "/apps/rhoconfig.txt") if File.exists?($srcdir + "/apps/rhoconfig.txt")
581
+ confpath_content += "\r\n" + "rhologhost=" + $rhologhostaddr
582
+ confpath_content += "\r\n" + "rhologport=" + $rhologhostport.to_s()
583
+ File.open($srcdir + "/apps/rhoconfig.txt", "w") { |f| f.write(confpath_content) } if confpath_content && confpath_content.length()>0
584
+
585
+ begin
586
+ require 'net/http'
587
+
588
+ res = Net::HTTP.start(Jake.localip(), $rhologhostport) {|http|
589
+ http.post('/', "RHOLOG_GET_APP_NAME")
590
+ }
591
+ puts "res : #{res}"
592
+ puts "body : #{res.body}"
593
+
594
+ if ( res && res.body == app_path)
595
+ puts "Log server is already running. Reuse it."
596
+
597
+ started = File.open($app_path + "/started", "w+")
598
+ started.close
599
+
600
+ return
601
+ else
602
+ puts "Close Log server for another app."
603
+ res = Net::HTTP.start(Jake.localip(), $rhologhostport) {|http|
604
+ http.post('/', "RHOLOG_CLOSE")
605
+ }
606
+
607
+ end
608
+ rescue Exception => e
609
+ puts "EXC: #{e}"
610
+ end
611
+
612
+ system("START rake run:webrickrhologserver[#{app_path}]")
613
+ end
577
614
 
578
615
  end
579
616
 
617
+ namespace :run do
618
+ desc "start rholog(webrick) server"
619
+ task :webrickrhologserver, :app_path do |t, args|
620
+ puts "Args were: #{args}"
621
+ $app_path = args[:app_path]
622
+
623
+ Rake::Task["config:wm"].invoke
624
+
625
+ $rhologserver = WEBrick::HTTPServer.new :Port => $rhologhostport
626
+
627
+ puts "LOCAL SERVER STARTED ON #{$rhologhostaddr}:#{$rhologhostport}"
628
+ started = File.open($app_path + "/started", "w+")
629
+ started.close
630
+
631
+ #write host and port 4 log server
632
+ $rhologfile = File.open(getLogPath, "w+")
633
+
634
+ $rhologserver.mount_proc '/' do |req,res|
635
+ if ( req.body == "RHOLOG_GET_APP_NAME" )
636
+ res.status = 200
637
+ res.chunked = true
638
+ res.body = $app_path
639
+ elsif ( req.body == "RHOLOG_CLOSE" )
640
+ res.status = 200
641
+ res.chunked = true
642
+ res.body = ""
643
+
644
+ $rhologserver.shutdown
645
+ else
646
+ $rhologfile.puts req.body
647
+ $rhologfile.flush
648
+ res.status = 200
649
+ res.chunked = true
650
+ res.body = ""
651
+ end
652
+ end
653
+
654
+ ['INT', 'TERM'].each {|signal|
655
+ trap(signal) {$rhologserver.shutdown}
656
+ }
657
+
658
+ $rhologserver.start
659
+ $rhologfile.close
660
+
661
+ end
662
+ end
@@ -79,7 +79,13 @@ module Rho
79
79
  if @@native_bar_data[:type] == :vtabbar
80
80
  tabs = @@native_bar_data[:data]
81
81
  # normalize the list
82
- tabs.map! { |tab| tab[:refresh] = false unless tab[:refresh]; tab }
82
+ if tabs.kind_of? Array
83
+ tabs.map! { |tab| tab[:refresh] = false unless tab[:refresh]; tab }
84
+ else
85
+ if tabs.kind_of? Hash
86
+ tabs[:tabs].map! { |tab| tab[:refresh] = false unless tab[:refresh]; tab }
87
+ end
88
+ end
83
89
  puts "Initializing application with vertical tabs: #{tabs.inspect}"
84
90
  NativeTabbar.create_vertical(tabs)
85
91
  #NativeTabbar.create(tabs)
@@ -87,7 +93,13 @@ module Rho
87
93
  elsif @@native_bar_data[:type] == :tabbar
88
94
  tabs = @@native_bar_data[:data]
89
95
  # normalize the list
90
- tabs.map! { |tab| tab[:refresh] = false unless tab[:refresh]; tab }
96
+ if tabs.kind_of? Array
97
+ tabs.map! { |tab| tab[:refresh] = false unless tab[:refresh]; tab }
98
+ else
99
+ if tabs.kind_of? Hash
100
+ tabs[:tabs].map! { |tab| tab[:refresh] = false unless tab[:refresh]; tab }
101
+ end
102
+ end
91
103
  puts "Initializing application with tabs: #{tabs.inspect}"
92
104
  NativeTabbar.create(tabs)
93
105
  NativeTabbar.switch_tab(0)
@@ -2,11 +2,11 @@
2
2
 
3
3
  <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
4
4
  android:orientation="vertical" android:layout_width="fill_parent"
5
- android:layout_height="fill_parent" android:fillViewport="true">
6
- <LinearLayout android:id="@+id/datetime" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_gravity="center_horizontal" android:orientation="vertical">
7
- <DatePicker android:layout_height="wrap_content" android:id="@+id/datePicker" android:layout_gravity="top|center_horizontal" android:layout_width="wrap_content"></DatePicker>
8
- <TimePicker android:layout_height="wrap_content" android:id="@+id/timePicker" android:layout_gravity="center_vertical|center_horizontal" android:layout_width="wrap_content"></TimePicker>
9
- <LinearLayout android:id="@+id/LinearLayout01" android:layout_weight="1" android:layout_gravity="center_vertical|center_horizontal" android:layout_height="wrap_content" android:layout_width="wrap_content">
5
+ android:layout_height="wrap_content" android:fillViewport="true" android:layout_gravity="center_vertical">
6
+ <LinearLayout android:id="@+id/datetime" android:layout_width="wrap_content" android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_gravity="center_vertical|center_horizontal" android:orientation="vertical">
7
+ <DatePicker android:layout_height="wrap_content" android:id="@+id/datePicker" android:layout_gravity="center_vertical|center_horizontal" android:layout_width="wrap_content" android:layout_margin="7dp"></DatePicker>
8
+ <TimePicker android:layout_height="wrap_content" android:id="@+id/timePicker" android:layout_gravity="center_vertical|center_horizontal" android:layout_width="wrap_content" android:layout_marginBottom="7dp" android:visibility="visible"></TimePicker>
9
+ <LinearLayout android:id="@+id/LinearLayout01" android:layout_gravity="center_vertical|center_horizontal" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="20dp">
10
10
  <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:id="@+id/okButton" android:text="@string/ok" android:clickable="true"></Button><Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:text="@string/cancel" android:id="@+id/cancelButton" android:clickable="true"></Button>
11
11
  </LinearLayout>
12
12
  </LinearLayout>
@@ -314,10 +314,10 @@ public class DateTimePickerScreen extends BaseActivity {
314
314
 
315
315
  switch (_fmt) {
316
316
  case FORMAT_DATE:
317
- _timePicker.setVisibility(View.INVISIBLE);
317
+ _timePicker.setVisibility(View.GONE);
318
318
  break;
319
319
  case FORMAT_TIME:
320
- _datePicker.setVisibility(View.INVISIBLE);
320
+ _datePicker.setVisibility(View.GONE);
321
321
  break;
322
322
  case FORMAT_DATE_TIME:
323
323
  break;
@@ -38,6 +38,7 @@ import com.google.android.maps.GeoPoint;
38
38
  import com.google.android.maps.ItemizedOverlay;
39
39
  import com.google.android.maps.OverlayItem;
40
40
  import com.rhomobile.rhodes.file.RhoFileApi;
41
+ import com.rhomobile.rhodes.util.PerformOnUiThread;
41
42
 
42
43
  public class AnnotationsOverlay extends ItemizedOverlay<OverlayItem> {
43
44
 
@@ -121,10 +122,15 @@ public class AnnotationsOverlay extends ItemizedOverlay<OverlayItem> {
121
122
 
122
123
  @Override
123
124
  protected boolean onTap(int i) {
124
- Annotation ann = annotations.elementAt(i);
125
+ final Annotation ann = annotations.elementAt(i);
125
126
  //if (ann.url == null)
126
127
  // return false;
127
- mainView.selectAnnotation(ann);
128
+ //PerformOnUiThread.exec(new Runnable() {
129
+ //public void run() {
130
+ mainView.selectAnnotation(ann);
131
+ //}
132
+ //}, false);
133
+
128
134
  //WebView.navigate(ann.url, WebView.activeTab());
129
135
  //mainView.finish();
130
136
  return true;
@@ -55,88 +55,152 @@ import com.rhomobile.rhodes.util.Utils;
55
55
 
56
56
  public class CalloutOverlay extends ItemizedOverlay<OverlayItem> {
57
57
 
58
- public static final String TAG = "AnnotationOverlay";
58
+ public static final String TAG = "CalloutOverlay";
59
59
 
60
60
  private GoogleMapView mainView = null;
61
61
  private Callout mCallout = null;
62
62
  private Annotation mSelectedAnnotation = null;
63
63
 
64
+
65
+ private Boolean is_logging = false;
66
+
67
+ private void printLog(String msg) {
68
+ if (is_logging) {
69
+ Utils.platformLog(TAG, msg);
70
+ }
71
+ }
72
+
64
73
  public CalloutOverlay(GoogleMapView view, Drawable marker) {
65
74
  super(boundCenterBottom(marker));
66
75
  mainView = view;
76
+ mSelectedAnnotation = null;
67
77
  populate();
68
78
  }
69
79
 
70
80
  public void selectAnnotation(Annotation ann) {
71
- mSelectedAnnotation = ann;
81
+ printLog("selectAnnotation() START");
82
+
72
83
  if (mCallout == null) {
73
84
  mCallout = new Callout(ann.latitude, ann.longitude, ann.title, ann.subtitle, ann.url, mainView);
74
85
  }
75
86
  else {
76
87
  mCallout.rebuild(ann.latitude, ann.longitude, ann.title, ann.subtitle, ann.url);
77
88
  }
78
- populate();
89
+ printLog("selectAnnotation() prePopulate");
90
+ final Annotation _ann = ann;
91
+ //PerformOnUiThread.exec(new Runnable() {
92
+ Annotation mAnn = _ann;
93
+ //public void run() {
94
+ mSelectedAnnotation = mAnn;
95
+ populate();
96
+ //mainView.
97
+ //}
98
+ //}, false);
99
+ printLog("selectAnnotation() FINISH");
79
100
  }
80
101
 
81
102
  public void deselectAnnotation() {
82
- mSelectedAnnotation = null;
103
+ printLog("deselectAnnotation() START");
104
+ printLog("deselectAnnotation() prePopulate");
105
+ //PerformOnUiThread.exec(new Runnable() {
106
+ //public void run() {
107
+ mSelectedAnnotation = null;
108
+ populate();
109
+ //}
110
+ //}, false);
111
+ printLog("deselectAnnotation() FINISH");
83
112
  }
84
113
 
85
114
 
86
115
  @Override
87
116
  protected OverlayItem createItem(int i) {
117
+ printLog(" -- createItem() START");
88
118
  Annotation ann = mSelectedAnnotation;
89
- GeoPoint pnt = new GeoPoint((int)(ann.latitude*1000000), (int)(ann.longitude*1000000));
90
- OverlayItem item = new OverlayItem(pnt, ann.title, ann.subtitle);
91
-
92
- Bitmap bitmap = mCallout.getResultBitmap();
93
- bitmap.setDensity(DisplayMetrics.DENSITY_MEDIUM);
94
- BitmapDrawable bd = new BitmapDrawable(bitmap);
95
- //bd.setTargetDensity(DisplayMetrics.DENSITY_MEDIUM);
96
- bd.setVisible(true, true);
97
- bd.setBounds( ann.callout_x_offset + mCallout.getXOffset(),
98
- ann.callout_y_offset + mCallout.getYOffset(),
99
- ann.callout_x_offset + mCallout.getXOffset() + bitmap.getWidth(),
100
- ann.callout_y_offset + mCallout.getYOffset() + bitmap.getHeight());
119
+ OverlayItem item = null;
101
120
 
102
- item.setMarker(bd);
121
+ if (ann != null) {
122
+ GeoPoint pnt = new GeoPoint((int)(ann.latitude*1000000), (int)(ann.longitude*1000000));
123
+ item = new OverlayItem(pnt, ann.title, ann.subtitle);
124
+
125
+ Bitmap bitmap = mCallout.getResultBitmap();
126
+ bitmap.setDensity(DisplayMetrics.DENSITY_MEDIUM);
127
+ BitmapDrawable bd = new BitmapDrawable(bitmap);
128
+ //bd.setTargetDensity(DisplayMetrics.DENSITY_MEDIUM);
129
+ bd.setVisible(true, true);
130
+ bd.setBounds( ann.callout_x_offset + mCallout.getXOffset(),
131
+ ann.callout_y_offset + mCallout.getYOffset(),
132
+ ann.callout_x_offset + mCallout.getXOffset() + bitmap.getWidth(),
133
+ ann.callout_y_offset + mCallout.getYOffset() + bitmap.getHeight());
134
+
135
+ item.setMarker(bd);
136
+ }
137
+ else {
138
+ GeoPoint pnt = new GeoPoint((int)(0), (int)(0));
139
+ item = new OverlayItem(pnt, "", "");
140
+ Bitmap bm = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
141
+ bm.eraseColor(0);
142
+ bm.setDensity(DisplayMetrics.DENSITY_MEDIUM);
143
+ BitmapDrawable bd = new BitmapDrawable(bm);
144
+ bd.setVisible(true, true);
145
+ bd.setBounds( 0,
146
+ 0,
147
+ 1,
148
+ 1);
149
+
150
+ item.setMarker(bd);
151
+ }
152
+ printLog(" -- createItem() FINISH");
103
153
  return item;
104
154
  }
105
155
 
106
156
  @Override
107
157
  public int size() {
108
- if (mSelectedAnnotation != null) {
109
- return 1;
110
- }
111
- return 0;
158
+ int s = 0;
159
+ //if (mSelectedAnnotation != null) {
160
+ s = 1;
161
+ //}
162
+ printLog("size() == "+String.valueOf(s));
163
+ return s;
112
164
  }
113
165
 
114
166
  @Override
115
167
  protected boolean onTap(int i) {
168
+ printLog("onTap("+String.valueOf(i)+") START");
116
169
  if (mSelectedAnnotation == null) {
170
+ printLog("onTap() return false");
117
171
  return false;
118
172
  }
119
173
  if ((mSelectedAnnotation.url != null) && (mSelectedAnnotation.url.length() > 0)) {
120
174
  WebView.navigate(mSelectedAnnotation.url, WebView.activeTab());
121
175
  mainView.finish();
176
+ printLog("onTap() return true 1");
122
177
  return true;
123
178
  }
179
+ printLog("onTap() return true 2");
124
180
  return true;
125
181
  }
126
182
 
127
183
  @Override
128
184
  public boolean onTap(GeoPoint p, com.google.android.maps.MapView mapView) {
185
+ printLog("onTap() START");
129
186
  boolean result = super.onTap(p, mapView);
187
+ printLog("onTap() after super");
130
188
  if (!result) {
131
189
  if (mSelectedAnnotation != null) {
132
- PerformOnUiThread.exec(new Runnable() {
190
+ deselectAnnotation();
191
+ /*
192
+ PerformOnUiThread.exec(new Runnable() {
133
193
  public void run() {
134
- mSelectedAnnotation = null;
135
- populate();
194
+ //mSelectedAnnotation = null;
195
+ //populate();
196
+ deselectAnnotation();
136
197
  }
137
198
  }, false);
199
+ //*/
200
+
138
201
  }
139
202
  }
203
+ printLog("onTap() FINISH");
140
204
  return result;
141
205
  }
142
206