Merge branch 'master' of github.com:phonegap/phonegap-android

This commit is contained in:
Joe Bowser 2011-06-24 14:02:02 -07:00
commit 11a29e11e1
7 changed files with 114 additions and 34 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ local.properties
framework/phonegap.jar framework/phonegap.jar
framework/bin framework/bin
framework/assets/www/.DS_Store framework/assets/www/.DS_Store
.DS_Store

View File

@ -9,8 +9,8 @@ package com.phonegap;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.widget.EditText;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
@ -18,7 +18,6 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
import android.media.AudioManager; import android.media.AudioManager;
import android.net.Uri; import android.net.Uri;
@ -30,20 +29,22 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
import android.webkit.GeolocationPermissions.Callback;
import android.webkit.JsPromptResult;
import android.webkit.JsResult; import android.webkit.JsResult;
import android.webkit.SslErrorHandler; import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient; import android.webkit.WebChromeClient;
import android.webkit.JsPromptResult;
import android.webkit.WebSettings; import android.webkit.WebSettings;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.webkit.WebStorage; import android.webkit.WebStorage;
import android.webkit.WebView; import android.webkit.WebView;
import android.webkit.WebViewClient; import android.webkit.WebViewClient;
import android.webkit.GeolocationPermissions.Callback; import android.widget.EditText;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import com.phonegap.api.PhonegapActivity;
import com.phonegap.api.Plugin; import com.phonegap.api.Plugin;
import com.phonegap.api.PluginManager; import com.phonegap.api.PluginManager;
import com.phonegap.api.PhonegapActivity;
/** /**
* This class is the main Android activity that represents the PhoneGap * This class is the main Android activity that represents the PhoneGap
@ -124,8 +125,13 @@ public class DroidGap extends PhonegapActivity {
protected boolean clearHistory = false; protected boolean clearHistory = false;
// The initial URL for our app // The initial URL for our app
// ie http://server/path/index.html#abc?query
private String url; 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
private String baseUrl; private String baseUrl;
@ -335,6 +341,7 @@ public class DroidGap extends PhonegapActivity {
*/ */
public void loadUrl(final String url) { public void loadUrl(final String url) {
System.out.println("loadUrl("+url+")"); System.out.println("loadUrl("+url+")");
this.urlFile = this.getUrlFile(url);
this.url = url; this.url = url;
int i = url.lastIndexOf('/'); int i = url.lastIndexOf('/');
if (i > 0) { if (i > 0) {
@ -613,17 +620,28 @@ public class DroidGap extends PhonegapActivity {
// Send pause event to JavaScript // Send pause event to JavaScript
this.appView.loadUrl("javascript:try{PhoneGap.onPause.fire();}catch(e){};"); 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 app doesn't want to run in background
if (!this.keepRunning) { if (!this.keepRunning) {
// Forward to plugins
this.pluginManager.onPause();
// Pause JavaScript timers (including setInterval) // Pause JavaScript timers (including setInterval)
this.appView.pauseTimers(); 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 @Override
/** /**
* Called when the activity will start interacting with the user. * Called when the activity will start interacting with the user.
@ -637,6 +655,9 @@ public class DroidGap extends PhonegapActivity {
// Send resume event to JavaScript // Send resume event to JavaScript
this.appView.loadUrl("javascript:try{PhoneGap.onResume.fire();}catch(e){};"); 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 app doesn't want to run in background
if (!this.keepRunning || this.activityResultKeepRunning) { if (!this.keepRunning || this.activityResultKeepRunning) {
@ -646,9 +667,6 @@ public class DroidGap extends PhonegapActivity {
this.activityResultKeepRunning = false; this.activityResultKeepRunning = false;
} }
// Forward to plugins
this.pluginManager.onResume();
// Resume JavaScript timers (including setInterval) // Resume JavaScript timers (including setInterval)
this.appView.resumeTimers(); this.appView.resumeTimers();
} }
@ -698,13 +716,29 @@ public class DroidGap extends PhonegapActivity {
this.callbackServer.sendJavascript(statement); 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 * Provides a hook for calling "alert" from javascript. Useful for
* debugging your javascript. * debugging your javascript.
*/ */
public class GapClient extends WebChromeClient { public class GapClient extends WebChromeClient {
private Context ctx; private DroidGap ctx;
/** /**
* Constructor. * Constructor.
@ -712,7 +746,7 @@ public class DroidGap extends PhonegapActivity {
* @param ctx * @param ctx
*/ */
public GapClient(Context ctx) { public GapClient(Context ctx) {
this.ctx = ctx; this.ctx = (DroidGap)ctx;
} }
/** /**
@ -785,7 +819,7 @@ public class DroidGap extends PhonegapActivity {
@Override @Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
boolean reqOk = false; boolean reqOk = false;
if (((DroidGap)(this.ctx)).url.equals(url)) { if (this.ctx.urlFile.equals(this.ctx.getUrlFile(url))) {
reqOk = true; reqOk = true;
} }
@ -1161,6 +1195,7 @@ public class DroidGap extends PhonegapActivity {
// If back key is bound, then send event to JavaScript // If back key is bound, then send event to JavaScript
if (this.bound) { if (this.bound) {
this.appView.loadUrl("javascript:PhoneGap.fireEvent('backbutton');"); this.appView.loadUrl("javascript:PhoneGap.fireEvent('backbutton');");
return true;
} }
// If not bound // 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 // Go to previous page in webview if it is possible to go back
if (this.appView.canGoBack()) { if (this.appView.canGoBack()) {
this.appView.goBack(); this.appView.goBack();
return true;
} }
// If not, then invoke behavior of super class // If not, then invoke behavior of super class
@ -1181,11 +1217,13 @@ public class DroidGap extends PhonegapActivity {
// If menu key // If menu key
else if (keyCode == KeyEvent.KEYCODE_MENU) { else if (keyCode == KeyEvent.KEYCODE_MENU) {
this.appView.loadUrl("javascript:PhoneGap.fireEvent('menubutton');"); this.appView.loadUrl("javascript:PhoneGap.fireEvent('menubutton');");
return true;
} }
// If search key // If search key
else if (keyCode == KeyEvent.KEYCODE_SEARCH) { else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
this.appView.loadUrl("javascript:PhoneGap.fireEvent('searchbutton');"); this.appView.loadUrl("javascript:PhoneGap.fireEvent('searchbutton');");
return true;
} }
return false; return false;

View File

@ -10,6 +10,7 @@ package com.phonegap;
import java.io.*; import java.io.*;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLDecoder;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
@ -229,15 +230,16 @@ public class FileUtils extends Plugin {
* @throws JSONException * @throws JSONException
*/ */
private JSONObject resolveLocalFileSystemURI(String url) throws IOException, 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 // Test to see if this is a valid URL first
@SuppressWarnings("unused") @SuppressWarnings("unused")
URL testUrl = new URL(url); URL testUrl = new URL(decoded);
File fp = null; File fp = null;
if (url.startsWith("file://")) { if (decoded.startsWith("file://")) {
fp = new File(url.substring(7, url.length())); fp = new File(decoded.substring(7, decoded.length()));
} else { } else {
fp = new File(url); fp = new File(decoded);
} }
if (!fp.exists()) { if (!fp.exists()) {
throw new FileNotFoundException(); throw new FileNotFoundException();

View File

@ -54,13 +54,17 @@ public interface IPlugin {
/** /**
* Called when the system is about to start resuming a previous activity. * 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. * 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. * The final call you receive before your activity is destroyed.

View File

@ -64,14 +64,24 @@ public abstract class Plugin implements IPlugin {
/** /**
* Called when the system is about to start resuming a previous activity. * 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. * 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) {
} }
/** /**

View File

@ -13,6 +13,7 @@ import java.util.Map.Entry;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import android.content.Intent;
import android.webkit.WebView; import android.webkit.WebView;
/** /**
@ -229,27 +230,31 @@ public final class PluginManager {
/** /**
* Called when the system is about to start resuming a previous activity. * 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<Entry<String,Plugin>> s = this.plugins.entrySet(); java.util.Set<Entry<String,Plugin>> s = this.plugins.entrySet();
java.util.Iterator<Entry<String,Plugin>> it = s.iterator(); java.util.Iterator<Entry<String,Plugin>> it = s.iterator();
while(it.hasNext()) { while(it.hasNext()) {
Entry<String,Plugin> entry = it.next(); Entry<String,Plugin> entry = it.next();
Plugin plugin = entry.getValue(); Plugin plugin = entry.getValue();
plugin.onPause(); plugin.onPause(multitasking);
} }
} }
/** /**
* Called when the activity will start interacting with the user. * 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<Entry<String,Plugin>> s = this.plugins.entrySet(); java.util.Set<Entry<String,Plugin>> s = this.plugins.entrySet();
java.util.Iterator<Entry<String,Plugin>> it = s.iterator(); java.util.Iterator<Entry<String,Plugin>> it = s.iterator();
while(it.hasNext()) { while(it.hasNext()) {
Entry<String,Plugin> entry = it.next(); Entry<String,Plugin> entry = it.next();
Plugin plugin = entry.getValue(); Plugin plugin = entry.getValue();
plugin.onResume(); plugin.onResume(multitasking);
} }
} }
@ -265,4 +270,17 @@ public final class PluginManager {
plugin.onDestroy(); plugin.onDestroy();
} }
} }
/**
* Called when the activity receives a new intent.
*/
public void onNewIntent(Intent intent) {
java.util.Set<Entry<String,Plugin>> s = this.plugins.entrySet();
java.util.Iterator<Entry<String,Plugin>> it = s.iterator();
while(it.hasNext()) {
Entry<String,Plugin> entry = it.next();
Plugin plugin = entry.getValue();
plugin.onNewIntent(intent);
}
}
} }

View File

@ -33,12 +33,19 @@ class Update
# TODO need to allow for www import inc icon # TODO need to allow for www import inc icon
def copy_libs def copy_libs
puts "Copying over libraries and assets..." puts "Copying over libraries and assets..."
version = IO.read(File.join(@framework_dir, '../VERSION'))
FileUtils.mkdir_p File.join(@path, "libs") FileUtils.cp File.join(@framework_dir, "phonegap.#{ version }.jar"), File.join(@path, "libs")
FileUtils.cp File.join(@framework_dir, "phonegap.jar"), File.join(@path, "libs")
FileUtils.mkdir_p File.join(@path, "assets", "www") # concat JS and put into www folder. this can be overridden in the config.xml via @app_js_dir
FileUtils.cp File.join(@framework_dir, "assets", "www", "phonegap.js"), File.join(@path, "assets", "www") 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
# #
end end