diff --git a/.gitignore b/.gitignore index afa78b8d..212af7e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.DS_Store default.properties gen assets/www/phonegap.js @@ -5,4 +6,4 @@ local.properties framework/phonegap.jar framework/bin framework/assets/www/.DS_Store -.DS_Store \ No newline at end of file +.DS_Store diff --git a/framework/res/xml/plugins.xml b/framework/res/xml/plugins.xml new file mode 100755 index 00000000..bf170607 --- /dev/null +++ b/framework/res/xml/plugins.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/framework/src/com/phonegap/DroidGap.java b/framework/src/com/phonegap/DroidGap.java index 3830722e..0a323051 100755 --- a/framework/src/com/phonegap/DroidGap.java +++ b/framework/src/com/phonegap/DroidGap.java @@ -9,6 +9,7 @@ package com.phonegap; import java.util.HashMap; import java.util.Map.Entry; + import org.json.JSONArray; import org.json.JSONException; @@ -133,11 +134,9 @@ public class DroidGap extends PhonegapActivity { // 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 + // The base of the initial URL for our app. + // Does not include file name. Ends with / + // ie http://server/path/ private String baseUrl = null; // Plugin to call when activity result is received @@ -291,23 +290,6 @@ public class DroidGap extends PhonegapActivity { this.callbackServer = new CallbackServer(); this.pluginManager = new PluginManager(appView, this); - this.addService("App", "com.phonegap.App"); - this.addService("Geolocation", "com.phonegap.GeoBroker"); - this.addService("Device", "com.phonegap.Device"); - this.addService("Accelerometer", "com.phonegap.AccelListener"); - this.addService("Compass", "com.phonegap.CompassListener"); - this.addService("Media", "com.phonegap.AudioHandler"); - this.addService("Camera", "com.phonegap.CameraLauncher"); - this.addService("Contacts", "com.phonegap.ContactManager"); - this.addService("Crypto", "com.phonegap.CryptoHandler"); - this.addService("File", "com.phonegap.FileUtils"); - this.addService("Location", "com.phonegap.GeoBroker"); // Always add Location, even though it is built-in on 2.x devices. Let JavaScript decide which one to use. - this.addService("Network Status", "com.phonegap.NetworkManager"); - this.addService("Notification", "com.phonegap.Notification"); - this.addService("Storage", "com.phonegap.Storage"); - this.addService("Temperature", "com.phonegap.TempListener"); - this.addService("FileTransfer", "com.phonegap.FileTransfer"); - this.addService("Capture", "com.phonegap.Capture"); } /** @@ -350,7 +332,6 @@ public class DroidGap extends PhonegapActivity { */ public void loadUrl(final String url) { System.out.println("loadUrl("+url+")"); - this.urlFile = this.getUrlFile(url); this.url = url; if (this.baseUrl == null) { int i = url.lastIndexOf('/'); @@ -617,7 +598,7 @@ public class DroidGap extends PhonegapActivity { public void setDoubleProperty(String name, double value) { this.getIntent().putExtra(name, value); } - + @Override /** * Called when the system is about to start resuming a previous activity. @@ -727,21 +708,6 @@ 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); - } /** * Display a new browser with the specified URL. @@ -1311,12 +1277,7 @@ public class DroidGap extends PhonegapActivity { @Override public void startActivityForResult(Intent intent, int requestCode) throws RuntimeException { System.out.println("startActivityForResult(intent,"+requestCode+")"); - if (requestCode == -1) { - super.startActivityForResult(intent, requestCode); - } - else { - throw new RuntimeException("PhoneGap Exception: Call startActivityForResult(Command, Intent) instead."); - } + super.startActivityForResult(intent, requestCode); } /** @@ -1357,7 +1318,12 @@ public class DroidGap extends PhonegapActivity { callback.onActivityResult(requestCode, resultCode, intent); } } - + + @Override + public void setActivityResultCallback(Plugin plugin) { + this.activityResultCallback = plugin; + } + /** * Report an error to the host application. These errors are unrecoverable (i.e. the main resource is unavailable). * The errorCode parameter corresponds to one of the ERROR_* constants. diff --git a/framework/src/com/phonegap/api/PhonegapActivity.java b/framework/src/com/phonegap/api/PhonegapActivity.java index dcadfa2b..135cc3a5 100755 --- a/framework/src/com/phonegap/api/PhonegapActivity.java +++ b/framework/src/com/phonegap/api/PhonegapActivity.java @@ -15,7 +15,7 @@ import android.content.Intent; * It is used to isolate plugin development, and remove dependency on entire Phonegap library. */ public abstract class PhonegapActivity extends Activity { - + /** * Add a class that implements a service. * @@ -40,4 +40,11 @@ public abstract class PhonegapActivity extends Activity { * @param requestCode The request code that is passed to callback to identify the activity */ abstract public void startActivityForResult(Plugin command, Intent intent, int requestCode); + + /** + * Set the plugin to be called when a sub-activity exits. + * + * @param plugin The plugin on which onActivityResult is to be called + */ + abstract public void setActivityResultCallback(Plugin plugin); } diff --git a/framework/src/com/phonegap/api/Plugin.java b/framework/src/com/phonegap/api/Plugin.java index 746bd408..282f60f4 100755 --- a/framework/src/com/phonegap/api/Plugin.java +++ b/framework/src/com/phonegap/api/Plugin.java @@ -8,6 +8,7 @@ package com.phonegap.api; import org.json.JSONArray; +import org.json.JSONObject; import android.content.Intent; import android.webkit.WebView; @@ -19,6 +20,7 @@ import android.webkit.WebView; */ public abstract class Plugin implements IPlugin { + public String id; public WebView webView; // WebView object public PhonegapActivity ctx; // PhonegapActivity object @@ -126,6 +128,26 @@ public abstract class Plugin implements IPlugin { this.ctx.sendJavascript(pluginResult.toSuccessCallbackString(callbackId)); } + /** + * Helper for success callbacks that just returns the Status.OK by default + * + * @param message The message to add to the success result. + * @param callbackId The callback id used when calling back into JavaScript. + */ + public void success(JSONObject message, String callbackId) { + this.ctx.sendJavascript(new PluginResult(PluginResult.Status.OK, message).toSuccessCallbackString(callbackId)); + } + + /** + * Helper for success callbacks that just returns the Status.OK by default + * + * @param message The message to add to the success result. + * @param callbackId The callback id used when calling back into JavaScript. + */ + public void success(String message, String callbackId) { + this.ctx.sendJavascript(new PluginResult(PluginResult.Status.OK, message).toSuccessCallbackString(callbackId)); + } + /** * Call the JavaScript error callback for this plugin. * @@ -135,4 +157,24 @@ public abstract class Plugin implements IPlugin { public void error(PluginResult pluginResult, String callbackId) { this.ctx.sendJavascript(pluginResult.toErrorCallbackString(callbackId)); } + + /** + * Helper for error callbacks that just returns the Status.ERROR by default + * + * @param message The message to add to the error result. + * @param callbackId The callback id used when calling back into JavaScript. + */ + public void error(JSONObject message, String callbackId) { + this.ctx.sendJavascript(new PluginResult(PluginResult.Status.ERROR, message).toErrorCallbackString(callbackId)); + } + + /** + * Helper for error callbacks that just returns the Status.ERROR by default + * + * @param message The message to add to the error result. + * @param callbackId The callback id used when calling back into JavaScript. + */ + public void error(String message, String callbackId) { + this.ctx.sendJavascript(new PluginResult(PluginResult.Status.ERROR, message).toErrorCallbackString(callbackId)); + } } diff --git a/framework/src/com/phonegap/api/PluginManager.java b/framework/src/com/phonegap/api/PluginManager.java index 393c6a29..e94d0ee5 100755 --- a/framework/src/com/phonegap/api/PluginManager.java +++ b/framework/src/com/phonegap/api/PluginManager.java @@ -7,13 +7,16 @@ */ package com.phonegap.api; +import java.io.IOException; import java.util.HashMap; import java.util.Map.Entry; import org.json.JSONArray; import org.json.JSONException; +import org.xmlpull.v1.XmlPullParserException; import android.content.Intent; +import android.content.res.XmlResourceParser; import android.webkit.WebView; /** @@ -39,6 +42,33 @@ public final class PluginManager { public PluginManager(WebView app, PhonegapActivity ctx) { this.ctx = ctx; this.app = app; + this.loadPlugins(); + } + + /** + * Load plugins from res/xml/plugins.xml + */ + public void loadPlugins() { + XmlResourceParser xml = ctx.getResources().getXml(com.phonegap.R.xml.plugins); + int eventType = -1; + while (eventType != XmlResourceParser.END_DOCUMENT) { + if (eventType == XmlResourceParser.START_TAG) { + String strNode = xml.getName(); + if (strNode.equals("plugin")) { + String name = xml.getAttributeValue(null, "name"); + String value = xml.getAttributeValue(null, "value"); + System.out.println("Plugin: "+name+" => "+value); + this.addService(name, value); + } + } + try { + eventType = xml.next(); + } catch (XmlPullParserException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } } /** @@ -101,7 +131,7 @@ public final class PluginManager { ctx.sendJavascript(cr.toErrorCallbackString(callbackId)); } } catch (Exception e) { - PluginResult cr = new PluginResult(PluginResult.Status.ERROR); + PluginResult cr = new PluginResult(PluginResult.Status.ERROR, e.getMessage()); ctx.sendJavascript(cr.toErrorCallbackString(callbackId)); } } @@ -160,24 +190,7 @@ public final class PluginManager { } return false; } - - /** - * Add plugin to be loaded and cached. This creates an instance of the plugin. - * If plugin is already created, then just return it. - * - * @param className The class to load - * @return The plugin - */ - public Plugin addPlugin(String className) { - try { - return this.addPlugin(className, this.getClassByName(className)); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - System.out.println("Error adding plugin "+className+"."); - } - return null; - } - + /** * Add plugin to be loaded and cached. This creates an instance of the plugin. * If plugin is already created, then just return it. diff --git a/lib/classic.rb b/lib/classic.rb index 4eeb7e53..a80cf656 100755 --- a/lib/classic.rb +++ b/lib/classic.rb @@ -97,6 +97,9 @@ class Classic # copies in the strings.xml FileUtils.mkdir_p File.join(app_res_dir, "values") FileUtils.cp File.join(framework_res_dir, "values","strings.xml"), File.join(app_res_dir, "values", "strings.xml") + # copies in plugins.xml + FileUtils.mkdir_p File.join(app_res_dir, "xml") + FileUtils.cp File.join(framework_res_dir, "xml","plugins.xml"), File.join(app_res_dir, "xml", "plugins.xml") # drops in the layout files: main.xml and preview.xml FileUtils.mkdir_p File.join(app_res_dir, "layout") %w(main.xml).each do |f|