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.
Files changed (41) hide show
  1. data/Gemfile.lock +1 -1
  2. data/README.md +7 -5
  3. data/Rakefile +3 -4
  4. data/assets/rakelib/ruboto.rake +138 -87
  5. data/assets/samples/sample_broadcast_receiver.rb +1 -1
  6. data/assets/src/InheritingActivity.java +0 -6
  7. data/assets/src/RubotoActivity.java +4 -1
  8. data/assets/src/RubotoBroadcastReceiver.java +2 -11
  9. data/assets/src/RubotoService.java +6 -52
  10. data/assets/src/org/ruboto/EntryPointActivity.java +276 -36
  11. data/assets/src/org/ruboto/JRubyAdapter.java +5 -152
  12. data/assets/src/org/ruboto/Script.java +1 -1
  13. data/assets/src/org/ruboto/ScriptLoader.java +26 -44
  14. data/assets/src/org/ruboto/test/InstrumentationTestRunner.java +4 -21
  15. data/bin/ruboto +0 -6
  16. data/lib/ruboto/commands/base.rb +58 -48
  17. data/lib/ruboto/sdk_locations.rb +23 -0
  18. data/lib/ruboto/sdk_versions.rb +1 -19
  19. data/lib/ruboto/util/build.rb +32 -32
  20. data/lib/ruboto/util/setup.rb +240 -0
  21. data/lib/ruboto/util/update.rb +12 -25
  22. data/lib/ruboto/util/verify.rb +7 -4
  23. data/lib/ruboto/util/xml_element.rb +62 -76
  24. data/lib/ruboto/version.rb +1 -1
  25. data/test/activity/image_button_activity_test.rb +2 -2
  26. data/test/activity/image_button_and_button_activity_test.rb +2 -2
  27. data/test/activity/json_activity.rb +1 -1
  28. data/test/activity/navigation_activity.rb +12 -12
  29. data/test/activity/navigation_activity_test.rb +7 -7
  30. data/test/activity/option_menu_activity.rb +0 -1
  31. data/test/activity/option_menu_activity_test.rb +2 -2
  32. data/test/activity/stack_activity_test.rb +10 -20
  33. data/test/app_test_methods.rb +0 -4
  34. data/test/broadcast_receiver_test.rb +16 -6
  35. data/test/minimal_app_test.rb +4 -12
  36. data/test/rake_test.rb +37 -23
  37. data/test/ruboto_gen_test.rb +12 -15
  38. data/test/sqldroid_test.rb +3 -6
  39. data/test/test_helper.rb +2 -0
  40. data/test/update_test_methods.rb +9 -9
  41. 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, (Object[]) args);
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
- // FIXME(uwe): Simplify when we stop support for RubotoCore 0.4.7
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
- // FIXME(uwe): Simplify when we stop support for RubotoCore 0.4.7
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
- // FIXME(uwe): Simplify when we stop support for RubotoCore 0.4.7
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
- // FIXME(uwe): Simplify when we stop support for RubotoCore 0.4.7
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
- runOnUiThread(new Runnable() {
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.LENGTH_SHORT).show();
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 = "https://raw.github.com/ruboto/ruboto-core/master/dist/" + RUBOTO_APK;
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
- try {
145
- Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(RUBOTO_URL));
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, args[0]);
156
- onStart();
157
- super.onResume();
158
- hideProgress();
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
  }