ruboto 0.11.0 → 0.12.0.rc.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +7 -5
- data/Rakefile +3 -4
- data/assets/rakelib/ruboto.rake +138 -87
- data/assets/samples/sample_broadcast_receiver.rb +1 -1
- data/assets/src/InheritingActivity.java +0 -6
- data/assets/src/RubotoActivity.java +4 -1
- data/assets/src/RubotoBroadcastReceiver.java +2 -11
- data/assets/src/RubotoService.java +6 -52
- data/assets/src/org/ruboto/EntryPointActivity.java +276 -36
- data/assets/src/org/ruboto/JRubyAdapter.java +5 -152
- data/assets/src/org/ruboto/Script.java +1 -1
- data/assets/src/org/ruboto/ScriptLoader.java +26 -44
- data/assets/src/org/ruboto/test/InstrumentationTestRunner.java +4 -21
- data/bin/ruboto +0 -6
- data/lib/ruboto/commands/base.rb +58 -48
- data/lib/ruboto/sdk_locations.rb +23 -0
- data/lib/ruboto/sdk_versions.rb +1 -19
- data/lib/ruboto/util/build.rb +32 -32
- data/lib/ruboto/util/setup.rb +240 -0
- data/lib/ruboto/util/update.rb +12 -25
- data/lib/ruboto/util/verify.rb +7 -4
- data/lib/ruboto/util/xml_element.rb +62 -76
- data/lib/ruboto/version.rb +1 -1
- data/test/activity/image_button_activity_test.rb +2 -2
- data/test/activity/image_button_and_button_activity_test.rb +2 -2
- data/test/activity/json_activity.rb +1 -1
- data/test/activity/navigation_activity.rb +12 -12
- data/test/activity/navigation_activity_test.rb +7 -7
- data/test/activity/option_menu_activity.rb +0 -1
- data/test/activity/option_menu_activity_test.rb +2 -2
- data/test/activity/stack_activity_test.rb +10 -20
- data/test/app_test_methods.rb +0 -4
- data/test/broadcast_receiver_test.rb +16 -6
- data/test/minimal_app_test.rb +4 -12
- data/test/rake_test.rb +37 -23
- data/test/ruboto_gen_test.rb +12 -15
- data/test/sqldroid_test.rb +3 -6
- data/test/test_helper.rb +2 -0
- data/test/update_test_methods.rb +9 -9
- metadata +7 -11
@@ -1,10 +1,4 @@
|
|
1
1
|
package THE_PACKAGE;
|
2
2
|
|
3
|
-
import android.os.Bundle;
|
4
|
-
|
5
3
|
public class InheritingActivity extends org.ruboto.EntryPointActivity {
|
6
|
-
public void onCreate(Bundle bundle) {
|
7
|
-
getScriptInfo().setRubyClassName(getClass().getSimpleName());
|
8
|
-
super.onCreate(bundle);
|
9
|
-
}
|
10
4
|
}
|
@@ -48,15 +48,18 @@ public class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
|
|
48
48
|
}
|
49
49
|
|
50
50
|
if (JRubyAdapter.isInitialized() && scriptInfo.isReadyToLoad()) {
|
51
|
-
ScriptLoader.loadScript(this
|
51
|
+
ScriptLoader.loadScript(this);
|
52
|
+
ScriptLoader.callOnCreate(this, (Object[]) args);
|
52
53
|
} else {
|
53
54
|
super.onCreate(bundle);
|
54
55
|
}
|
55
56
|
}
|
56
57
|
|
58
|
+
// FIXME(uwe): What is this for?
|
57
59
|
public boolean rubotoAttachable() {
|
58
60
|
return true;
|
59
61
|
}
|
62
|
+
// EMXIF
|
60
63
|
|
61
64
|
/****************************************************************************************
|
62
65
|
*
|
@@ -30,7 +30,7 @@ public class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
|
|
30
30
|
|
31
31
|
public void onReceive(android.content.Context context, android.content.Intent intent) {
|
32
32
|
try {
|
33
|
-
Log.d("onReceive: " + this);
|
33
|
+
Log.d("onReceive: " + this + " " + ScriptLoader.isCalledFromJRuby() + " " + scriptLoaded);
|
34
34
|
if (ScriptLoader.isCalledFromJRuby()) {
|
35
35
|
return;
|
36
36
|
}
|
@@ -43,23 +43,14 @@ public class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
|
|
43
43
|
}
|
44
44
|
}
|
45
45
|
|
46
|
-
// FIXME(uwe): Simplify when we stop supporting JRuby 1.6.x
|
47
|
-
if (JRubyAdapter.isJRubyPreOneSeven()) {
|
48
|
-
JRubyAdapter.put("$broadcast_receiver", this);
|
49
|
-
JRubyAdapter.put("$context", context);
|
50
|
-
JRubyAdapter.put("$intent", intent);
|
51
|
-
JRubyAdapter.runScriptlet("$broadcast_receiver.on_receive($context, $intent)");
|
52
|
-
} else if (JRubyAdapter.isJRubyOneSeven()) {
|
53
46
|
// FIXME(uwe): Simplify when we stop support for snake case aliasing interface callback methods.
|
54
47
|
if ((Boolean)JRubyAdapter.runScriptlet(scriptInfo.getRubyClassName() + ".instance_methods(false).any?{|m| m.to_sym == :onReceive}")) {
|
48
|
+
Log.d("onReceive: call method");
|
55
49
|
JRubyAdapter.runRubyMethod(this, "onReceive", new Object[]{context, intent});
|
56
50
|
} else if ((Boolean)JRubyAdapter.runScriptlet(scriptInfo.getRubyClassName() + ".instance_methods(false).any?{|m| m.to_sym == :on_receive}")) {
|
57
51
|
JRubyAdapter.runRubyMethod(this, "on_receive", new Object[]{context, intent});
|
58
52
|
}
|
59
53
|
// EMXIF
|
60
|
-
} else {
|
61
|
-
throw new RuntimeException("Unknown JRuby version: " + JRubyAdapter.get("JRUBY_VERSION"));
|
62
|
-
}
|
63
54
|
} catch(Exception e) {
|
64
55
|
e.printStackTrace();
|
65
56
|
}
|
@@ -31,6 +31,7 @@ public class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
|
|
31
31
|
}
|
32
32
|
}
|
33
33
|
|
34
|
+
// FIXME(uwe): Revert to generate these methods.
|
34
35
|
@Override
|
35
36
|
public int onStartCommand(android.content.Intent intent, int flags, int startId) {
|
36
37
|
if (ScriptLoader.isCalledFromJRuby()) return super.onStartCommand(intent, flags, startId);
|
@@ -48,42 +49,17 @@ public class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
|
|
48
49
|
String rubyClassName = scriptInfo.getRubyClassName();
|
49
50
|
if (rubyClassName == null) return super.onStartCommand(intent, flags, startId);
|
50
51
|
if ((Boolean)JRubyAdapter.runScriptlet(rubyClassName + ".instance_methods(false).any?{|m| m.to_sym == :on_start_command}")) {
|
51
|
-
|
52
|
-
if (JRubyAdapter.isJRubyPreOneSeven()) {
|
53
|
-
JRubyAdapter.put("$arg_intent", intent);
|
54
|
-
JRubyAdapter.put("$arg_flags", flags);
|
55
|
-
JRubyAdapter.put("$arg_startId", startId);
|
56
|
-
JRubyAdapter.put("$ruby_instance", scriptInfo.getRubyInstance());
|
57
|
-
return (Integer) ((Number)JRubyAdapter.runScriptlet("$ruby_instance.on_start_command($arg_intent, $arg_flags, $arg_startId)")).intValue();
|
52
|
+
return (Integer) JRubyAdapter.runRubyMethod(Integer.class, scriptInfo.getRubyInstance(), "on_start_command", new Object[]{intent, flags, startId});
|
58
53
|
} else {
|
59
|
-
if (JRubyAdapter.isJRubyOneSeven()) {
|
60
|
-
return (Integer) JRubyAdapter.runRubyMethod(Integer.class, scriptInfo.getRubyInstance(), "on_start_command", new Object[]{intent, flags, startId});
|
61
|
-
} else {
|
62
|
-
throw new RuntimeException("Unknown JRuby version: " + JRubyAdapter.get("JRUBY_VERSION"));
|
63
|
-
}
|
64
|
-
}
|
65
|
-
} else {
|
66
54
|
if ((Boolean)JRubyAdapter.runScriptlet(rubyClassName + ".instance_methods(false).any?{|m| m.to_sym == :onStartCommand}")) {
|
67
|
-
|
68
|
-
if (JRubyAdapter.isJRubyPreOneSeven()) {
|
69
|
-
JRubyAdapter.put("$arg_intent", intent);
|
70
|
-
JRubyAdapter.put("$arg_flags", flags);
|
71
|
-
JRubyAdapter.put("$arg_startId", startId);
|
72
|
-
JRubyAdapter.put("$ruby_instance", scriptInfo.getRubyInstance());
|
73
|
-
return (Integer) ((Number)JRubyAdapter.runScriptlet("$ruby_instance.onStartCommand($arg_intent, $arg_flags, $arg_startId)")).intValue();
|
74
|
-
} else {
|
75
|
-
if (JRubyAdapter.isJRubyOneSeven()) {
|
76
|
-
return (Integer) JRubyAdapter.runRubyMethod(Integer.class, scriptInfo.getRubyInstance(), "onStartCommand", new Object[]{intent, flags, startId});
|
77
|
-
} else {
|
78
|
-
throw new RuntimeException("Unknown JRuby version: " + JRubyAdapter.get("JRUBY_VERSION"));
|
79
|
-
}
|
80
|
-
}
|
55
|
+
return (Integer) JRubyAdapter.runRubyMethod(Integer.class, scriptInfo.getRubyInstance(), "onStartCommand", new Object[]{intent, flags, startId});
|
81
56
|
} else {
|
82
57
|
return super.onStartCommand(intent, flags, startId);
|
83
58
|
}
|
84
59
|
}
|
85
60
|
}
|
86
61
|
|
62
|
+
// FIXME(uwe): Revert to generate these methods.
|
87
63
|
@Override
|
88
64
|
public android.os.IBinder onBind(android.content.Intent intent) {
|
89
65
|
if (ScriptLoader.isCalledFromJRuby()) return null;
|
@@ -100,32 +76,10 @@ public class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
|
|
100
76
|
String rubyClassName = scriptInfo.getRubyClassName();
|
101
77
|
if (rubyClassName == null) return null;
|
102
78
|
if ((Boolean)JRubyAdapter.runScriptlet(rubyClassName + ".instance_methods(false).any?{|m| m.to_sym == :on_bind}")) {
|
103
|
-
|
104
|
-
if (JRubyAdapter.isJRubyPreOneSeven()) {
|
105
|
-
JRubyAdapter.put("$arg_intent", intent);
|
106
|
-
JRubyAdapter.put("$ruby_instance", scriptInfo.getRubyInstance());
|
107
|
-
return (android.os.IBinder) JRubyAdapter.runScriptlet("$ruby_instance.on_bind($arg_intent)");
|
108
|
-
} else {
|
109
|
-
if (JRubyAdapter.isJRubyOneSeven()) {
|
110
|
-
return (android.os.IBinder) JRubyAdapter.runRubyMethod(android.os.IBinder.class, scriptInfo.getRubyInstance(), "on_bind", intent);
|
111
|
-
} else {
|
112
|
-
throw new RuntimeException("Unknown JRuby version: " + JRubyAdapter.get("JRUBY_VERSION"));
|
113
|
-
}
|
114
|
-
}
|
79
|
+
return (android.os.IBinder) JRubyAdapter.runRubyMethod(android.os.IBinder.class, scriptInfo.getRubyInstance(), "on_bind", intent);
|
115
80
|
} else {
|
116
81
|
if ((Boolean)JRubyAdapter.runScriptlet(rubyClassName + ".instance_methods(false).any?{|m| m.to_sym == :onBind}")) {
|
117
|
-
|
118
|
-
if (JRubyAdapter.isJRubyPreOneSeven()) {
|
119
|
-
JRubyAdapter.put("$arg_intent", intent);
|
120
|
-
JRubyAdapter.put("$ruby_instance", scriptInfo.getRubyInstance());
|
121
|
-
return (android.os.IBinder) JRubyAdapter.runScriptlet("$ruby_instance.onBind($arg_intent)");
|
122
|
-
} else {
|
123
|
-
if (JRubyAdapter.isJRubyOneSeven()) {
|
124
|
-
return (android.os.IBinder) JRubyAdapter.runRubyMethod(android.os.IBinder.class, scriptInfo.getRubyInstance(), "onBind", intent);
|
125
|
-
} else {
|
126
|
-
throw new RuntimeException("Unknown JRuby version: " + JRubyAdapter.get("JRUBY_VERSION"));
|
127
|
-
}
|
128
|
-
}
|
82
|
+
return (android.os.IBinder) JRubyAdapter.runRubyMethod(android.os.IBinder.class, scriptInfo.getRubyInstance(), "onBind", intent);
|
129
83
|
} else {
|
130
84
|
return null;
|
131
85
|
}
|
@@ -1,5 +1,8 @@
|
|
1
1
|
package org.ruboto;
|
2
2
|
|
3
|
+
import android.app.DownloadManager;
|
4
|
+
import android.app.DownloadManager.Query;
|
5
|
+
import android.app.DownloadManager.Request;
|
3
6
|
import android.app.ProgressDialog;
|
4
7
|
import android.content.BroadcastReceiver;
|
5
8
|
import android.content.Context;
|
@@ -7,25 +10,40 @@ import android.content.DialogInterface;
|
|
7
10
|
import android.content.DialogInterface.OnCancelListener;
|
8
11
|
import android.content.Intent;
|
9
12
|
import android.content.IntentFilter;
|
13
|
+
import android.content.pm.PackageManager;
|
14
|
+
import android.database.Cursor;
|
10
15
|
import android.net.Uri;
|
11
16
|
import android.os.Bundle;
|
17
|
+
import android.provider.Settings;
|
12
18
|
import android.view.View;
|
13
19
|
import android.widget.TextView;
|
14
20
|
import android.widget.Toast;
|
15
21
|
|
22
|
+
/**
|
23
|
+
* This Activity acts as an entry point to the app. It must initialize the
|
24
|
+
* JRuby runtime before continuing its life cycle.
|
25
|
+
* While JRuby is initializing, a progress dialog is shown.
|
26
|
+
* If R.layout.splash is defined, by adding a res/layout/splash.xml file,
|
27
|
+
* this layout is displayed instead of the progress dialog.
|
28
|
+
*/
|
16
29
|
public class EntryPointActivity extends org.ruboto.RubotoActivity {
|
17
30
|
private int splash = 0;
|
18
31
|
private ProgressDialog loadingDialog;
|
19
32
|
private boolean dialogCancelled = false;
|
20
33
|
private BroadcastReceiver receiver;
|
34
|
+
private long enqueue;
|
35
|
+
java.io.File localFile;
|
36
|
+
private static final int INSTALL_REQUEST_CODE = 4242;
|
21
37
|
|
22
38
|
// FIXME(uwe): Remove this field? Duplicated by ScriptInfo.isLoaded() ?
|
23
39
|
protected boolean appStarted = false;
|
24
40
|
// EMXIF
|
25
41
|
|
26
42
|
public void onCreate(Bundle bundle) {
|
27
|
-
Log.d("onCreate:
|
43
|
+
Log.d("EntryPointActivity onCreate:");
|
44
|
+
getScriptInfo().setRubyClassName(getClass().getSimpleName());
|
28
45
|
|
46
|
+
localFile = new java.io.File(getFilesDir(), RUBOTO_APK);
|
29
47
|
try {
|
30
48
|
splash = Class.forName(getPackageName() + ".R$layout").getField("splash").getInt(null);
|
31
49
|
} catch (Exception e) {
|
@@ -34,6 +52,8 @@ public class EntryPointActivity extends org.ruboto.RubotoActivity {
|
|
34
52
|
|
35
53
|
if (JRubyAdapter.isInitialized()) {
|
36
54
|
appStarted = true;
|
55
|
+
} else {
|
56
|
+
initJRuby(true);
|
37
57
|
}
|
38
58
|
super.onCreate(bundle);
|
39
59
|
}
|
@@ -53,27 +73,8 @@ public class EntryPointActivity extends org.ruboto.RubotoActivity {
|
|
53
73
|
fireRubotoActivity();
|
54
74
|
} else {
|
55
75
|
Log.d("Not initialized");
|
56
|
-
showProgress();
|
57
|
-
receiver = new BroadcastReceiver(){
|
58
|
-
public void onReceive(Context context, Intent intent) {
|
59
|
-
Log.i("received broadcast: " + intent);
|
60
|
-
Log.i("URI: " + intent.getData());
|
61
|
-
if (intent.getData().toString().equals("package:org.ruboto.core")) {
|
62
|
-
Toast.makeText(context,"Ruboto Core is now installed.",Toast.LENGTH_SHORT).show();
|
63
|
-
if (receiver != null) {
|
64
|
-
unregisterReceiver(receiver);
|
65
|
-
receiver = null;
|
66
|
-
}
|
67
|
-
showProgress();
|
68
|
-
initJRuby(false);
|
69
|
-
}
|
70
|
-
}
|
71
|
-
};
|
72
|
-
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
|
73
|
-
filter.addDataScheme("package");
|
74
|
-
registerReceiver(receiver, filter);
|
75
|
-
initJRuby(true);
|
76
76
|
super.onResume();
|
77
|
+
initJRuby(true);
|
77
78
|
}
|
78
79
|
}
|
79
80
|
|
@@ -98,33 +99,39 @@ public class EntryPointActivity extends org.ruboto.RubotoActivity {
|
|
98
99
|
}
|
99
100
|
|
100
101
|
private void initJRuby(final boolean firstTime) {
|
102
|
+
showProgress();
|
101
103
|
new Thread(new Runnable() {
|
102
104
|
public void run() {
|
103
105
|
final boolean jrubyOk = JRubyAdapter.setUpJRuby(EntryPointActivity.this);
|
104
106
|
if (jrubyOk) {
|
105
107
|
Log.d("onResume: JRuby OK");
|
106
|
-
|
107
|
-
public void run() {
|
108
|
-
fireRubotoActivity();
|
109
|
-
}
|
110
|
-
});
|
108
|
+
fireRubotoActivity();
|
111
109
|
} else {
|
110
|
+
registerPackageInstallReceiver();
|
112
111
|
runOnUiThread(new Runnable() {
|
113
112
|
public void run() {
|
113
|
+
if (localFile.exists()) {
|
114
|
+
installDownload();
|
115
|
+
} else {
|
114
116
|
if (firstTime) {
|
115
117
|
Log.d("onResume: Checking JRuby - IN UI thread");
|
116
118
|
try {
|
117
119
|
setContentView(Class.forName(getPackageName() + ".R$layout").getField("get_ruboto_core").getInt(null));
|
120
|
+
if (hasInternetPermission()) {
|
121
|
+
getRubotoCore(null);
|
122
|
+
return;
|
123
|
+
}
|
118
124
|
} catch (Exception e) {
|
119
125
|
}
|
120
126
|
} else {
|
121
|
-
Toast.makeText(EntryPointActivity.this,"Failed to initialize Ruboto Core.",Toast.
|
127
|
+
Toast.makeText(EntryPointActivity.this,"Failed to initialize Ruboto Core.",Toast.LENGTH_LONG).show();
|
122
128
|
try {
|
123
129
|
TextView textView = (TextView) findViewById(Class.forName(getPackageName() + ".R$id").getField("text").getInt(null));
|
124
130
|
textView.setText("Woops! Ruboto Core was installed, but it failed to initialize properly! I am not sure how to proceed from here. If you can, please file an error report at http://ruboto.org/");
|
125
131
|
} catch (Exception e) {
|
126
132
|
}
|
127
133
|
}
|
134
|
+
}
|
128
135
|
hideProgress();
|
129
136
|
}
|
130
137
|
});
|
@@ -134,17 +141,42 @@ public class EntryPointActivity extends org.ruboto.RubotoActivity {
|
|
134
141
|
}
|
135
142
|
|
136
143
|
private static final String RUBOTO_APK = "RubotoCore-release.apk";
|
137
|
-
private static final String RUBOTO_URL = "
|
144
|
+
private static final String RUBOTO_URL = "http://ruboto.org/downloads/" + RUBOTO_APK;
|
138
145
|
|
139
146
|
// Called when the button is pressed.
|
140
147
|
public void getRubotoCore(View view) {
|
148
|
+
try {
|
149
|
+
if (hasInternetPermission() && canInstallFromUnknownSources()) {
|
150
|
+
if (enqueue <= 0) {
|
151
|
+
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
|
152
|
+
Request request = new Request(Uri.parse(RUBOTO_URL));
|
153
|
+
enqueue = dm.enqueue(request);
|
154
|
+
hideProgress();
|
155
|
+
showDownloadProgress("Downloading RubotoCore...");
|
156
|
+
new Thread(new Runnable() {
|
157
|
+
public void run() {
|
158
|
+
while (loadingDialog != null && enqueue > 0) {
|
159
|
+
// FIXME(uwe): Also set total bytes and bytes downloaded.
|
160
|
+
loadingDialog.setProgress(getProgressPercentage());
|
161
|
+
try {
|
162
|
+
Thread.sleep(1000);
|
163
|
+
} catch (InterruptedException ie) {
|
164
|
+
Log.e("Interupted!");
|
165
|
+
}
|
166
|
+
}
|
167
|
+
}
|
168
|
+
}).start();
|
169
|
+
}
|
170
|
+
return;
|
171
|
+
}
|
172
|
+
} catch (Exception e) {
|
173
|
+
Log.e("Exception in direct RubotoCore download: " + e);
|
174
|
+
}
|
141
175
|
try {
|
142
176
|
startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("market://details?id=org.ruboto.core")));
|
143
177
|
} catch (android.content.ActivityNotFoundException anfe) {
|
144
|
-
|
145
|
-
|
146
|
-
startActivity(intent);
|
147
|
-
} catch (Exception e) {}
|
178
|
+
Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(RUBOTO_URL));
|
179
|
+
startActivity(intent);
|
148
180
|
}
|
149
181
|
}
|
150
182
|
|
@@ -152,10 +184,15 @@ public class EntryPointActivity extends org.ruboto.RubotoActivity {
|
|
152
184
|
if(appStarted) return;
|
153
185
|
appStarted = true;
|
154
186
|
Log.i("Starting activity");
|
155
|
-
ScriptLoader.loadScript(this
|
156
|
-
|
157
|
-
|
158
|
-
|
187
|
+
ScriptLoader.loadScript(this);
|
188
|
+
runOnUiThread(new Runnable() {
|
189
|
+
public void run() {
|
190
|
+
ScriptLoader.callOnCreate(EntryPointActivity.this, args[0]);
|
191
|
+
onStart();
|
192
|
+
onResume();
|
193
|
+
hideProgress();
|
194
|
+
}
|
195
|
+
});
|
159
196
|
}
|
160
197
|
|
161
198
|
private void showProgress() {
|
@@ -178,6 +215,35 @@ public class EntryPointActivity extends org.ruboto.RubotoActivity {
|
|
178
215
|
}
|
179
216
|
}
|
180
217
|
|
218
|
+
private void showDownloadProgress(String message) {
|
219
|
+
if (loadingDialog == null) {
|
220
|
+
if (splash > 0) {
|
221
|
+
Log.i("Showing splash");
|
222
|
+
requestWindowFeature(android.view.Window.FEATURE_NO_TITLE);
|
223
|
+
setContentView(splash);
|
224
|
+
} else {
|
225
|
+
Log.i("Showing progress");
|
226
|
+
loadingDialog = new ProgressDialog(this);
|
227
|
+
loadingDialog.setTitle(null);
|
228
|
+
loadingDialog.setMessage(message);
|
229
|
+
loadingDialog.setIndeterminate(false);
|
230
|
+
loadingDialog.setMax(100);
|
231
|
+
loadingDialog.setProgressStyle(android.app.ProgressDialog.STYLE_HORIZONTAL);
|
232
|
+
loadingDialog.setCancelable(true);
|
233
|
+
loadingDialog.setCanceledOnTouchOutside(false);
|
234
|
+
loadingDialog.setOnCancelListener(new OnCancelListener() {
|
235
|
+
public void onCancel(DialogInterface dialog) {
|
236
|
+
dialogCancelled = true;
|
237
|
+
finish();
|
238
|
+
}
|
239
|
+
});
|
240
|
+
loadingDialog.show();
|
241
|
+
}
|
242
|
+
} else {
|
243
|
+
loadingDialog.setMessage(message);
|
244
|
+
}
|
245
|
+
}
|
246
|
+
|
181
247
|
private void hideProgress() {
|
182
248
|
if (loadingDialog != null) {
|
183
249
|
Log.d("Hide progress");
|
@@ -186,4 +252,178 @@ public class EntryPointActivity extends org.ruboto.RubotoActivity {
|
|
186
252
|
}
|
187
253
|
}
|
188
254
|
|
255
|
+
private void registerPackageInstallReceiver() {
|
256
|
+
receiver = new BroadcastReceiver(){
|
257
|
+
public void onReceive(Context context, Intent intent) {
|
258
|
+
Log.d("Received intent: " + intent + " (" + intent.getExtras() + ")");
|
259
|
+
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
|
260
|
+
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
|
261
|
+
if (downloadId == enqueue) {
|
262
|
+
if (localFile.exists()) {
|
263
|
+
return;
|
264
|
+
}
|
265
|
+
Query query = new Query();
|
266
|
+
query.setFilterById(enqueue);
|
267
|
+
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
|
268
|
+
Cursor c = dm.query(query);
|
269
|
+
if (c.moveToFirst()) {
|
270
|
+
hideProgress();
|
271
|
+
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
|
272
|
+
if (DownloadManager.STATUS_SUCCESSFUL == status) {
|
273
|
+
storeDownload(dm, downloadId);
|
274
|
+
installDownload();
|
275
|
+
} else {
|
276
|
+
int reason = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_REASON));
|
277
|
+
Toast.makeText(context,"Download failed (" + status + "): " + reason, Toast.LENGTH_LONG).show();
|
278
|
+
}
|
279
|
+
} else {
|
280
|
+
Toast.makeText(context,"Download diappeared!", Toast.LENGTH_LONG).show();
|
281
|
+
}
|
282
|
+
c.close();
|
283
|
+
}
|
284
|
+
} else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
|
285
|
+
if (intent.getData().toString().equals("package:org.ruboto.core")) {
|
286
|
+
Toast.makeText(context,"Ruboto Core is now installed.",Toast.LENGTH_LONG).show();
|
287
|
+
deleteFile(RUBOTO_APK);
|
288
|
+
if (receiver != null) {
|
289
|
+
unregisterReceiver(receiver);
|
290
|
+
receiver = null;
|
291
|
+
}
|
292
|
+
initJRuby(false);
|
293
|
+
} else {
|
294
|
+
Toast.makeText(context,"Installed: " + intent.getData().toString(),Toast.LENGTH_LONG).show();
|
295
|
+
}
|
296
|
+
}
|
297
|
+
}
|
298
|
+
};
|
299
|
+
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
|
300
|
+
filter.addDataScheme("package");
|
301
|
+
registerReceiver(receiver, filter);
|
302
|
+
IntentFilter download_filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
|
303
|
+
registerReceiver(receiver, download_filter);
|
304
|
+
}
|
305
|
+
|
306
|
+
private void storeDownload(DownloadManager dm, long downloadId) {
|
307
|
+
try {
|
308
|
+
android.os.ParcelFileDescriptor file = dm.openDownloadedFile(downloadId);
|
309
|
+
java.io.InputStream fileStream = new java.io.FileInputStream(file.getFileDescriptor());
|
310
|
+
java.io.FileOutputStream fos = openFileOutput(RUBOTO_APK, MODE_WORLD_READABLE);
|
311
|
+
byte[] buffer = new byte[1024];
|
312
|
+
int length;
|
313
|
+
while((length = fileStream.read(buffer)) > 0) {
|
314
|
+
fos.write(buffer, 0, length);
|
315
|
+
}
|
316
|
+
fos.flush();
|
317
|
+
fileStream.close();
|
318
|
+
fos.close();
|
319
|
+
dm.remove(downloadId);
|
320
|
+
enqueue = 0;
|
321
|
+
} catch (java.io.IOException ioe) {
|
322
|
+
Log.e("Exception copying RubotoCore: " + ioe);
|
323
|
+
Toast.makeText(this, "Exception copying RubotoCore: " + ioe, Toast.LENGTH_LONG).show();
|
324
|
+
}
|
325
|
+
}
|
326
|
+
|
327
|
+
// FIXME(uwe): Remove when we stop supporting Android < 4.0.3
|
328
|
+
private void installDownload() {
|
329
|
+
if (android.os.Build.VERSION.SDK_INT < 15) {
|
330
|
+
installDownload_10();
|
331
|
+
} else {
|
332
|
+
installDownload_15();
|
333
|
+
}
|
334
|
+
}
|
335
|
+
// EMXIF
|
336
|
+
|
337
|
+
// FIXME(uwe): Remove when we stop supporting Android < 4.0.3
|
338
|
+
private void installDownload_10() {
|
339
|
+
Uri uri = Uri.fromFile(localFile);
|
340
|
+
EntryPointActivity.this.grantUriPermission("com.android.packageinstaller", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
341
|
+
Intent installIntent = new Intent(Intent.ACTION_VIEW);
|
342
|
+
installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
|
343
|
+
installIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
344
|
+
startActivityForResult(installIntent, INSTALL_REQUEST_CODE);
|
345
|
+
}
|
346
|
+
// EMXIF
|
347
|
+
|
348
|
+
// FIXME(uwe): Use constants when we stop suporting Android < 4.0.3
|
349
|
+
private void installDownload_15() {
|
350
|
+
Uri uri = Uri.fromFile(localFile);
|
351
|
+
EntryPointActivity.this.grantUriPermission("com.android.packageinstaller", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
352
|
+
Intent installIntent = new Intent("android.intent.action.INSTALL_PACKAGE"); // Intent.ACTION_INSTALL_PACKAGE
|
353
|
+
installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
|
354
|
+
installIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
355
|
+
// FIXME(uwe): Remove when we stop supporting Android api level < 16
|
356
|
+
installIntent.putExtra("android.intent.extra.ALLOW_REPLACE", true); // Intent.EXTRA_ALLOW_REPLACE
|
357
|
+
// EMXIF
|
358
|
+
installIntent.putExtra("android.intent.extra.INSTALLER_PACKAGE_NAME", getPackageName()); // Intent.EXTRA_INSTALLER_PACKAGE_NAME
|
359
|
+
installIntent.putExtra("android.intent.extra.NOT_UNKNOWN_SOURCE", true); // Intent.EXTRA_NOT_UNKNOWN_SOURCE
|
360
|
+
installIntent.putExtra("android.intent.extra.RETURN_RESULT", true); // Intent.EXTRA_RETURN_RESULT
|
361
|
+
startActivityForResult(installIntent, INSTALL_REQUEST_CODE);
|
362
|
+
}
|
363
|
+
// EMXIF
|
364
|
+
|
365
|
+
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
366
|
+
Log.d("onActivityResult: " + requestCode + ", " + resultCode + ", " + data);
|
367
|
+
Log.d("onActivityResult: " + INSTALL_REQUEST_CODE + ", " + RESULT_OK + ", " + RESULT_CANCELED);
|
368
|
+
if (requestCode == INSTALL_REQUEST_CODE) {
|
369
|
+
if (resultCode == RESULT_OK) {
|
370
|
+
Log.d("onActivityResult: Install OK.");
|
371
|
+
} else if (resultCode == RESULT_CANCELED) {
|
372
|
+
Log.d("onActivityResult: Install canceled.");
|
373
|
+
// FIXME(uwe): Maybe show a dialog explaining that RubotoCore is needed and try again?
|
374
|
+
deleteFile(RUBOTO_APK);
|
375
|
+
if (!JRubyAdapter.isInitialized()) {
|
376
|
+
finish();
|
377
|
+
}
|
378
|
+
// EMXIF
|
379
|
+
} else {
|
380
|
+
Log.e("onActivityResult: resultCode: " + resultCode);
|
381
|
+
}
|
382
|
+
}
|
383
|
+
super.onActivityResult(requestCode, resultCode, data);
|
384
|
+
}
|
385
|
+
|
386
|
+
private boolean hasInternetPermission() {
|
387
|
+
String permission = "android.permission.INTERNET";
|
388
|
+
int res = checkCallingOrSelfPermission(permission);
|
389
|
+
return (res == PackageManager.PERMISSION_GRANTED);
|
390
|
+
}
|
391
|
+
|
392
|
+
private boolean canInstallFromUnknownSources() {
|
393
|
+
Uri settingsUri = Settings.Secure.CONTENT_URI;
|
394
|
+
String[] projection = new String[]{Settings.System.VALUE};
|
395
|
+
String selection = Settings.Secure.NAME + " = ? AND " + Settings.Secure.VALUE + " = ?";
|
396
|
+
|
397
|
+
// FIXME(uwe): Use android.provider.Settings.Global.INSTALL_NON_MARKET_APPS
|
398
|
+
// when we stop supporting Android api level < 17
|
399
|
+
String[] selectionArgs = {Settings.Secure.INSTALL_NON_MARKET_APPS, String.valueOf(1)};
|
400
|
+
// EMXIF
|
401
|
+
|
402
|
+
Cursor query = getContentResolver().query(settingsUri, projection,
|
403
|
+
selection, selectionArgs, null);
|
404
|
+
return query.getCount() == 1;
|
405
|
+
}
|
406
|
+
|
407
|
+
// Get the downloaded percent
|
408
|
+
private int getProgressPercentage() {
|
409
|
+
int downloadedBytesSoFar = 0, totalBytes = 0, percentage = 0;
|
410
|
+
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
|
411
|
+
try {
|
412
|
+
Cursor c = dm.query(new DownloadManager.Query().setFilterById(enqueue));
|
413
|
+
if (c.moveToFirst()) {
|
414
|
+
int soFarIndex =c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
|
415
|
+
downloadedBytesSoFar = (int) c.getLong(soFarIndex);
|
416
|
+
int totalSizeIndex = c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
|
417
|
+
totalBytes = (int) c.getLong(totalSizeIndex);
|
418
|
+
}
|
419
|
+
System.out.println("PERCEN ------" + downloadedBytesSoFar
|
420
|
+
+ " ------ " + totalBytes + "****" + percentage);
|
421
|
+
percentage = (downloadedBytesSoFar * 100 / totalBytes);
|
422
|
+
System.out.println("percentage % " + percentage);
|
423
|
+
} catch (Exception e) {
|
424
|
+
e.printStackTrace();
|
425
|
+
}
|
426
|
+
return percentage;
|
427
|
+
}
|
428
|
+
|
189
429
|
}
|