rhodes 1.5.4 → 1.5.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|