diff --git a/Android/BarcodeScanner/BarcodeScanner.java b/Android/BarcodeScanner/BarcodeScanner.java index 90ea41a..c761605 100644 --- a/Android/BarcodeScanner/BarcodeScanner.java +++ b/Android/BarcodeScanner/BarcodeScanner.java @@ -12,6 +12,7 @@ import org.json.JSONArray; import org.json.JSONException; import com.phonegap.DroidGap; +import com.phonegap.api.PhonegapActivity; import com.phonegap.api.Plugin; import com.phonegap.api.PluginResult; @@ -142,7 +143,7 @@ public class BarcodeScanner extends Plugin { } private void showDownloadDialog(final String title, final String message, final String yesString, final String noString) { - final DroidGap context = this.ctx; + final PhonegapActivity context = this.ctx; Runnable runnable = new Runnable() { public void run() { @@ -153,9 +154,18 @@ public class BarcodeScanner extends Plugin { public void onClick(DialogInterface dlg, int i) { dlg.dismiss(); Intent intent = new Intent(Intent.ACTION_VIEW, - Uri.parse("market://search?q=pname:com.google.zxing.client.android") + Uri.parse("market://search?q=pname:com.google.zxing.client.android") ); - context.startActivity(intent); + try { + context.startActivity(intent); + } catch (ActivityNotFoundException e) { +// We don't have the market app installed, so download it directly. + Intent in = new Intent(Intent.ACTION_VIEW); + in.setData(Uri.parse("http://zxing.googlecode.com/files/BarcodeScanner3.5.apk")); + context.startActivity(in); + + } + } }); dialog.setNegativeButton(noString, new DialogInterface.OnClickListener() { diff --git a/Android/ChildBrowser/ChildBrowser.java b/Android/ChildBrowser/ChildBrowser.java index 1fd0131..5f9512a 100755 --- a/Android/ChildBrowser/ChildBrowser.java +++ b/Android/ChildBrowser/ChildBrowser.java @@ -1,7 +1,7 @@ /* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. - * + * * Copyright (c) 2005-2010, Nitobi Software Inc. * Copyright (c) 2010, IBM Corporation */ @@ -18,75 +18,93 @@ import com.phonegap.api.PluginResult; public class ChildBrowser extends Plugin { - /** - * Executes the request and returns PluginResult. - * - * @param action The action to execute. - * @param args JSONArry of arguments for the plugin. - * @param callbackId The callback id used when calling back into JavaScript. - * @return A PluginResult object with a status and message. - */ - public PluginResult execute(String action, JSONArray args, String callbackId) { - PluginResult.Status status = PluginResult.Status.OK; - String result = ""; - - try { - if (action.equals("showWebPage")) { - result = this.showWebPage(args.getString(0), args.optBoolean(1)); - if (result.length() > 0) { - status = PluginResult.Status.ERROR; - } - } - return new PluginResult(status, result); - } catch (JSONException e) { - return new PluginResult(PluginResult.Status.JSON_EXCEPTION); - } - } + /** + * Executes the request and returns PluginResult. + * + * @param action The action to execute. + * @param args JSONArry of arguments for the plugin. + * @param callbackId The callback id used when calling back into JavaScript. + * @return A PluginResult object with a status and message. + */ + public PluginResult execute(String action, JSONArray args, String callbackId) { + PluginResult.Status status = PluginResult.Status.OK; + String result = ""; + + try { + if (action.equals("showWebPage")) { + result = this.showWebPage(args.getString(0), args.optBoolean(1)); + if (result.length() > 0) { + status = PluginResult.Status.ERROR; + } + } + return new PluginResult(status, result); + } catch (JSONException e) { + return new PluginResult(PluginResult.Status.JSON_EXCEPTION); + } + } + + /** + * Identifies if action to be executed returns a value and should be run synchronously. + * + * @param action The action to execute + * @return T=returns value + */ + public boolean isSynch(String action) { + return false; + } - /** - * Identifies if action to be executed returns a value and should be run synchronously. - * - * @param action The action to execute - * @return T=returns value - */ - public boolean isSynch(String action) { - return false; - } - /** * Called by AccelBroker when listener is to be shut down. * Stop listener. */ - public void onDestroy() { + public void onDestroy() { } //-------------------------------------------------------------------------- // LOCAL METHODS //-------------------------------------------------------------------------- - + /** * Display a new browser with the specified URL. * - * @param url The url to load. - * @param usePhoneGap Load url in PhoneGap webview - * @return "" if ok, or error message. + * NOTE: If usePhoneGap is set, only trusted PhoneGap URLs should be loaded, + * since any PhoneGap API can be called by the loaded HTML page. + * + * @param url The url to load. + * @param usePhoneGap Load url in PhoneGap webview. + * @return "" if ok, or error message. */ public String showWebPage(String url, boolean usePhoneGap) { - try { - Intent intent = null; - if (usePhoneGap) { - intent = new Intent().setClass(this.ctx, com.phonegap.DroidGap.class); - } - else { - intent = new Intent(Intent.ACTION_VIEW); - } - intent.setData(Uri.parse(url)); - this.ctx.startActivity(intent); - return ""; + try { + Intent intent = null; + if (usePhoneGap) { + // Loads and displays a new PhoneGap app on top of current PhoneGap app. + // For the currently running PhoneGap app: + // If keepRunning=true (default), then the current app continues to run in background + // If keepRunning=false, then the current app is paused by Android + // When BACK is pressed, the current app has focus. + intent = new Intent().setClass(this.ctx, com.phonegap.DroidGap.class); + intent.setData(Uri.parse(url)); // This line will be removed in future. + intent.putExtra("url", url); + + // Timeout parameter: 60 sec max - May be less if http device timeout is less. + intent.putExtra("loadUrlTimeoutValue", 60000); + + // These parameters can be configured if you want to show the loading dialog + intent.putExtra("loadingDialog", "Wait,Loading web page..."); // show loading dialog + intent.putExtra("hideLoadingDialogOnPageLoad", true); // hide it once page has completely loaded + + } + else { + intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + } + this.ctx.startActivity(intent); + return ""; } catch (android.content.ActivityNotFoundException e) { - System.out.println("ChildBrowser: Error loading url "+url+":"+ e.toString()); - return e.toString(); + System.out.println("ChildBrowser: Error loading url "+url+":"+ e.toString()); + return e.toString(); } } - + } diff --git a/Android/ChildBrowser/README.md b/Android/ChildBrowser/README.md index 14dd32b..83290f6 100755 --- a/Android/ChildBrowser/README.md +++ b/Android/ChildBrowser/README.md @@ -19,6 +19,14 @@ Using this plugin requires [Android PhoneGap](http://github.com/phonegap/phonega 2. Create a directory within your project called "src/com/phonegap/plugins/childBrowser" and move ChildBrowser.java into it. +3. Add the following activity to your AndroidManifest.xml file. It should be added inside the <application> tag. + + <activity android:name="com.phonegap.DroidGap" android:label="@string/app_name">
+ <intent-filter>
+ </intent-filter>
+ </activity> + + ## Using the plugin ## The plugin creates the object `window.plugins.childBrowser`. To use, call one of the following, available methods: @@ -26,10 +34,14 @@ The plugin creates the object `window.plugins.childBrowser`. To use, call one o
   /**
    * Display a new browser with the specified URL.
+   * 
+   * NOTE: If usePhoneGap is set, only trusted PhoneGap URLs should be loaded,
+   *       since any PhoneGap API can be called by the loaded HTML page.
    *
    * @param url           The url to load
-   * @param usePhoneGap   Load url in PhoneGap webview [optional]
+   * @param usePhoneGap   Load url in PhoneGap webview [optional] - Default: false
    */
+   
   showWebPage(url, [usePhoneGap])
 
@@ -43,6 +55,14 @@ Sample use: * Initial release +### Nov 12, 2010 ### + +* Changed how URL is passed when usePhoneGap=true. Instead of using Data, it is now passed as Extra. This will work with latest edge version with the same date. +* Added "Loading" dialog that is shown when usePhoneGap=true. + +### Dec 2, 2010 ### + +* Added warning comments about loading URLs when usePhoneGap=true. ## BUGS AND CONTRIBUTIONS ## diff --git a/Android/ChildBrowser/childbrowser.js b/Android/ChildBrowser/childbrowser.js index dce4289..593e874 100755 --- a/Android/ChildBrowser/childbrowser.js +++ b/Android/ChildBrowser/childbrowser.js @@ -14,9 +14,12 @@ function ChildBrowser() { /** * Display a new browser with the specified URL. + * + * NOTE: If usePhoneGap is set, only trusted PhoneGap URLs should be loaded, + * since any PhoneGap API can be called by the loaded HTML page. * * @param url The url to load - * @param usePhoneGap Load url in PhoneGap webview [optional] + * @param usePhoneGap Load url in PhoneGap webview [optional] - Default: false */ ChildBrowser.prototype.showWebPage = function(url, usePhoneGap) { PhoneGap.exec(null, null, "ChildBrowser", "showWebPage", [url, usePhoneGap]); diff --git a/Android/WebIntent/README.md b/Android/WebIntent/README.md new file mode 100644 index 0000000..c6acf0d --- /dev/null +++ b/Android/WebIntent/README.md @@ -0,0 +1,67 @@ +# WebIntents plugin for Phonegap # +By Boris Smus + +## Adding the Plugin to your project ## +1. To install the plugin, move webintent.js to your project's www folder and include a reference to it in your html files. +2. Create a folder called "borismus" within your project's src/com/ folder and move the java file into it. + +## Using the plugin ## +The plugin creates the object `window.plugins.webintent` with three methods: + +### startActivity ### +Launches an Android intent. For example: + + + window.plugins.webintent.startActivity({ + action: WebIntent.ACTION_VIEW, + url: 'geo:0,0?q=' + address}, + function() {}, + function() {alert('Failed to open URL via Android Intent')}; + ); + + +### hasExtra ### +checks if this app was invoked with the specified extra. For example: + + window.plugins.webintent.hasExtra(WebIntent.EXTRA_TEXT, + function(has) { + // has is true iff it has the extra + }, function() { + // Something really bad happened. + } + ); + +### getExtra ### +Gets the extra that this app was invoked with. For example: + + window.plugins.webintent.getExtra(WebIntent.EXTRA_TEXT, + function(url) { + // url is the value of EXTRA_TEXT + }, function() { + // There was no extra supplied. + } + ); + +## Licence ## + +The MIT License + +Copyright (c) 2010 Boris Smus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/Android/WebIntent/WebIntent.java b/Android/WebIntent/WebIntent.java new file mode 100644 index 0000000..9beff64 --- /dev/null +++ b/Android/WebIntent/WebIntent.java @@ -0,0 +1,101 @@ +package com.borismus.webintent; + +import java.util.HashMap; +import java.util.Map; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.content.Intent; +import android.net.Uri; + +import com.phonegap.api.Plugin; +import com.phonegap.api.PluginResult; + +/** + * WebIntent is a PhoneGap plugin that bridges Android intents and web applications: + * + * 1. web apps can spawn intents that call native Android applications. + * 2. (after setting up correct intent filters for PhoneGap applications), Android + * intents can be handled by PhoneGap web applications. + * + * @author boris@borismus.com + * + */ +public class WebIntent extends Plugin { + + /** + * Executes the request and returns PluginResult. + * + * @param action The action to execute. + * @param args JSONArray of arguments for the plugin. + * @param callbackId The callback id used when calling back into JavaScript. + * @return A PluginResult object with a status and message. + */ + public PluginResult execute(String action, JSONArray args, String callbackId) { + try { + if (action.equals("startActivity")) { + if(args.length() != 1) { + return new PluginResult(PluginResult.Status.INVALID_ACTION); + } + + // Parse the arguments + JSONObject obj = args.getJSONObject(0); + String type = obj.has("type") ? obj.getString("type") : null; + Uri uri = obj.has("url") ? Uri.parse(obj.getString("url")) : null; + JSONObject extras = obj.has("extras") ? obj.getJSONObject("extras") : null; + Map extrasMap = new HashMap(); + + // Populate the extras if any exist + if (extras != null) { + JSONArray extraNames = extras.names(); + for (int i = 0; i < extraNames.length(); i++) { + String key = extraNames.getString(i); + String value = extras.getString(key); + extrasMap.put(key, value); + } + } + + startActivity(obj.getString("action"), uri, type, extrasMap); + return new PluginResult(PluginResult.Status.OK); + + } else if (action.equals("hasExtra")) { + if (args.length() != 1) { + return new PluginResult(PluginResult.Status.INVALID_ACTION); + } + Intent i = this.ctx.getIntent(); + String extraName = args.getString(0); + return new PluginResult(PluginResult.Status.OK, i.hasExtra(extraName)); + + } else if (action.equals("getExtra")) { + if (args.length() != 1) { + return new PluginResult(PluginResult.Status.INVALID_ACTION); + } + Intent i = this.ctx.getIntent(); + String extraName = args.getString(0); + if (i.hasExtra(extraName)) { + return new PluginResult(PluginResult.Status.OK, i.getStringExtra(extraName)); + } else { + return new PluginResult(PluginResult.Status.ERROR); + } + } + return new PluginResult(PluginResult.Status.INVALID_ACTION); + } catch (JSONException e) { + e.printStackTrace(); + return new PluginResult(PluginResult.Status.JSON_EXCEPTION); + } + } + + void startActivity(String action, Uri uri, String type, Map extras) { + Intent i = (uri != null ? new Intent(action, uri) : new Intent(action)); + if (type != null) { + i.setType(type); + } + for (String key : extras.keySet()) { + String value = extras.get(key); + i.putExtra(key, value); + } + this.ctx.startActivity(i); + } +} diff --git a/Android/WebIntent/webintent.js b/Android/WebIntent/webintent.js new file mode 100644 index 0000000..b8eb212 --- /dev/null +++ b/Android/WebIntent/webintent.js @@ -0,0 +1,42 @@ +/** + * Phonegap Web Intent plugin + * Copyright (c) Boris Smus 2010 + * + */ +var WebIntent = function() { + +}; + +WebIntent.ACTION_SEND = "android.intent.action.SEND"; +WebIntent.ACTION_VIEW= "android.intent.action.VIEW"; +WebIntent.EXTRA_TEXT = "android.intent.extra.TEXT"; +WebIntent.EXTRA_SUBJECT = "android.intent.extra.SUBJECT"; + +WebIntent.prototype.startActivity = function(params, success, fail) { + return PhoneGap.exec(function(args) { + success(args); + }, function(args) { + fail(args); + }, 'WebIntent', 'startActivity', [params]); +}; + +WebIntent.prototype.hasExtra = function(params, success, fail) { + return PhoneGap.exec(function(args) { + success(args); + }, function(args) { + fail(args); + }, 'WebIntent', 'hasExtra', [params]); +}; + +WebIntent.prototype.getExtra = function(params, success, fail) { + return PhoneGap.exec(function(args) { + success(args); + }, function(args) { + fail(args); + }, 'WebIntent', 'getExtra', [params]); +}; + +PhoneGap.addConstructor(function() { + PhoneGap.addPlugin('webintent', new WebIntent()); + PluginManager.addService("WebIntent","com.borismus.webintent.WebIntent"); +}); \ No newline at end of file diff --git a/iPhone/Keychain/SAiOSKeychainPlugin.js b/iPhone/Keychain/SAiOSKeychainPlugin.js index 2016e5b..9a3d44a 100644 --- a/iPhone/Keychain/SAiOSKeychainPlugin.js +++ b/iPhone/Keychain/SAiOSKeychainPlugin.js @@ -98,7 +98,7 @@ SAiOSKeychainPlugin.install = function() if ( !window.plugins ) { window.plugins = {}; } - if ( !window.plugins.paypal ) { + if ( !window.plugins.keychain ) { window.plugins.keychain = new SAiOSKeychainPlugin(); } }