ruboto-core 0.2.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +1 -1
- data/Gemfile.lock +8 -4
- data/README.md +1 -1
- data/Rakefile +4 -0
- data/assets/Rakefile +140 -64
- data/assets/assets/scripts/ruboto.rb +17 -26
- data/assets/res/drawable-hdpi/icon.png +0 -0
- data/assets/res/drawable-ldpi/icon.png +0 -0
- data/assets/res/drawable-mdpi/icon.png +0 -0
- data/assets/src/RubotoActivity.java +2 -0
- data/assets/src/org/ruboto/Script.java +38 -4
- data/assets/src/org/ruboto/test/InstrumentationTestRunner.java +12 -0
- data/lib/java_class_gen/android_api.xml +1 -1
- data/lib/ruboto/commands/base.rb +19 -9
- data/lib/ruboto/util/asset_copier.rb +10 -3
- data/lib/ruboto/util/build.rb +1 -1
- data/lib/ruboto/util/update.rb +110 -23
- data/lib/ruboto/util/verify.rb +24 -0
- data/lib/ruboto/util/xml_element.rb +2 -9
- data/test/activity/{image_button.rb → image_button_activity.rb} +0 -0
- data/test/activity/{image_button_test.rb → image_button_activity_test.rb} +1 -1
- data/test/activity/{image_button_and_button.rb → image_button_and_button_activity.rb} +0 -7
- data/test/activity/{image_button_and_button_test.rb → image_button_and_button_activity_test.rb} +1 -1
- data/test/activity/option_menu_activity.rb +21 -0
- data/test/activity/option_menu_activity_test.rb +20 -0
- data/test/app_test_methods.rb +24 -31
- data/test/minimal_app_test.rb +22 -0
- data/test/rake_test.rb +2 -17
- data/test/ruboto_gen_test.rb +19 -8
- data/test/ruboto_update_test.rb +8 -18
- data/test/service_test.rb +2 -4
- data/test/test_helper.rb +59 -7
- metadata +31 -13
data/COPYING
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c)
|
1
|
+
Copyright (c) 2011 Daniel Jackoway, Charles Nutter, Scott Moyer, Uwe Kubosch
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
of this software and associated documentation files (the "Software"), to deal
|
data/Gemfile.lock
CHANGED
@@ -2,11 +2,15 @@ GEM
|
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
4
|
arrayfields (4.7.4)
|
5
|
-
|
5
|
+
chronic (0.6.2)
|
6
|
+
fattr (2.2.0)
|
6
7
|
jruby-jars (1.6.3)
|
7
|
-
main (4.
|
8
|
-
arrayfields (
|
9
|
-
|
8
|
+
main (4.7.3)
|
9
|
+
arrayfields (~> 4.7.4)
|
10
|
+
chronic (~> 0.6.2)
|
11
|
+
fattr (~> 2.2.0)
|
12
|
+
map (~> 4.3.0)
|
13
|
+
map (4.3.0)
|
10
14
|
|
11
15
|
PLATFORMS
|
12
16
|
java
|
data/README.md
CHANGED
@@ -40,7 +40,7 @@ Command-line Tools
|
|
40
40
|
<a name="application_generator"></a>
|
41
41
|
### Application generator
|
42
42
|
|
43
|
-
$ ruboto gen app --package com.yourdomain.whatever --path path/to/where/you/want/the/app --name NameOfApp --target android-version --
|
43
|
+
$ ruboto gen app --package com.yourdomain.whatever --path path/to/where/you/want/the/app --name NameOfApp --target android-version --min-sdk another-android-version --activity MainActivityName
|
44
44
|
Version values must be specified using'android-' and the sdk level number (e.g., android-8 is froyo).
|
45
45
|
|
46
46
|
<a name="class_generator"></a>
|
data/Rakefile
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
task :default => :gem
|
2
2
|
|
3
|
+
desc "Generate a gem"
|
3
4
|
task :gem do
|
4
5
|
`gem build ruboto-core.gemspec`
|
5
6
|
end
|
6
7
|
|
8
|
+
desc "Push the gem to RubyGems"
|
7
9
|
task :release do
|
8
10
|
sh "gem push #{Dir['ruboto-core-*.gem'][-1]}"
|
9
11
|
end
|
10
12
|
|
13
|
+
desc "Run the tests"
|
11
14
|
task :test do
|
15
|
+
FileUtils.rm_rf Dir['tmp/RubotoTestApp_template*']
|
12
16
|
Dir['test/*_test.rb'].each do |f|
|
13
17
|
require f.chomp('.rb')
|
14
18
|
end
|
data/assets/Rakefile
CHANGED
@@ -3,32 +3,51 @@ require 'time'
|
|
3
3
|
def manifest() @manifest ||= REXML::Document.new(File.read(MANIFEST_FILE)) end
|
4
4
|
def package() manifest.root.attribute('package') end
|
5
5
|
def build_project_name() @build_project_name ||= REXML::Document.new(File.read('build.xml')).elements['project'].attribute(:name).value end
|
6
|
-
|
7
|
-
|
8
|
-
BUNDLE_JAR = 'libs/bundle.jar'
|
9
|
-
BUNDLE_PATH = 'tmp/bundle'
|
6
|
+
def sdcard_path() @sdcard_path ||= "/mnt/sdcard/Android/data/#{package}/files" end
|
7
|
+
def app_files_path() @app_files_path ||= "/data/data/#{package}/files" end
|
10
8
|
|
11
9
|
require 'rake/clean'
|
12
10
|
require 'rexml/document'
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
MANIFEST_FILE = 'AndroidManifest.xml'
|
18
|
-
|
12
|
+
UPDATE_MARKER_FILE = File.expand_path(File.join('tmp', 'LAST_UPDATE'), File.dirname(__FILE__))
|
13
|
+
BUNDLE_JAR = File.expand_path 'libs/bundle.jar'
|
14
|
+
BUNDLE_PATH = File.expand_path 'tmp/bundle'
|
15
|
+
MANIFEST_FILE = File.expand_path 'AndroidManifest.xml'
|
16
|
+
RUBOTO_CONFIG_FILE = File.expand_path 'ruboto.yml'
|
17
|
+
GEM_FILE = File.expand_path('Gemfile.apk')
|
18
|
+
APK_FILE = File.expand_path "bin/#{build_project_name}-debug.apk"
|
19
|
+
TEST_APK_FILE = File.expand_path "test/bin/#{build_project_name}Test-debug.apk"
|
20
|
+
JRUBY_JARS = Dir[File.expand_path 'libs/jruby-*.jar']
|
21
|
+
RESOURCE_FILES = Dir[File.expand_path 'res/**/*']
|
22
|
+
JAVA_SOURCE_FILES = Dir[File.expand_path 'src/**/*.java']
|
19
23
|
|
20
24
|
CLEAN.include('tmp', 'bin')
|
21
25
|
|
22
26
|
task :default => :debug
|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
|
28
|
+
file JRUBY_JARS => RUBOTO_CONFIG_FILE do
|
29
|
+
next unless File.exists? RUBOTO_CONFIG_FILE
|
30
|
+
jruby_jars_mtime = JRUBY_JARS.map{|f| File.mtime(f)}.min
|
31
|
+
ruboto_yml_mtime = File.mtime(RUBOTO_CONFIG_FILE)
|
32
|
+
next if jruby_jars_mtime > ruboto_yml_mtime
|
33
|
+
puts '*' * 80
|
34
|
+
if JRUBY_JARS.empty?
|
35
|
+
puts ' The JRuby jars are missing.'
|
36
|
+
else
|
37
|
+
puts " The JRuby jars need reconfiguring after changes to #{RUBOTO_CONFIG_FILE}"
|
38
|
+
puts " #{RUBOTO_CONFIG_FILE}: #{ruboto_yml_mtime}"
|
39
|
+
puts " #{JRUBY_JARS.join(', ')}: #{jruby_jars_mtime}"
|
40
|
+
end
|
41
|
+
puts ' Run "ruboto update jruby" to regenerate the JRuby jars'
|
42
|
+
puts '*' * 80
|
27
43
|
end
|
28
44
|
|
45
|
+
desc 'build debug package'
|
46
|
+
task :debug => APK_FILE
|
47
|
+
|
29
48
|
desc "build package and install it on the emulator or device"
|
30
|
-
task :install =>
|
31
|
-
|
49
|
+
task :install => APK_FILE do
|
50
|
+
install_apk
|
32
51
|
end
|
33
52
|
|
34
53
|
task :tag => :release do
|
@@ -59,67 +78,81 @@ task :emulator do
|
|
59
78
|
system 'emulator -partition-size 1024 -avd Android_3.0'
|
60
79
|
end
|
61
80
|
|
62
|
-
task :
|
81
|
+
task :start do
|
63
82
|
`adb shell am start -a android.intent.action.MAIN -n #{package}/.#{main_activity}`
|
64
83
|
end
|
65
84
|
|
66
|
-
task :
|
85
|
+
task :stop do
|
67
86
|
`adb shell ps | grep #{package} | awk '{print $2}' | xargs adb shell kill`
|
68
87
|
end
|
69
88
|
|
70
89
|
desc 'Restart the application'
|
71
|
-
task :restart => [:
|
90
|
+
task :restart => [:stop, :start]
|
72
91
|
|
73
92
|
task :uninstall do
|
74
|
-
|
75
|
-
system "adb uninstall #{package}"
|
93
|
+
uninstall_apk
|
76
94
|
end
|
77
95
|
|
78
96
|
namespace :install do
|
79
97
|
desc 'Uninstall, build, and install the application'
|
80
|
-
task :clean => [:uninstall, :install]
|
81
|
-
|
82
|
-
desc 'Build, install, and restart the application'
|
83
|
-
task :restart => [:install, :start_app]
|
84
|
-
|
85
|
-
namespace :restart do
|
86
|
-
desc 'Uninstall, build, install, and restart the application'
|
87
|
-
task :clean => [:uninstall, :install, :start_app]
|
88
|
-
end
|
98
|
+
task :clean => [:uninstall, APK_FILE, :install]
|
89
99
|
end
|
90
100
|
|
91
101
|
file MANIFEST_FILE
|
102
|
+
file RUBOTO_CONFIG_FILE
|
103
|
+
|
104
|
+
file APK_FILE => [MANIFEST_FILE, RUBOTO_CONFIG_FILE, BUNDLE_JAR] + JRUBY_JARS + JAVA_SOURCE_FILES + RESOURCE_FILES do |t|
|
105
|
+
if File.exist?(APK_FILE)
|
106
|
+
changed_prereqs = t.prerequisites.select do |p|
|
107
|
+
File.exist?(p) && !Dir[p].empty? && Dir[p].map{|f| File.mtime(f)}.max > File.mtime(APK_FILE)
|
108
|
+
end
|
92
109
|
|
93
|
-
|
94
|
-
|
95
|
-
|
110
|
+
if changed_prereqs.empty?
|
111
|
+
puts
|
112
|
+
puts 'skipping'
|
113
|
+
puts
|
114
|
+
next
|
115
|
+
end
|
116
|
+
changed_prereqs.each{|f| puts "#{f} changed."}
|
117
|
+
puts "Forcing rebuild of #{APK_FILE}."
|
118
|
+
end
|
119
|
+
sh 'ant debug'
|
96
120
|
end
|
97
121
|
|
98
122
|
desc 'Copy scripts to emulator or device'
|
99
|
-
task :update_scripts
|
100
|
-
sdcard_path
|
101
|
-
|
102
|
-
if package_installed? && device_path_exists?(sdcard_path)
|
103
|
-
puts 'Pushing files to apk public file area.'
|
123
|
+
task :update_scripts do
|
124
|
+
if device_path_exists?(sdcard_path)
|
125
|
+
data_dir_name = 'public'
|
104
126
|
data_dir = sdcard_path
|
105
|
-
elsif
|
106
|
-
|
127
|
+
elsif device_path_exists?(app_files_path)
|
128
|
+
data_dir_name = 'private'
|
107
129
|
data_dir = app_files_path
|
108
130
|
else
|
109
131
|
puts 'Cannot find the scripts directory on the device.'
|
110
|
-
|
111
|
-
|
112
|
-
|
132
|
+
unless manifest.root.elements["uses-permission[@android:name='android.permission.WRITE_EXTERNAL_STORAGE']"]
|
133
|
+
puts 'If you have a non-rooted device, you need to add'
|
134
|
+
puts %q{ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />}
|
135
|
+
puts 'to the AndroidManifest.xml file to enable the update_scripts rake task.'
|
136
|
+
end
|
113
137
|
puts "Reverting to uninstalling and re-installing the apk."
|
114
|
-
Rake::Task[
|
138
|
+
Rake::Task[:uninstall].reenable
|
139
|
+
Rake::Task[:uninstall].invoke
|
140
|
+
FileUtils.rm_f APK_FILE
|
141
|
+
Rake::Task[APK_FILE].reenable
|
142
|
+
Rake::Task[APK_FILE].invoke
|
143
|
+
Rake::Task[:install].reenable
|
144
|
+
Rake::Task[:install].invoke
|
115
145
|
next
|
116
146
|
end
|
147
|
+
Rake::Task['install'].invoke
|
148
|
+
puts "Pushing files to apk #{data_dir_name} file area."
|
117
149
|
last_update = File.exists?(UPDATE_MARKER_FILE) ? Time.parse(File.read(UPDATE_MARKER_FILE)) : Time.parse('1970-01-01T00:00:00')
|
118
150
|
Dir.chdir('assets') do
|
119
151
|
['scripts'].each do |asset_dir|
|
120
152
|
Dir["#{asset_dir}/*"].each do |asset_file|
|
121
153
|
next if File.directory? asset_file
|
122
|
-
next if File.
|
154
|
+
next if File.mtime(asset_file) < last_update
|
155
|
+
next if asset_file =~ /~$/
|
123
156
|
print "#{asset_file}: " ; $stdout.flush
|
124
157
|
`adb push #{asset_file} #{data_dir}/#{asset_file}`
|
125
158
|
end
|
@@ -130,13 +163,13 @@ end
|
|
130
163
|
|
131
164
|
namespace :update_scripts do
|
132
165
|
desc 'Copy scripts to emulator and restart the app'
|
133
|
-
task :restart => [:
|
166
|
+
task :restart => [:stop, :update_scripts, :start]
|
134
167
|
end
|
135
168
|
|
136
169
|
task :update_test_scripts do
|
137
170
|
test_scripts_path = "/data/data/#{package}.tests/files/scripts"
|
138
171
|
# TODO(uwe): Investigate if we can just push the scripts instead of building and installing the instrumentation APK
|
139
|
-
if
|
172
|
+
if package_installed?(true) && device_path_exists?(test_scripts_path)
|
140
173
|
Dir['test/assets/scripts/*.rb'].each do |script|
|
141
174
|
print "#{script}: " ; $stdout.flush
|
142
175
|
`adb push #{script} #{test_scripts_path}`
|
@@ -166,15 +199,15 @@ namespace :test do
|
|
166
199
|
end
|
167
200
|
end
|
168
201
|
|
169
|
-
file
|
202
|
+
file GEM_FILE
|
170
203
|
|
171
204
|
desc 'Generate bundle jar from Gemfile'
|
172
|
-
file BUNDLE_JAR =>
|
173
|
-
next unless File.exists?
|
205
|
+
file BUNDLE_JAR => GEM_FILE do
|
206
|
+
next unless File.exists? GEM_FILE
|
174
207
|
puts "Generating #{BUNDLE_JAR}"
|
175
208
|
|
176
209
|
FileUtils.mkdir_p BUNDLE_PATH
|
177
|
-
sh "bundle install --path=#{BUNDLE_PATH}"
|
210
|
+
sh "bundle install --gemfile #{GEM_FILE} --path=#{BUNDLE_PATH}"
|
178
211
|
|
179
212
|
# FIXME(uwe): Should not be necessary. ARJDBC should not offer the same files as AR.
|
180
213
|
|
@@ -210,6 +243,25 @@ end
|
|
210
243
|
EOF
|
211
244
|
replace_faulty_code(faulty_file, faulty_code)
|
212
245
|
end
|
246
|
+
# FIXME end
|
247
|
+
|
248
|
+
# Expand JARs
|
249
|
+
Dir.chdir "#{BUNDLE_PATH}/ruby/1.8/gems" do
|
250
|
+
Dir['*'].each do |gem_lib|
|
251
|
+
next if gem_lib =~ /jdbc-sqlite/
|
252
|
+
Dir.chdir "#{gem_lib}/lib" do
|
253
|
+
Dir['**/*.jar'].each do |jar|
|
254
|
+
puts "Expanding #{gem_lib} #{jar} into #{BUNDLE_JAR}"
|
255
|
+
|
256
|
+
`jar xf #{jar}`
|
257
|
+
FileUtils.rm_f(jar)
|
258
|
+
# FileUtils.touch(jar + '.rb')
|
259
|
+
# FileUtils.touch(jar.chomp('jar') + 'rb')
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
213
265
|
|
214
266
|
FileUtils.rm_f BUNDLE_JAR
|
215
267
|
Dir["#{BUNDLE_PATH}/ruby/1.8/gems/*"].each_with_index do |gem_dir, i|
|
@@ -220,15 +272,15 @@ end
|
|
220
272
|
Rake::Task['install'].invoke
|
221
273
|
end
|
222
274
|
|
223
|
-
task :mark_update do
|
224
|
-
mark_update
|
225
|
-
end
|
226
|
-
|
227
275
|
# Methods
|
228
276
|
|
229
|
-
def mark_update
|
277
|
+
def mark_update(time = Time.now)
|
230
278
|
FileUtils.mkdir_p File.dirname(UPDATE_MARKER_FILE)
|
231
|
-
File.open(UPDATE_MARKER_FILE, 'w'){|f| f <<
|
279
|
+
File.open(UPDATE_MARKER_FILE, 'w'){|f| f << time.iso8601}
|
280
|
+
end
|
281
|
+
|
282
|
+
def clear_update
|
283
|
+
FileUtils.rm_f UPDATE_MARKER_FILE
|
232
284
|
end
|
233
285
|
|
234
286
|
def strings(name)
|
@@ -246,22 +298,24 @@ def main_activity() manifest.root.elements['application'].elements["activity[@an
|
|
246
298
|
def device_path_exists?(path)
|
247
299
|
path_output =`adb shell ls #{path}`
|
248
300
|
result = path_output.chomp !~ /No such file or directory|opendir failed, Permission denied/
|
249
|
-
puts "Checking path on device: #{path}: #{result || path_output}"
|
250
301
|
result
|
251
302
|
end
|
252
303
|
|
253
304
|
def package_installed? test = false
|
254
305
|
package_name = "#{package}#{'.tests' if test}"
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
if o
|
259
|
-
|
260
|
-
|
306
|
+
['', '-0', '-1', '-2'].each do |i|
|
307
|
+
p = "/data/app/#{package_name}#{i}.apk"
|
308
|
+
o = `adb shell ls -l #{p}`.chomp
|
309
|
+
if o =~ /^-rw-r--r-- system\s+system\s+(\d+) \d{4}-\d{2}-\d{2} \d{2}:\d{2} #{File.basename(p)}$/
|
310
|
+
apk_file = test ? TEST_APK_FILE : APK_FILE
|
311
|
+
if !File.exists?(apk_file) || $1.to_i == File.size(apk_file)
|
312
|
+
return true
|
313
|
+
else
|
314
|
+
return false
|
315
|
+
end
|
261
316
|
end
|
262
317
|
end
|
263
|
-
|
264
|
-
return false
|
318
|
+
return nil
|
265
319
|
end
|
266
320
|
|
267
321
|
private
|
@@ -280,3 +334,25 @@ def replace_faulty_code(faulty_file, faulty_code)
|
|
280
334
|
puts "Could not find expected faulty code\n\n#{faulty_code}\n\nin file #{faulty_file}\n\n#{old_code}\n\n"
|
281
335
|
end
|
282
336
|
end
|
337
|
+
|
338
|
+
def install_apk
|
339
|
+
case package_installed?
|
340
|
+
when true
|
341
|
+
puts "Package already installed."
|
342
|
+
return
|
343
|
+
when false
|
344
|
+
puts "Package installed, but of wrong size."
|
345
|
+
end
|
346
|
+
sh 'ant ruboto-install-debug'
|
347
|
+
clear_update
|
348
|
+
end
|
349
|
+
|
350
|
+
def uninstall_apk
|
351
|
+
return if package_installed?.nil?
|
352
|
+
puts "Uninstalling package #{package}"
|
353
|
+
system "adb uninstall #{package}"
|
354
|
+
if $? != 0 && package_installed?
|
355
|
+
puts "Uninstall failed exit code #{$?}"
|
356
|
+
exit $?
|
357
|
+
end
|
358
|
+
end
|
@@ -197,8 +197,9 @@ def ruboto_configure_activity(klass)
|
|
197
197
|
|
198
198
|
p = Proc.new do |num, menu_item|
|
199
199
|
# handles a problem where this is called for context items
|
200
|
-
# JRUBY-5866 JRuby can't access nested Java class if the class is called 'id'
|
201
|
-
|
200
|
+
# TODO(uwe): JRUBY-5866 JRuby can't access nested Java class if the class is called 'id'
|
201
|
+
# TODO(uwe): Remove check for SDK version when we stop supporting api level < 11
|
202
|
+
unless @just_processed_context_item == menu_item || (android.os.Build::VERSION::SDK_INT >= 11 && menu_item.item_id == AndroidIds.home)
|
202
203
|
instance_eval &(menu_item.on_click)
|
203
204
|
@just_processed_context_item = nil
|
204
205
|
true
|
@@ -599,27 +600,17 @@ def setup_preferences
|
|
599
600
|
@preferences_setup_complete = true
|
600
601
|
end
|
601
602
|
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
#
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
# if $service
|
618
|
-
java_import "org.ruboto.RubotoService"
|
619
|
-
ruboto_setup(RubotoService)
|
620
|
-
# end
|
621
|
-
|
622
|
-
# if $broadcast_receiver
|
623
|
-
java_import "org.ruboto.RubotoBroadcastReceiver"
|
624
|
-
ruboto_setup(RubotoBroadcastReceiver, "receive")
|
625
|
-
# end
|
603
|
+
# Setup activity support
|
604
|
+
java_import "org.ruboto.RubotoActivity"
|
605
|
+
setup_activity
|
606
|
+
ruboto_configure_activity(RubotoActivity)
|
607
|
+
ruboto_setup(RubotoActivity)
|
608
|
+
setup_view
|
609
|
+
|
610
|
+
# setup service support
|
611
|
+
java_import "org.ruboto.RubotoService"
|
612
|
+
ruboto_setup(RubotoService)
|
613
|
+
|
614
|
+
# setup broadcast receiver support
|
615
|
+
java_import "org.ruboto.RubotoBroadcastReceiver"
|
616
|
+
ruboto_setup(RubotoBroadcastReceiver, "receive")
|
Binary file
|
Binary file
|
Binary file
|
@@ -127,11 +127,13 @@ THE_CONSTANTS
|
|
127
127
|
} else {
|
128
128
|
try {
|
129
129
|
new Script(scriptName).execute();
|
130
|
+
/* TODO(uwe): Add a way to add callbacks from a class or just forward all calls to the instance
|
130
131
|
rubyClassName = this.getClass().getSimpleName();
|
131
132
|
if (getRuby().get(rubyClassName) != null) {
|
132
133
|
rubyInstance = Script.exec(rubyClassName + ".new");
|
133
134
|
getRuby().callMethod(rubyInstance, "on_create", configBundle);
|
134
135
|
}
|
136
|
+
*/
|
135
137
|
} catch(IOException e){
|
136
138
|
e.printStackTrace();
|
137
139
|
ProgressDialog.show(this, "Script failed", "Something bad happened", true, true);
|