diff --git a/.gitignore b/.gitignore index 5c53ca30..afa78b8d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ local.properties framework/phonegap.jar framework/bin framework/assets/www/.DS_Store +.DS_Store \ No newline at end of file diff --git a/framework/src/com/phonegap/DroidGap.java b/framework/src/com/phonegap/DroidGap.java index 01e226b0..ca37d1af 100755 --- a/framework/src/com/phonegap/DroidGap.java +++ b/framework/src/com/phonegap/DroidGap.java @@ -9,8 +9,8 @@ package com.phonegap; import org.json.JSONArray; import org.json.JSONException; + import android.app.AlertDialog; -import android.widget.EditText; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -18,7 +18,6 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; -import android.graphics.Bitmap; import android.graphics.Color; import android.media.AudioManager; import android.net.Uri; @@ -30,20 +29,22 @@ import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; +import android.webkit.GeolocationPermissions.Callback; +import android.webkit.JsPromptResult; import android.webkit.JsResult; import android.webkit.SslErrorHandler; import android.webkit.WebChromeClient; -import android.webkit.JsPromptResult; import android.webkit.WebSettings; +import android.webkit.WebSettings.LayoutAlgorithm; import android.webkit.WebStorage; import android.webkit.WebView; import android.webkit.WebViewClient; -import android.webkit.GeolocationPermissions.Callback; -import android.webkit.WebSettings.LayoutAlgorithm; +import android.widget.EditText; import android.widget.LinearLayout; + +import com.phonegap.api.PhonegapActivity; import com.phonegap.api.Plugin; import com.phonegap.api.PluginManager; -import com.phonegap.api.PhonegapActivity; /** * This class is the main Android activity that represents the PhoneGap @@ -124,8 +125,13 @@ public class DroidGap extends PhonegapActivity { protected boolean clearHistory = false; // The initial URL for our app + // ie http://server/path/index.html#abc?query private String url; + // The initial URL for our app up to and including the file name + // ie http://server/path/index.html + private String urlFile; + // The base of the initial URL for our app private String baseUrl; @@ -335,6 +341,7 @@ public class DroidGap extends PhonegapActivity { */ public void loadUrl(final String url) { System.out.println("loadUrl("+url+")"); + this.urlFile = this.getUrlFile(url); this.url = url; int i = url.lastIndexOf('/'); if (i > 0) { @@ -613,17 +620,28 @@ public class DroidGap extends PhonegapActivity { // Send pause event to JavaScript this.appView.loadUrl("javascript:try{PhoneGap.onPause.fire();}catch(e){};"); + // Forward to plugins + this.pluginManager.onPause(this.keepRunning); + // If app doesn't want to run in background if (!this.keepRunning) { - - // Forward to plugins - this.pluginManager.onPause(); // Pause JavaScript timers (including setInterval) this.appView.pauseTimers(); } } + @Override + /** + * Called when the activity receives a new intent + **/ + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + + //Forward to plugins + this.pluginManager.onNewIntent(intent); + } + @Override /** * Called when the activity will start interacting with the user. @@ -637,6 +655,9 @@ public class DroidGap extends PhonegapActivity { // Send resume event to JavaScript this.appView.loadUrl("javascript:try{PhoneGap.onResume.fire();}catch(e){};"); + // Forward to plugins + this.pluginManager.onResume(this.keepRunning || this.activityResultKeepRunning); + // If app doesn't want to run in background if (!this.keepRunning || this.activityResultKeepRunning) { @@ -646,9 +667,6 @@ public class DroidGap extends PhonegapActivity { this.activityResultKeepRunning = false; } - // Forward to plugins - this.pluginManager.onResume(); - // Resume JavaScript timers (including setInterval) this.appView.resumeTimers(); } @@ -698,13 +716,29 @@ public class DroidGap extends PhonegapActivity { this.callbackServer.sendJavascript(statement); } + /** + * Return up to file part of url. + * If url = http://server/page.html#abc, then return http://server/page.html + * + * @param url + * @return + */ + private String getUrlFile(String url) { + int p1 = url.indexOf("#"); + int p2 = url.indexOf("?"); + if (p1 < 0) p1 = url.length(); + if (p2 < 0) p2 = url.length(); + int p3 = (p1 < p2) ? p1 : p2; + return url.substring(0, p3); + } + /** * Provides a hook for calling "alert" from javascript. Useful for * debugging your javascript. */ public class GapClient extends WebChromeClient { - private Context ctx; + private DroidGap ctx; /** * Constructor. @@ -712,7 +746,7 @@ public class DroidGap extends PhonegapActivity { * @param ctx */ public GapClient(Context ctx) { - this.ctx = ctx; + this.ctx = (DroidGap)ctx; } /** @@ -785,7 +819,7 @@ public class DroidGap extends PhonegapActivity { @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { boolean reqOk = false; - if (((DroidGap)(this.ctx)).url.equals(url)) { + if (this.ctx.urlFile.equals(this.ctx.getUrlFile(url))) { reqOk = true; } @@ -1161,6 +1195,7 @@ public class DroidGap extends PhonegapActivity { // If back key is bound, then send event to JavaScript if (this.bound) { this.appView.loadUrl("javascript:PhoneGap.fireEvent('backbutton');"); + return true; } // If not bound @@ -1169,6 +1204,7 @@ public class DroidGap extends PhonegapActivity { // Go to previous page in webview if it is possible to go back if (this.appView.canGoBack()) { this.appView.goBack(); + return true; } // If not, then invoke behavior of super class @@ -1181,11 +1217,13 @@ public class DroidGap extends PhonegapActivity { // If menu key else if (keyCode == KeyEvent.KEYCODE_MENU) { this.appView.loadUrl("javascript:PhoneGap.fireEvent('menubutton');"); + return true; } // If search key else if (keyCode == KeyEvent.KEYCODE_SEARCH) { this.appView.loadUrl("javascript:PhoneGap.fireEvent('searchbutton');"); + return true; } return false; diff --git a/framework/src/com/phonegap/FileUtils.java b/framework/src/com/phonegap/FileUtils.java index a53884ef..08ff7cce 100755 --- a/framework/src/com/phonegap/FileUtils.java +++ b/framework/src/com/phonegap/FileUtils.java @@ -10,6 +10,7 @@ package com.phonegap; import java.io.*; import java.net.MalformedURLException; import java.net.URL; +import java.net.URLDecoder; import java.nio.channels.FileChannel; import org.apache.commons.codec.binary.Base64; @@ -229,15 +230,16 @@ public class FileUtils extends Plugin { * @throws JSONException */ private JSONObject resolveLocalFileSystemURI(String url) throws IOException, JSONException { + String decoded = URLDecoder.decode(url, "UTF-8"); // Test to see if this is a valid URL first - @SuppressWarnings("unused") - URL testUrl = new URL(url); - + @SuppressWarnings("unused") + URL testUrl = new URL(decoded); + File fp = null; - if (url.startsWith("file://")) { - fp = new File(url.substring(7, url.length())); + if (decoded.startsWith("file://")) { + fp = new File(decoded.substring(7, decoded.length())); } else { - fp = new File(url); + fp = new File(decoded); } if (!fp.exists()) { throw new FileNotFoundException(); diff --git a/framework/src/com/phonegap/api/IPlugin.java b/framework/src/com/phonegap/api/IPlugin.java index b3b3a1da..b9c316e0 100755 --- a/framework/src/com/phonegap/api/IPlugin.java +++ b/framework/src/com/phonegap/api/IPlugin.java @@ -54,13 +54,17 @@ public interface IPlugin { /** * Called when the system is about to start resuming a previous activity. + * + * @param multitasking Flag indicating if multitasking is turned on for app */ - void onPause(); + void onPause(boolean multitasking); /** * Called when the activity will start interacting with the user. + * + * @param multitasking Flag indicating if multitasking is turned on for app */ - void onResume(); + void onResume(boolean multitasking); /** * The final call you receive before your activity is destroyed. diff --git a/framework/src/com/phonegap/api/Plugin.java b/framework/src/com/phonegap/api/Plugin.java index a527159a..746bd408 100755 --- a/framework/src/com/phonegap/api/Plugin.java +++ b/framework/src/com/phonegap/api/Plugin.java @@ -64,14 +64,24 @@ public abstract class Plugin implements IPlugin { /** * Called when the system is about to start resuming a previous activity. + * + * @param multitasking Flag indicating if multitasking is turned on for app */ - public void onPause() { + public void onPause(boolean multitasking) { } /** * Called when the activity will start interacting with the user. + * + * @param multitasking Flag indicating if multitasking is turned on for app */ - public void onResume() { + public void onResume(boolean multitasking) { + } + + /** + * Called when the activity receives a new intent. + */ + public void onNewIntent(Intent intent) { } /** diff --git a/framework/src/com/phonegap/api/PluginManager.java b/framework/src/com/phonegap/api/PluginManager.java index ad1cf20b..393c6a29 100755 --- a/framework/src/com/phonegap/api/PluginManager.java +++ b/framework/src/com/phonegap/api/PluginManager.java @@ -13,6 +13,7 @@ import java.util.Map.Entry; import org.json.JSONArray; import org.json.JSONException; +import android.content.Intent; import android.webkit.WebView; /** @@ -229,27 +230,31 @@ public final class PluginManager { /** * Called when the system is about to start resuming a previous activity. + * + * @param multitasking Flag indicating if multitasking is turned on for app */ - public void onPause() { + public void onPause(boolean multitasking) { java.util.Set> s = this.plugins.entrySet(); java.util.Iterator> it = s.iterator(); while(it.hasNext()) { Entry entry = it.next(); Plugin plugin = entry.getValue(); - plugin.onPause(); + plugin.onPause(multitasking); } } /** * Called when the activity will start interacting with the user. + * + * @param multitasking Flag indicating if multitasking is turned on for app */ - public void onResume() { + public void onResume(boolean multitasking) { java.util.Set> s = this.plugins.entrySet(); java.util.Iterator> it = s.iterator(); while(it.hasNext()) { Entry entry = it.next(); Plugin plugin = entry.getValue(); - plugin.onResume(); + plugin.onResume(multitasking); } } @@ -265,4 +270,17 @@ public final class PluginManager { plugin.onDestroy(); } } + + /** + * Called when the activity receives a new intent. + */ + public void onNewIntent(Intent intent) { + java.util.Set> s = this.plugins.entrySet(); + java.util.Iterator> it = s.iterator(); + while(it.hasNext()) { + Entry entry = it.next(); + Plugin plugin = entry.getValue(); + plugin.onNewIntent(intent); + } + } } \ No newline at end of file diff --git a/lib/update.rb b/lib/update.rb index aa1459a1..23e57a70 100755 --- a/lib/update.rb +++ b/lib/update.rb @@ -33,12 +33,19 @@ class Update # TODO need to allow for www import inc icon def copy_libs puts "Copying over libraries and assets..." - - FileUtils.mkdir_p File.join(@path, "libs") - FileUtils.cp File.join(@framework_dir, "phonegap.jar"), File.join(@path, "libs") + version = IO.read(File.join(@framework_dir, '../VERSION')) - FileUtils.mkdir_p File.join(@path, "assets", "www") - FileUtils.cp File.join(@framework_dir, "assets", "www", "phonegap.js"), File.join(@path, "assets", "www") + FileUtils.cp File.join(@framework_dir, "phonegap.#{ version }.jar"), File.join(@path, "libs") + + # concat JS and put into www folder. this can be overridden in the config.xml via @app_js_dir + js_dir = File.join(@framework_dir, "assets", "js") + phonegapjs = IO.read(File.join(js_dir, 'phonegap.js.base')) + Dir.new(js_dir).entries.each do |script| + next if script[0].chr == "." or script == "phonegap.js.base" + phonegapjs << IO.read(File.join(js_dir, script)) + phonegapjs << "\n\n" + end + File.open(File.join(@path, "assets", "www", "phonegap.#{ version }.js"), 'w') {|f| f.write(phonegapjs) } end # end \ No newline at end of file