rhodes 1.5.4 → 1.5.5
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/Manifest.txt +11 -1
- data/Rakefile +1 -1
- data/lib/extensions/digest/ext/Rakefile +11 -6
- data/lib/extensions/digest/ext/build.bat +2 -0
- data/lib/extensions/uri/uri.rb +29 -0
- data/lib/extensions/uri/uri/common.rb +727 -0
- data/lib/extensions/uri/uri/ftp.rb +198 -0
- data/lib/extensions/uri/uri/generic.rb +1128 -0
- data/lib/extensions/uri/uri/http.rb +100 -0
- data/lib/extensions/uri/uri/https.rb +20 -0
- data/lib/extensions/uri/uri/ldap.rb +190 -0
- data/lib/extensions/uri/uri/ldaps.rb +12 -0
- data/lib/extensions/uri/uri/mailto.rb +266 -0
- data/lib/framework/rhodes.rb +2 -2
- data/lib/framework/rhom/rhom_db_adapter.rb +12 -26
- data/lib/framework/rhom/rhom_object_factory.rb +8 -1
- data/lib/framework/version.rb +2 -2
- data/lib/rhodes.rb +2 -2
- data/platform/android/Rhodes/AndroidManifest.xml +2 -2
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +87 -42
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/SplashScreen.java +58 -7
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/MainView.java +2 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/SimpleMainView.java +35 -19
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/TabbedMainView.java +4 -0
- data/platform/android/build/android.rake +30 -25
- data/platform/bb/build/rhodes_build.files +1 -1
- data/platform/bb/rhodes/rhodes.jdp +1 -1
- data/platform/bb/rhodes/src/com/rho/RhoRubyHelper.java +1 -1
- data/platform/bb/rhodes/src/com/rho/rubyext/Alert.java +300 -0
- data/platform/bb/rhodes/src/com/rho/rubyext/GeoLocation.java +42 -5
- data/platform/bb/rhodes/src/rhomobile/PushListeningThread.java +3 -4
- data/platform/bb/rhodes/src/rhomobile/RhodesApplication.java +33 -107
- data/platform/iphone/Classes/RhoRunnerAppDelegate.m +2 -0
- data/platform/iphone/Info.plist +1 -1
- data/platform/iphone/rbuild/iphone.rake +1 -1
- data/platform/iphone/rhoextlib/rhoextlib.xcodeproj/project.pbxproj +4 -0
- data/platform/shared/common/RhoMutexLock.h +8 -1
- data/platform/shared/common/RhodesApp.cpp +1 -1
- data/platform/shared/db/DBAdapter.cpp +77 -8
- data/platform/shared/db/DBAdapter.h +24 -9
- data/platform/shared/db/DBResult.cpp +19 -0
- data/platform/shared/db/DBResult.h +7 -5
- data/platform/shared/net/HttpServer.cpp +2 -0
- data/platform/shared/ruby/ext/rho/rhoruby.c +55 -0
- data/platform/shared/ruby/ext/rho/rhoruby.h +9 -0
- data/platform/shared/ruby/ext/rho/rhosupport.c +13 -4
- data/platform/shared/ruby/ext/sqlite3_api/sqlite3_api_wrap.c +21 -0
- data/platform/shared/ruby/thread_pthread.c +4 -4
- data/platform/shared/ruby/thread_win32.c +4 -4
- data/platform/shared/rubyJVM/src/com/rho/RhodesApp.java +19 -1
- data/platform/shared/rubyJVM/src/com/rho/db/DBAdapter.java +57 -24
- data/platform/shared/rubyJVM/src/com/rho/net/NetRequest.java +6 -1
- data/platform/shared/rubyJVM/src/com/rho/sync/SyncSource.java +2 -2
- data/platform/shared/rubyJVM/src/com/rho/sync/SyncThread.java +5 -5
- data/platform/shared/sync/SyncSource.cpp +1 -1
- data/platform/shared/sync/SyncThread.cpp +6 -9
- data/platform/wm/rhodes/Rhodes.cpp +4 -0
- data/rakefile.rb +1 -1
- metadata +13 -3
- data/platform/bb/rhodes/src/rhomobile/Alert.java +0 -65
@@ -74,7 +74,13 @@ public class SimpleMainView implements MainView {
|
|
74
74
|
reload(0);
|
75
75
|
}
|
76
76
|
};
|
77
|
-
|
77
|
+
|
78
|
+
private class ActionExit implements View.OnClickListener {
|
79
|
+
public void onClick(View v) {
|
80
|
+
Rhodes.exit();
|
81
|
+
}
|
82
|
+
};
|
83
|
+
|
78
84
|
private class ActionCustomRunnable implements Runnable {
|
79
85
|
private boolean callback;
|
80
86
|
private String url;
|
@@ -138,22 +144,11 @@ public class SimpleMainView implements MainView {
|
|
138
144
|
view.addView(bottom);
|
139
145
|
|
140
146
|
if (params != null) {
|
141
|
-
LinearLayout left = new LinearLayout(r);
|
142
|
-
left.setGravity(Gravity.LEFT);
|
143
|
-
left.setOrientation(LinearLayout.HORIZONTAL);
|
144
|
-
left.setLayoutParams(new LinearLayout.LayoutParams(FILL_PARENT, FILL_PARENT, 1));
|
145
|
-
bottom.addView(left);
|
146
|
-
|
147
|
-
LinearLayout right = new LinearLayout(r);
|
148
|
-
right.setGravity(Gravity.RIGHT);
|
149
|
-
right.setOrientation(LinearLayout.HORIZONTAL);
|
150
|
-
right.setLayoutParams(new LinearLayout.LayoutParams(FILL_PARENT, FILL_PARENT, 1));
|
151
|
-
bottom.addView(right);
|
152
|
-
|
153
|
-
LinearLayout current = left;
|
154
|
-
|
155
147
|
String rootPath = r.getRootPath() + "/apps/";
|
156
148
|
|
149
|
+
LinearLayout group = null;
|
150
|
+
// First group should have gravity LEFT
|
151
|
+
int gravity = Gravity.LEFT;
|
157
152
|
for (int i = 0, lim = params.size(); i < lim; ++i) {
|
158
153
|
Object param = params.elementAt(i);
|
159
154
|
if (!(param instanceof Map<?,?>))
|
@@ -193,8 +188,13 @@ public class SimpleMainView implements MainView {
|
|
193
188
|
icon = r.getResources().getDrawable(AndroidR.drawable.refresh);
|
194
189
|
onClick = new ActionRefresh();
|
195
190
|
}
|
191
|
+
else if (action.equalsIgnoreCase("close") || action.equalsIgnoreCase("exit")) {
|
192
|
+
icon = r.getResources().getDrawable(AndroidR.drawable.exit);
|
193
|
+
onClick = new ActionExit();
|
194
|
+
}
|
196
195
|
else if (action.equalsIgnoreCase("separator")) {
|
197
|
-
|
196
|
+
group = null;
|
197
|
+
gravity = Gravity.CENTER;
|
198
198
|
continue;
|
199
199
|
}
|
200
200
|
|
@@ -204,8 +204,9 @@ public class SimpleMainView implements MainView {
|
|
204
204
|
throw new IllegalArgumentException("'icon' should be String");
|
205
205
|
String iconPath = rootPath + (String)iconObj;
|
206
206
|
Bitmap bitmap = BitmapFactory.decodeFile(iconPath);
|
207
|
-
if (bitmap
|
208
|
-
icon
|
207
|
+
if (bitmap == null)
|
208
|
+
throw new IllegalArgumentException("Can't find icon: " + iconPath);
|
209
|
+
icon = new BitmapDrawable(bitmap);
|
209
210
|
}
|
210
211
|
|
211
212
|
if (icon == null) {
|
@@ -238,8 +239,19 @@ public class SimpleMainView implements MainView {
|
|
238
239
|
|
239
240
|
button.setOnClickListener(onClick);
|
240
241
|
button.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
241
|
-
|
242
|
+
if (group == null) {
|
243
|
+
group = new LinearLayout(r);
|
244
|
+
group.setGravity(gravity);
|
245
|
+
group.setOrientation(LinearLayout.HORIZONTAL);
|
246
|
+
group.setLayoutParams(new LinearLayout.LayoutParams(FILL_PARENT, FILL_PARENT, 1));
|
247
|
+
bottom.addView(group);
|
248
|
+
}
|
249
|
+
group.addView(button);
|
242
250
|
}
|
251
|
+
|
252
|
+
// Last group should have gravity RIGHT
|
253
|
+
if (group != null)
|
254
|
+
group.setGravity(Gravity.RIGHT);
|
243
255
|
}
|
244
256
|
}
|
245
257
|
|
@@ -282,5 +294,9 @@ public class SimpleMainView implements MainView {
|
|
282
294
|
public int activeTab() {
|
283
295
|
return 0;
|
284
296
|
}
|
297
|
+
|
298
|
+
public void loadData(String data, int index) {
|
299
|
+
webView.loadData(data, "text/html", "utf-8");
|
300
|
+
}
|
285
301
|
|
286
302
|
}
|
@@ -328,7 +328,7 @@ namespace "build" do
|
|
328
328
|
|
329
329
|
end
|
330
330
|
# desc "Build RhoBundle for android"
|
331
|
-
task :rhobundle => ["config:android","build:bundle:noxruby",:extensions,:librhodes] do
|
331
|
+
task :rhobundle => ["config:android","build:bundle:noxruby",:generate_sources,:extensions,:librhodes] do
|
332
332
|
# Rake::Task["build:bundle:noxruby"].execute
|
333
333
|
|
334
334
|
assets = File.join(Jake.get_absolute($androidpath), "Rhodes", "assets")
|
@@ -345,11 +345,35 @@ namespace "build" do
|
|
345
345
|
File.open(File.join(assets, "name"), "w") { |f| f.write($appname) }
|
346
346
|
end
|
347
347
|
|
348
|
+
task :generate_sources => "config:android" do
|
349
|
+
# Generate gapikey.h
|
350
|
+
gapikey_h = File.join($androidpath, "Rhodes", "jni", "include", "gapikey.h")
|
351
|
+
gapi_defined = false
|
352
|
+
if File.file? gapikey_h
|
353
|
+
File.open(gapikey_h, 'r') do |f|
|
354
|
+
while line = f.gets
|
355
|
+
gapi_defined = true if line =~ /GOOGLE_API_KEY/
|
356
|
+
break if gapi_defined
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
if $use_geomapping != gapi_defined or not File.file? gapikey_h
|
362
|
+
File.open(gapikey_h, 'w') do |f|
|
363
|
+
f.puts "#ifndef RHO_GAPIKEY_H_411BFA4742CF4F2AAA3F6B411ED7514F"
|
364
|
+
f.puts "#define RHO_GAPIKEY_H_411BFA4742CF4F2AAA3F6B411ED7514F"
|
365
|
+
f.puts "#define GOOGLE_API_KEY \"#{$gapikey}\"" if $use_geomapping and !$gapikey.nil?
|
366
|
+
f.puts "#endif /* RHO_GAPIKEY_H_411BFA4742CF4F2AAA3F6B411ED7514F */"
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
348
371
|
task :extensions => "config:android" do
|
349
372
|
|
350
373
|
ENV["ANDROID_NDK"] = $androidndkpath
|
351
374
|
ENV["ANDROID_API_LEVEL"] = ANDROID_API_LEVEL.to_s
|
352
375
|
ENV["TARGET_TEMP_DIR"] = $extensionsdir
|
376
|
+
ENV["RHO_ROOT"] = $startdir
|
353
377
|
ENV["BUILD_DIR"] ||= $startdir + "/platform/android/build"
|
354
378
|
|
355
379
|
mkdir_p $bindir + "/libs/" + $confdir + "/extensions" unless File.exist? $bindir + "/libs/" + $confdir + "/extensions"
|
@@ -370,9 +394,11 @@ namespace "build" do
|
|
370
394
|
extpath = rhoextpath
|
371
395
|
end
|
372
396
|
|
373
|
-
|
374
|
-
|
375
|
-
|
397
|
+
if RUBY_PLATFORM =~ /(win|w)32$/
|
398
|
+
puts Jake.run('build.bat', [], extpath) if File.exists? File.join(extpath, 'build.bat')
|
399
|
+
else
|
400
|
+
puts Jake.run('./build', [], extpath) if File.executable? File.join(extpath, 'build')
|
401
|
+
end
|
376
402
|
exit 1 unless $? == 0
|
377
403
|
|
378
404
|
end
|
@@ -566,27 +592,6 @@ namespace "build" do
|
|
566
592
|
objdir = File.join $rhobindir, $confdir, "librhodes"
|
567
593
|
libname = File.join $bindir, "libs", $confdir, "librhodes.so"
|
568
594
|
|
569
|
-
# Generate gapikey.h
|
570
|
-
gapikey_h = File.join(incdir, 'gapikey.h')
|
571
|
-
gapi_defined = false
|
572
|
-
if File.file? gapikey_h
|
573
|
-
File.open(gapikey_h, 'r') do |f|
|
574
|
-
while line = f.gets
|
575
|
-
gapi_defined = true if line =~ /GOOGLE_API_KEY/
|
576
|
-
break if gapi_defined
|
577
|
-
end
|
578
|
-
end
|
579
|
-
end
|
580
|
-
|
581
|
-
if $use_geomapping != gapi_defined or not File.file? gapikey_h
|
582
|
-
File.open(gapikey_h, 'w') do |f|
|
583
|
-
f.puts "#ifndef RHO_GAPIKEY_H_411BFA4742CF4F2AAA3F6B411ED7514F"
|
584
|
-
f.puts "#define RHO_GAPIKEY_H_411BFA4742CF4F2AAA3F6B411ED7514F"
|
585
|
-
f.puts "#define GOOGLE_API_KEY \"#{$gapikey}\"" if $use_geomapping and !$gapikey.nil?
|
586
|
-
f.puts "#endif /* RHO_GAPIKEY_H_411BFA4742CF4F2AAA3F6B411ED7514F */"
|
587
|
-
end
|
588
|
-
end
|
589
|
-
|
590
595
|
args = []
|
591
596
|
args << "-I#{srcdir}/../include"
|
592
597
|
args << "-I#{$shareddir}"
|
@@ -2,6 +2,7 @@ platform\bb\rhodes\src\com\rho\Jsr75File.java
|
|
2
2
|
platform\bb\rhodes\src\com\rho\rubyext\GeoLocation.java
|
3
3
|
platform\bb\rhodes\src\com\rho\rubyext\System.java
|
4
4
|
platform\bb\rhodes\src\com\rho\rubyext\XMLParser.java
|
5
|
+
platform\bb\rhodes\src\com\rho\rubyext\Alert.java
|
5
6
|
platform\bb\rhodes\src\com\rho\net\BaseSocket.java
|
6
7
|
platform\bb\rhodes\src\com\rho\net\bb\BBHttpConnection.java
|
7
8
|
platform\bb\rhodes\src\com\rho\net\bb\NativeBBHttpConnection.java
|
@@ -22,7 +23,6 @@ platform\bb\rhodes\src\rhomobile\RhoPhonebook.java
|
|
22
23
|
platform\bb\rhodes\src\rhomobile\SecondaryResourceFetchThread.java
|
23
24
|
platform\bb\rhodes\src\rhomobile\Utilities.java
|
24
25
|
platform\bb\rhodes\src\rhomobile\WebView.java
|
25
|
-
platform\bb\rhodes\src\rhomobile\Alert.java
|
26
26
|
platform\bb\rhodes\src\rhomobile\datetime\DateTimePicker.java
|
27
27
|
platform\bb\rhodes\src\rhomobile\datetime\DateTimeScreen.java
|
28
28
|
platform\bb\rhodes\src\rhomobile\RingtoneManager.java
|
@@ -30,6 +30,7 @@ src\com\rho\Jsr75File.java
|
|
30
30
|
src\com\rho\rubyext\GeoLocation.java
|
31
31
|
src\com\rho\rubyext\System.java
|
32
32
|
src\com\rho\rubyext\XMLParser.java
|
33
|
+
src\com\rho\rubyext\Alert.java
|
33
34
|
src\com\rho\net\BaseSocket.java
|
34
35
|
src\com\rho\net\bb\BBHttpConnection.java
|
35
36
|
src\com\rho\net\bb\NativeBBHttpConnection.java
|
@@ -39,7 +40,6 @@ src\com\rho\net\TCPSocket.java
|
|
39
40
|
src\com\rho\RhoMainScreen.java
|
40
41
|
src\com\rho\RhoRubyHelper.java
|
41
42
|
src\com\rho\Version.java
|
42
|
-
src\rhomobile\Alert.java
|
43
43
|
src\rhomobile\camera\Camera.java
|
44
44
|
src\rhomobile\camera\CameraFilesListener.java
|
45
45
|
src\rhomobile\camera\CameraScreen.java
|
@@ -6,7 +6,7 @@ import net.rim.device.api.system.ApplicationDescriptor;
|
|
6
6
|
import net.rim.device.api.system.CodeModuleGroup;
|
7
7
|
import net.rim.device.api.system.DeviceInfo;
|
8
8
|
import net.rim.device.api.io.http.HttpHeaders;
|
9
|
-
import
|
9
|
+
import com.rho.rubyext.Alert;
|
10
10
|
import rhomobile.NativeBar;
|
11
11
|
import rhomobile.RhoPhonebook;
|
12
12
|
import rhomobile.RhodesApplication;
|
@@ -0,0 +1,300 @@
|
|
1
|
+
package com.rho.rubyext;
|
2
|
+
|
3
|
+
import java.io.InputStream;
|
4
|
+
import java.util.Vector;
|
5
|
+
|
6
|
+
import javax.microedition.media.Player;
|
7
|
+
|
8
|
+
import net.rim.device.api.system.Application;
|
9
|
+
import net.rim.device.api.ui.component.Dialog;
|
10
|
+
|
11
|
+
import com.rho.RhoClassFactory;
|
12
|
+
import com.rho.RhoEmptyLogger;
|
13
|
+
import com.rho.RhoLogger;
|
14
|
+
import com.rho.RhodesApp;
|
15
|
+
import com.rho.SimpleFile;
|
16
|
+
import com.xruby.runtime.builtin.*;
|
17
|
+
import com.xruby.runtime.lang.*;
|
18
|
+
|
19
|
+
public class Alert
|
20
|
+
{
|
21
|
+
private static final RhoLogger LOG = RhoLogger.RHO_STRIP_LOG ? new RhoEmptyLogger() :
|
22
|
+
new RhoLogger("Alert");
|
23
|
+
|
24
|
+
public static final RubyID titleID = RubyID.intern("title");
|
25
|
+
public static final RubyID messageID = RubyID.intern("message");
|
26
|
+
public static final RubyID iconID = RubyID.intern("icon");
|
27
|
+
public static final RubyID callbackID = RubyID.intern("callback");
|
28
|
+
public static final RubyID buttonsID = RubyID.intern("buttons");
|
29
|
+
public static final RubyID buttonidID = RubyID.intern("id");
|
30
|
+
|
31
|
+
public static final RubyID alertTypeID = RubyID.intern("alert");
|
32
|
+
public static final RubyID questionTypeID = RubyID.intern("question");
|
33
|
+
public static final RubyID infoTypeID = RubyID.intern("info");
|
34
|
+
|
35
|
+
public static void showPopup(final String message)
|
36
|
+
{
|
37
|
+
Application.getApplication().invokeLater(new Runnable() {
|
38
|
+
public void run() {
|
39
|
+
Application.getApplication().requestForeground();
|
40
|
+
Dialog.alert(message);
|
41
|
+
}
|
42
|
+
});
|
43
|
+
}
|
44
|
+
|
45
|
+
private static String getHashStringValue(RubyHash hash, RubyID id)
|
46
|
+
{
|
47
|
+
RubyValue val = hash.get(id.toSymbol());
|
48
|
+
|
49
|
+
return val != null && val != RubyConstant.QNIL ? val.toStr() : "";
|
50
|
+
}
|
51
|
+
|
52
|
+
private static class PopupHandler implements Runnable
|
53
|
+
{
|
54
|
+
String m_strMessage = "";
|
55
|
+
String m_strCallback = "";
|
56
|
+
Vector m_vecButtons = new Vector();
|
57
|
+
Vector m_vecIDs = new Vector();
|
58
|
+
private static final int atAlert = 1;
|
59
|
+
private static final int atQuestion = 2;
|
60
|
+
private static final int atInfo = 3;
|
61
|
+
int m_nType = 0;
|
62
|
+
|
63
|
+
PopupHandler(RubyHash hash)
|
64
|
+
{
|
65
|
+
m_strMessage = getHashStringValue(hash, messageID );
|
66
|
+
m_strCallback = getHashStringValue(hash, callbackID );
|
67
|
+
|
68
|
+
RubyValue valButtons = hash.get(buttonsID.toSymbol());
|
69
|
+
if ( valButtons != null && valButtons instanceof RubyArray )
|
70
|
+
{
|
71
|
+
RubyArray arButtons = (RubyArray)valButtons;
|
72
|
+
for ( int i = 0; i < arButtons.size(); i++ )
|
73
|
+
{
|
74
|
+
RubyValue valButton = arButtons.get(i);
|
75
|
+
if ( valButton != null && valButton instanceof RubyString )
|
76
|
+
{
|
77
|
+
m_vecButtons.addElement(valButton.toStr());
|
78
|
+
m_vecIDs.addElement(valButton.toStr());
|
79
|
+
}else if ( valButton != null && valButton instanceof RubyHash )
|
80
|
+
{
|
81
|
+
String strLabel = getHashStringValue((RubyHash)valButton, titleID );
|
82
|
+
if ( strLabel.length() > 0 )
|
83
|
+
{
|
84
|
+
m_vecButtons.addElement(strLabel);
|
85
|
+
String strID = getHashStringValue((RubyHash)valButton, buttonidID );
|
86
|
+
if ( strID.length() > 0 )
|
87
|
+
m_vecIDs.addElement(strID);
|
88
|
+
else
|
89
|
+
m_vecIDs.addElement(strLabel);
|
90
|
+
}
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
RubyValue valIcon = hash.get(iconID.toSymbol());
|
96
|
+
if ( valIcon instanceof RubySymbol )
|
97
|
+
{
|
98
|
+
if ( valIcon == alertTypeID.toSymbol() )
|
99
|
+
m_nType = atAlert;
|
100
|
+
else if( valIcon == questionTypeID.toSymbol() )
|
101
|
+
m_nType = atQuestion;
|
102
|
+
else if( valIcon == infoTypeID.toSymbol() )
|
103
|
+
m_nType = atInfo;
|
104
|
+
|
105
|
+
}else
|
106
|
+
{
|
107
|
+
if (m_vecButtons.size() > 0 )
|
108
|
+
m_nType = atQuestion;
|
109
|
+
else
|
110
|
+
m_nType = atInfo;
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
public void run() {
|
115
|
+
Application.getApplication().requestForeground();
|
116
|
+
|
117
|
+
switch( m_nType )
|
118
|
+
{
|
119
|
+
case atAlert:
|
120
|
+
Dialog.alert(m_strMessage);
|
121
|
+
break;
|
122
|
+
case atQuestion:
|
123
|
+
Object[] btns = new Object[m_vecButtons.size()];
|
124
|
+
m_vecButtons.copyInto(btns);
|
125
|
+
int nRes = Dialog.ask(m_strMessage,btns,0);
|
126
|
+
|
127
|
+
try
|
128
|
+
{
|
129
|
+
RhodesApp.getInstance().callPopupCallback(m_strCallback, (String)m_vecIDs.elementAt(nRes),
|
130
|
+
(String)m_vecButtons.elementAt(nRes));
|
131
|
+
}catch(Exception exc)
|
132
|
+
{
|
133
|
+
LOG.ERROR("show_popup callback failed.", exc);
|
134
|
+
}
|
135
|
+
break;
|
136
|
+
case atInfo:
|
137
|
+
Dialog.inform(m_strMessage);
|
138
|
+
break;
|
139
|
+
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
}
|
144
|
+
|
145
|
+
public static void vibrate(final String duration)
|
146
|
+
{
|
147
|
+
Application.getApplication().invokeLater(new Runnable() {
|
148
|
+
public void run() {
|
149
|
+
int dt = 2500;
|
150
|
+
try {
|
151
|
+
dt = Integer.parseInt(duration);
|
152
|
+
} catch (NumberFormatException e) {
|
153
|
+
}
|
154
|
+
|
155
|
+
if (dt > 25500) dt = 25500;
|
156
|
+
|
157
|
+
if (dt > 0) {
|
158
|
+
net.rim.device.api.system.Alert.startVibrate(dt);
|
159
|
+
}
|
160
|
+
}
|
161
|
+
});
|
162
|
+
}
|
163
|
+
|
164
|
+
private static final String[][] filetypes = { {"mp3", "audio/mpeg"}, {"wav","audio/x-wav"} };
|
165
|
+
private static String getTypeFromExt(String file_name) {
|
166
|
+
int pt = file_name.lastIndexOf('.');
|
167
|
+
if (pt<0) {
|
168
|
+
return filetypes[0][1];
|
169
|
+
}
|
170
|
+
String ext = file_name.substring(pt+1);
|
171
|
+
for (int cnt = filetypes.length - 1; cnt >= 0; --cnt) {
|
172
|
+
if(filetypes[cnt][0].equals(ext)) {
|
173
|
+
return filetypes[cnt][1];
|
174
|
+
}
|
175
|
+
}
|
176
|
+
return null;
|
177
|
+
}
|
178
|
+
|
179
|
+
public static void play_file(final String file_name, final String media_type)
|
180
|
+
{
|
181
|
+
Application.getApplication().invokeLater(new Runnable()
|
182
|
+
{
|
183
|
+
public void run() {
|
184
|
+
String type = media_type == null ? getTypeFromExt(file_name) : media_type;
|
185
|
+
if (type != null) {
|
186
|
+
LOG.INFO("File type: " + type);
|
187
|
+
} else {
|
188
|
+
LOG.ERROR("Error - can't play unknown file type");
|
189
|
+
return;
|
190
|
+
}
|
191
|
+
|
192
|
+
String types[] =
|
193
|
+
javax.microedition.media.Manager.getSupportedContentTypes(null);
|
194
|
+
for (int cnt = types.length - 1; cnt >= 0; --cnt) {
|
195
|
+
if (type.equals(types[cnt])) {
|
196
|
+
LOG.INFO( "Playing file " + file_name + " of type: " + types[cnt]);
|
197
|
+
|
198
|
+
SimpleFile file = null;
|
199
|
+
try {
|
200
|
+
//retrieve the file
|
201
|
+
Class clazz = Class.forName("rhomobile.RhodesApplication");
|
202
|
+
file = RhoClassFactory.createFile();
|
203
|
+
String strClassName = file_name;
|
204
|
+
if ( !strClassName.startsWith("/apps") )
|
205
|
+
strClassName = "/apps" + file_name;
|
206
|
+
|
207
|
+
InputStream is = file.getResourceAsStream(clazz.getClass(), strClassName);
|
208
|
+
//create an instance of the player from the InputStream
|
209
|
+
Player player = javax.microedition.media.Manager.createPlayer(is,type);
|
210
|
+
player.realize();
|
211
|
+
player.prefetch();
|
212
|
+
//start the player
|
213
|
+
player.start();
|
214
|
+
} catch (Exception ex) {
|
215
|
+
LOG.ERROR("Error playing " + file_name + " :" + ex.getMessage());
|
216
|
+
} finally {
|
217
|
+
try{
|
218
|
+
if ( file != null )
|
219
|
+
file.close();
|
220
|
+
}catch(Exception exc){}
|
221
|
+
}
|
222
|
+
return;
|
223
|
+
}
|
224
|
+
}
|
225
|
+
|
226
|
+
LOG.ERROR("Error - media type " + type + " isn't supported.");
|
227
|
+
}
|
228
|
+
});
|
229
|
+
}
|
230
|
+
|
231
|
+
public static void initMethods(RubyClass klass) {
|
232
|
+
klass.getSingletonClass().defineMethod("show_popup", new RubyOneArgMethod()
|
233
|
+
{
|
234
|
+
protected RubyValue run(RubyValue receiver, RubyValue arg0, RubyBlock block)
|
235
|
+
{
|
236
|
+
try {
|
237
|
+
if ( arg0 instanceof RubyString )
|
238
|
+
{
|
239
|
+
String message = arg0.toString();
|
240
|
+
Alert.showPopup(message);
|
241
|
+
}else if ( arg0 instanceof RubyHash)
|
242
|
+
{
|
243
|
+
PopupHandler handler = new PopupHandler((RubyHash)arg0);
|
244
|
+
Application.getApplication().invokeLater(handler);
|
245
|
+
}
|
246
|
+
else
|
247
|
+
throw new RubyException(RubyRuntime.ArgumentErrorClass, "in Alert.show_popup: wrong argument type.Should be String or Hash");
|
248
|
+
|
249
|
+
return RubyConstant.QNIL;
|
250
|
+
} catch(Exception e) {
|
251
|
+
LOG.ERROR("show_popup failed", e);
|
252
|
+
throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
|
253
|
+
}
|
254
|
+
|
255
|
+
}
|
256
|
+
});
|
257
|
+
klass.getSingletonClass().defineMethod("vibrate", new RubyVarArgMethod() {
|
258
|
+
protected RubyValue run(RubyValue receiver, RubyArray args, RubyBlock block)
|
259
|
+
{
|
260
|
+
if ( args != null && args.size() > 1 )
|
261
|
+
throw new RubyException(RubyRuntime.ArgumentErrorClass,
|
262
|
+
"in Alert.vibrate: wrong number of arguments ( " + args.size() + " for " + 1 + " )");
|
263
|
+
|
264
|
+
try {
|
265
|
+
String duration = "2500";
|
266
|
+
if ((args != null) && (args.size() > 0))
|
267
|
+
duration = args.get(0).toString();
|
268
|
+
Alert.vibrate(duration);
|
269
|
+
|
270
|
+
return RubyConstant.QNIL;
|
271
|
+
} catch(Exception e) {
|
272
|
+
LOG.ERROR("vibrate failed", e);
|
273
|
+
throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
|
274
|
+
}
|
275
|
+
}
|
276
|
+
});
|
277
|
+
klass.getSingletonClass().defineMethod("play_file", new RubyVarArgMethod() {
|
278
|
+
protected RubyValue run(RubyValue receiver, RubyArray args, RubyBlock block)
|
279
|
+
{
|
280
|
+
if ( args.size() < 1 || args.size() > 2 )
|
281
|
+
throw new RubyException(RubyRuntime.ArgumentErrorClass,
|
282
|
+
"in Alert.play_file: wrong number of arguments ( " + args.size() + " for " + 2 + " )");
|
283
|
+
|
284
|
+
try {
|
285
|
+
String file_name = args.get(0).toString();
|
286
|
+
String media_type = null;
|
287
|
+
if ((args.size() > 1) && (args.get(1) != RubyConstant.QNIL))
|
288
|
+
media_type = args.get(1).toString();
|
289
|
+
Alert.play_file(file_name,media_type);
|
290
|
+
|
291
|
+
return RubyConstant.QNIL;
|
292
|
+
} catch(Exception e) {
|
293
|
+
LOG.ERROR("play_file failed", e);
|
294
|
+
throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
|
295
|
+
}
|
296
|
+
}
|
297
|
+
});
|
298
|
+
}
|
299
|
+
|
300
|
+
}
|