2010-10-19 04:31:16 +08:00
/ *
* 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.
2009-04-02 07:56:43 +08:00
*
2010-10-19 04:31:16 +08:00
* Copyright ( c ) 2005 - 2010 , Nitobi Software Inc .
* Copyright ( c ) 2010 , IBM Corporation
2009-04-02 07:56:43 +08:00
* /
2010-10-19 04:31:16 +08:00
package com.phonegap ;
2009-04-02 07:56:43 +08:00
import android.app.AlertDialog ;
import android.content.Context ;
2009-12-17 03:09:32 +08:00
import android.content.DialogInterface ;
2009-07-18 07:23:18 +08:00
import android.content.Intent ;
2009-04-02 07:56:43 +08:00
import android.content.res.Configuration ;
2010-06-05 05:54:16 +08:00
import android.graphics.Bitmap ;
2009-11-25 08:51:23 +08:00
import android.graphics.Color ;
2010-04-24 07:18:11 +08:00
import android.net.Uri ;
2009-04-02 07:56:43 +08:00
import android.os.Bundle ;
import android.util.Log ;
2009-12-17 04:50:08 +08:00
import android.view.KeyEvent ;
2009-11-25 08:51:23 +08:00
import android.view.ViewGroup ;
2009-04-02 07:56:43 +08:00
import android.view.Window ;
import android.view.WindowManager ;
import android.webkit.JsResult ;
import android.webkit.WebChromeClient ;
2009-11-10 09:22:36 +08:00
import android.webkit.WebSettings ;
2009-11-26 09:25:16 +08:00
import android.webkit.WebStorage ;
2009-04-02 07:56:43 +08:00
import android.webkit.WebView ;
2010-04-24 07:18:11 +08:00
import android.webkit.WebViewClient ;
2010-07-08 06:18:14 +08:00
import android.webkit.GeolocationPermissions.Callback ;
2009-11-13 02:51:22 +08:00
import android.webkit.WebSettings.LayoutAlgorithm ;
2010-07-31 03:23:55 +08:00
import android.widget.ImageView ;
2009-11-25 08:51:23 +08:00
import android.widget.LinearLayout ;
2010-11-06 02:10:51 +08:00
import com.phonegap.api.Plugin ;
import com.phonegap.api.PluginManager ;
import com.phonegap.api.PhonegapActivity ;
2009-04-02 07:56:43 +08:00
2010-08-27 22:31:57 +08:00
/ * *
* This class is the main Android activity that represents the PhoneGap
* application . It should be extended by the user to load the specific
* html file that contains the application .
*
* As an example :
*
* package com.phonegap.examples ;
* import android.app.Activity ;
* import android.os.Bundle ;
* import com.phonegap.* ;
*
* public class Examples extends DroidGap {
* @Override
* public void onCreate ( Bundle savedInstanceState ) {
* super . onCreate ( savedInstanceState ) ;
2010-11-12 01:34:12 +08:00
*
* // Initialize activity
* super . init ( ) ;
*
* // Set properties for activity
* super . setProperty ( " loadingDialog " , false ) ; // hide loading dialog (default is to show it)
*
* // Add your plugins here or in JavaScript
* super . addService ( " MyService " , " com.phonegap.examples.MyService " ) ;
*
* // Clear cache if you want
* super . appView . clearCache ( true ) ;
*
* // Load your application
2010-08-27 22:31:57 +08:00
* super . loadUrl ( " file:///android_asset/www/index.html " ) ;
* }
* }
* /
2010-11-06 02:10:51 +08:00
public class DroidGap extends PhonegapActivity {
2010-09-07 02:13:09 +08:00
private static final String LOG_TAG = " DroidGap " ;
2010-09-03 00:27:48 +08:00
protected WebView appView ; // The webview for our app
2010-09-07 02:13:09 +08:00
private LinearLayout root ;
private BrowserKey mKey ;
2010-09-04 03:01:24 +08:00
public CallbackServer callbackServer ;
2010-10-08 22:18:10 +08:00
protected PluginManager pluginManager ;
2010-09-07 02:13:09 +08:00
2010-08-26 23:39:02 +08:00
private String url ; // The initial URL for our app
private String baseUrl ; // The base of the initial URL for our app
2010-09-04 03:01:24 +08:00
2010-11-12 01:34:12 +08:00
// Plugin to call when activity result is received
private Plugin activityResultCallback = null ;
// Flag indicates that "app loading" dialog should be hidden once page is loaded.
// The default is to hide it once PhoneGap JavaScript code has initialized.
protected boolean hideLoadingDialogOnPageLoad = false ;
// Flag indicates that a URL navigated to from PhoneGap app should be loaded into same webview
// instead of being loaded into the web browser.
protected boolean loadInWebView = false ;
2010-11-12 05:59:35 +08:00
// Splash screen drawable resource to display when starting app
protected int splashscreen = 0 ;
2010-09-04 03:14:28 +08:00
/ * *
* Called when the activity is first created .
*
* @param savedInstanceState
* /
2010-11-12 01:34:12 +08:00
@Override
2009-04-02 07:56:43 +08:00
public void onCreate ( Bundle savedInstanceState ) {
2010-11-12 04:00:56 +08:00
super . onCreate ( savedInstanceState ) ;
getWindow ( ) . requestFeature ( Window . FEATURE_NO_TITLE ) ;
getWindow ( ) . setFlags ( WindowManager . LayoutParams . FLAG_FORCE_NOT_FULLSCREEN ,
WindowManager . LayoutParams . FLAG_FORCE_NOT_FULLSCREEN ) ;
// This builds the view. We could probably get away with NOT having a LinearLayout, but I like having a bucket!
root = new LinearLayout ( this ) ;
root . setOrientation ( LinearLayout . VERTICAL ) ;
root . setBackgroundColor ( Color . BLACK ) ;
root . setLayoutParams ( new LinearLayout . LayoutParams ( ViewGroup . LayoutParams . FILL_PARENT ,
ViewGroup . LayoutParams . FILL_PARENT , 0 . 0F ) ) ;
// If url was passed in to intent, then init webview, which will load the url
Bundle bundle = this . getIntent ( ) . getExtras ( ) ;
if ( bundle ! = null ) {
String url = bundle . getString ( " url " ) ;
if ( url ! = null ) {
this . init ( ) ;
}
}
}
2010-09-10 00:01:56 +08:00
/ * *
* Create and initialize web container .
* /
2010-11-12 01:34:12 +08:00
public void init ( ) {
2010-07-31 03:23:55 +08:00
2010-09-10 00:01:56 +08:00
// Create web container
this . appView = new WebView ( DroidGap . this ) ;
this . appView . setLayoutParams ( new LinearLayout . LayoutParams (
2010-07-31 03:23:55 +08:00
ViewGroup . LayoutParams . FILL_PARENT ,
ViewGroup . LayoutParams . FILL_PARENT ,
1 . 0F ) ) ;
2009-11-26 09:25:16 +08:00
WebViewReflect . checkCompatibility ( ) ;
2010-07-31 03:23:55 +08:00
if ( android . os . Build . VERSION . RELEASE . startsWith ( " 2. " ) ) {
2010-09-10 00:01:56 +08:00
this . appView . setWebChromeClient ( new EclairClient ( DroidGap . this ) ) ;
2010-08-27 22:31:57 +08:00
}
else {
2010-09-10 00:01:56 +08:00
this . appView . setWebChromeClient ( new GapClient ( DroidGap . this ) ) ;
2009-12-09 06:08:48 +08:00
}
2010-07-07 02:43:25 +08:00
2010-09-10 00:01:56 +08:00
this . appView . setWebViewClient ( new GapViewClient ( this ) ) ;
2010-08-25 02:19:22 +08:00
2010-09-10 00:01:56 +08:00
this . appView . setInitialScale ( 100 ) ;
this . appView . setVerticalScrollBarEnabled ( false ) ;
this . appView . requestFocusFromTouch ( ) ;
2010-08-18 02:26:39 +08:00
2010-09-10 00:01:56 +08:00
// Enable JavaScript
WebSettings settings = this . appView . getSettings ( ) ;
2009-11-10 09:22:36 +08:00
settings . setJavaScriptEnabled ( true ) ;
settings . setJavaScriptCanOpenWindowsAutomatically ( true ) ;
2009-11-13 02:51:22 +08:00
settings . setLayoutAlgorithm ( LayoutAlgorithm . NORMAL ) ;
2009-11-26 09:25:16 +08:00
2010-09-10 00:01:56 +08:00
// Enable database
Package pack = this . getClass ( ) . getPackage ( ) ;
String appPackage = pack . getName ( ) ;
2009-11-26 09:25:16 +08:00
WebViewReflect . setStorage ( settings , true , " /data/data/ " + appPackage + " /app_database/ " ) ;
2010-09-10 00:01:56 +08:00
// Enable DOM storage
2010-03-03 03:14:20 +08:00
WebViewReflect . setDomStorage ( settings ) ;
2010-09-10 00:01:56 +08:00
// Enable built-in geolocation
2010-07-08 06:18:14 +08:00
WebViewReflect . setGeolocationEnabled ( settings , true ) ;
2010-09-10 00:01:56 +08:00
// Bind PhoneGap objects to JavaScript
this . bindBrowser ( this . appView ) ;
2010-11-12 01:34:12 +08:00
// Add web view
root . addView ( this . appView ) ;
setContentView ( root ) ;
// Handle activity parameters
this . handleActivityParameters ( ) ;
2010-07-08 06:18:14 +08:00
}
2010-11-12 01:34:12 +08:00
2010-11-12 04:00:56 +08:00
/ * *
* Bind PhoneGap objects to JavaScript .
*
* @param appView
* /
private void bindBrowser ( WebView appView ) {
this . callbackServer = new CallbackServer ( ) ;
this . pluginManager = new PluginManager ( appView , this ) ;
this . mKey = new BrowserKey ( appView , this ) ;
// This creates the new javascript interfaces for PhoneGap
appView . addJavascriptInterface ( this . pluginManager , " PluginManager " ) ;
appView . addJavascriptInterface ( this . mKey , " BackButton " ) ;
appView . addJavascriptInterface ( this . callbackServer , " CallbackServer " ) ;
appView . addJavascriptInterface ( new SplashScreen ( this ) , " SplashScreen " ) ;
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 " ) ;
}
2010-11-12 01:34:12 +08:00
/ * *
* Look at activity parameters and process them .
* /
private void handleActivityParameters ( ) {
2010-11-12 05:59:35 +08:00
// If spashscreen
this . splashscreen = this . getProperty ( " splashscreen " , 0 ) ;
if ( this . splashscreen ! = 0 ) {
appView . setBackgroundColor ( 0 ) ;
appView . setBackgroundResource ( splashscreen ) ;
}
2010-11-12 04:00:56 +08:00
// If loadingDialog, then show the App loading dialog
if ( this . getProperty ( " loadingDialog " , true ) ) {
this . pluginManager . exec ( " Notification " , " activityStart " , null , " [ \" Wait \" , \" Loading Application... \" ] " , false ) ;
}
2010-09-10 00:01:56 +08:00
2010-11-12 04:00:56 +08:00
// If hideLoadingDialogOnPageLoad
this . hideLoadingDialogOnPageLoad = this . getProperty ( " hideLoadingDialogOnPageLoad " , false ) ;
2010-11-12 01:34:12 +08:00
2010-11-12 04:00:56 +08:00
// If loadInWebView
this . loadInWebView = this . getProperty ( " loadInWebView " , false ) ;
2010-11-12 01:34:12 +08:00
2010-11-12 04:00:56 +08:00
// If url specified, then load it
String url = this . getProperty ( " url " , null ) ;
if ( url ! = null ) {
System . out . println ( " Loading initial URL= " + url ) ;
this . loadUrl ( url ) ;
}
}
/ * *
* Load the url into the webview .
*
* @param url
* /
public void loadUrl ( final String url ) {
System . out . println ( " loadUrl( " + url + " ) " ) ;
this . url = url ;
int i = url . lastIndexOf ( '/' ) ;
if ( i > 0 ) {
this . baseUrl = url . substring ( 0 , i ) ;
}
else {
this . baseUrl = this . url ;
}
System . out . println ( " url= " + url + " baseUrl= " + baseUrl ) ;
// Init web view if not already done
if ( this . appView = = null ) {
this . init ( ) ;
}
// Initialize callback server
this . callbackServer . init ( url ) ;
// Load URL on UI thread
this . runOnUiThread ( new Runnable ( ) {
public void run ( ) {
DroidGap . this . appView . loadUrl ( url ) ;
}
} ) ;
2010-11-12 01:34:12 +08:00
}
2010-07-08 06:18:14 +08:00
2010-11-12 01:34:12 +08:00
@Override
2010-08-12 23:51:12 +08:00
/ * *
* Called by the system when the device configuration changes while your activity is running .
*
* @param Configuration newConfig
* /
2009-04-02 07:56:43 +08:00
public void onConfigurationChanged ( Configuration newConfig ) {
2010-11-12 04:00:56 +08:00
//don't reload the current page when the orientation is changed
super . onConfigurationChanged ( newConfig ) ;
2010-11-12 01:34:12 +08:00
}
/ * *
* Get boolean property for activity .
*
* @param name
* @param defaultValue
* @return
* /
protected boolean getProperty ( String name , boolean defaultValue ) {
Bundle bundle = this . getIntent ( ) . getExtras ( ) ;
if ( bundle = = null ) {
return defaultValue ;
}
Boolean p = ( Boolean ) bundle . get ( name ) ;
if ( p = = null ) {
return defaultValue ;
}
return p . booleanValue ( ) ;
}
/ * *
* Get int property for activity .
*
* @param name
* @param defaultValue
* @return
* /
protected int getProperty ( String name , int defaultValue ) {
Bundle bundle = this . getIntent ( ) . getExtras ( ) ;
if ( bundle = = null ) {
return defaultValue ;
}
Integer p = ( Integer ) bundle . get ( name ) ;
if ( p = = null ) {
return defaultValue ;
}
return p . intValue ( ) ;
}
/ * *
* Get string property for activity .
*
* @param name
* @param defaultValue
* @return
* /
protected String getProperty ( String name , String defaultValue ) {
Bundle bundle = this . getIntent ( ) . getExtras ( ) ;
if ( bundle = = null ) {
return defaultValue ;
}
String p = bundle . getString ( name ) ;
if ( p = = null ) {
return defaultValue ;
}
return p ;
}
/ * *
* Get double property for activity .
*
* @param name
* @param defaultValue
* @return
* /
protected double getProperty ( String name , double defaultValue ) {
Bundle bundle = this . getIntent ( ) . getExtras ( ) ;
if ( bundle = = null ) {
return defaultValue ;
}
Double p = ( Double ) bundle . get ( name ) ;
if ( p = = null ) {
return defaultValue ;
}
return p . doubleValue ( ) ;
}
/ * *
* Set boolean property on activity .
*
* @param name
* @param value
* /
protected void setProperty ( String name , boolean value ) {
if ( this . appView ! = null ) {
System . out . println ( " Setting property after webview is already initialized - no effect. " ) ;
}
this . getIntent ( ) . putExtra ( name , value ) ;
}
/ * *
* Set int property on activity .
*
* @param name
* @param value
* /
protected void setProperty ( String name , int value ) {
if ( this . appView ! = null ) {
System . out . println ( " Setting property after webview is already initialized - no effect. " ) ;
}
this . getIntent ( ) . putExtra ( name , value ) ;
}
/ * *
* Set string property on activity .
*
* @param name
* @param value
* /
protected void setProperty ( String name , String value ) {
if ( this . appView ! = null ) {
System . out . println ( " Setting property after webview is already initialized - no effect. " ) ;
}
this . getIntent ( ) . putExtra ( name , value ) ;
}
/ * *
* Set double property on activity .
*
* @param name
* @param value
* /
protected void setProperty ( String name , double value ) {
if ( this . appView ! = null ) {
System . out . println ( " Setting property after webview is already initialized - no effect. " ) ;
}
this . getIntent ( ) . putExtra ( name , value ) ;
}
2010-08-12 23:51:12 +08:00
@Override
/ * *
* Called when the system is about to start resuming a previous activity .
* /
2010-09-08 02:59:54 +08:00
protected void onPause ( ) {
2010-08-12 23:51:12 +08:00
super . onPause ( ) ;
2010-08-20 04:41:06 +08:00
2010-09-08 02:59:54 +08:00
// Forward to plugins
this . pluginManager . onPause ( ) ;
2010-08-20 04:41:06 +08:00
// Send pause event to JavaScript
2010-09-10 00:01:56 +08:00
this . appView . loadUrl ( " javascript:try{PhoneGap.onPause.fire();}catch(e){}; " ) ;
2010-08-12 23:51:12 +08:00
// Pause JavaScript timers (including setInterval)
2010-09-10 00:01:56 +08:00
this . appView . pauseTimers ( ) ;
2010-08-12 23:51:12 +08:00
}
@Override
/ * *
* Called when the activity will start interacting with the user .
* /
2010-09-08 02:59:54 +08:00
protected void onResume ( ) {
2010-08-12 23:51:12 +08:00
super . onResume ( ) ;
2010-08-20 04:41:06 +08:00
2010-09-08 02:59:54 +08:00
// Forward to plugins
this . pluginManager . onResume ( ) ;
2010-09-04 03:14:28 +08:00
2010-08-20 04:41:06 +08:00
// Send resume event to JavaScript
2010-09-10 00:01:56 +08:00
this . appView . loadUrl ( " javascript:try{PhoneGap.onResume.fire();}catch(e){}; " ) ;
2010-08-12 23:51:12 +08:00
// Resume JavaScript timers (including setInterval)
2010-09-10 00:01:56 +08:00
this . appView . resumeTimers ( ) ;
2010-08-12 23:51:12 +08:00
}
2009-04-02 07:56:43 +08:00
2010-08-12 23:51:12 +08:00
@Override
/ * *
* The final call you receive before your activity is destroyed .
* /
public void onDestroy ( ) {
super . onDestroy ( ) ;
2010-08-26 23:39:02 +08:00
// Make sure pause event is sent if onPause hasn't been called before onDestroy
2010-09-10 00:01:56 +08:00
this . appView . loadUrl ( " javascript:try{PhoneGap.onPause.fire();}catch(e){}; " ) ;
2010-08-26 23:39:02 +08:00
2010-08-12 23:51:12 +08:00
// Load blank page so that JavaScript onunload is called
2010-09-10 00:01:56 +08:00
this . appView . loadUrl ( " about:blank " ) ;
2010-08-12 23:51:12 +08:00
// Clean up objects
2010-09-10 00:01:56 +08:00
if ( this . mKey ! = null ) {
2010-08-19 02:12:53 +08:00
}
2010-09-04 03:14:28 +08:00
2010-09-08 02:59:54 +08:00
// Forward to plugins
this . pluginManager . onDestroy ( ) ;
2010-09-07 02:13:09 +08:00
2010-09-10 00:01:56 +08:00
if ( this . callbackServer ! = null ) {
this . callbackServer . destroy ( ) ;
2010-08-19 02:12:53 +08:00
}
2010-08-12 23:51:12 +08:00
}
2010-09-11 00:31:22 +08:00
/ * *
* Add a class that implements a service .
*
* @param serviceType
* @param className
* /
public void addService ( String serviceType , String className ) {
this . pluginManager . addService ( serviceType , className ) ;
}
2010-08-19 02:12:53 +08:00
/ * *
* Send JavaScript statement back to JavaScript .
2010-11-12 01:34:12 +08:00
* ( This is a convenience method )
2010-08-19 02:12:53 +08:00
*
* @param message
* /
public void sendJavascript ( String statement ) {
this . callbackServer . sendJavascript ( statement ) ;
}
/ * *
* Get the port that the callback server is listening on .
*
* @return
* /
public int getPort ( ) {
return this . callbackServer . getPort ( ) ;
}
2010-04-24 07:18:11 +08:00
2010-09-07 23:33:08 +08:00
/ * *
* Provides a hook for calling " alert " from javascript . Useful for
* debugging your javascript .
* /
public class GapClient extends WebChromeClient {
2010-09-10 00:01:56 +08:00
private Context ctx ;
/ * *
* Constructor .
*
* @param ctx
* /
2010-09-07 23:33:08 +08:00
public GapClient ( Context ctx ) {
2010-09-10 00:01:56 +08:00
this . ctx = ctx ;
2010-09-07 23:33:08 +08:00
}
2010-09-10 00:01:56 +08:00
2010-09-07 23:33:08 +08:00
/ * *
* Tell the client to display a javascript alert dialog .
*
* @param view
* @param url
* @param message
* @param result
* /
@Override
public boolean onJsAlert ( WebView view , String url , String message , final JsResult result ) {
Log . d ( LOG_TAG , message ) ;
2010-09-10 00:01:56 +08:00
AlertDialog . Builder dlg = new AlertDialog . Builder ( this . ctx ) ;
2010-09-07 23:33:08 +08:00
dlg . setMessage ( message ) ;
dlg . setTitle ( " Alert " ) ;
dlg . setCancelable ( false ) ;
dlg . setPositiveButton ( android . R . string . ok ,
new AlertDialog . OnClickListener ( ) {
public void onClick ( DialogInterface dialog , int which ) {
result . confirm ( ) ;
}
} ) ;
dlg . create ( ) ;
dlg . show ( ) ;
return true ;
}
2009-12-17 03:09:32 +08:00
2010-09-07 23:33:08 +08:00
/ * *
* Tell the client to display a confirm dialog to the user .
*
* @param view
* @param url
* @param message
* @param result
* /
@Override
public boolean onJsConfirm ( WebView view , String url , String message , final JsResult result ) {
2010-09-10 00:01:56 +08:00
AlertDialog . Builder dlg = new AlertDialog . Builder ( this . ctx ) ;
2010-09-07 23:33:08 +08:00
dlg . setMessage ( message ) ;
dlg . setTitle ( " Confirm " ) ;
dlg . setCancelable ( false ) ;
dlg . setPositiveButton ( android . R . string . ok ,
new DialogInterface . OnClickListener ( ) {
public void onClick ( DialogInterface dialog , int which ) {
result . confirm ( ) ;
}
} ) ;
dlg . setNegativeButton ( android . R . string . cancel ,
new DialogInterface . OnClickListener ( ) {
public void onClick ( DialogInterface dialog , int which ) {
result . cancel ( ) ;
}
} ) ;
dlg . create ( ) ;
dlg . show ( ) ;
return true ;
}
2009-12-01 07:41:24 +08:00
2010-09-07 23:33:08 +08:00
}
2010-09-10 00:01:56 +08:00
/ * *
* WebChromeClient that extends GapClient with additional support for Android 2 . X
* /
public final class EclairClient extends GapClient {
2010-11-12 04:00:56 +08:00
private String TAG = " PhoneGapLog " ;
private long MAX_QUOTA = 100 * 1024 * 1024 ;
/ * *
* Constructor .
*
* @param ctx
* /
public EclairClient ( Context ctx ) {
super ( ctx ) ;
}
/ * *
* Handle database quota exceeded notification .
*
* @param url
* @param databaseIdentifier
* @param currentQuota
* @param estimatedSize
* @param totalUsedQuota
* @param quotaUpdater
* /
@Override
public void onExceededDatabaseQuota ( String url , String databaseIdentifier , long currentQuota , long estimatedSize ,
long totalUsedQuota , WebStorage . QuotaUpdater quotaUpdater )
{
Log . d ( TAG , " event raised onExceededDatabaseQuota estimatedSize: " + Long . toString ( estimatedSize ) + " currentQuota: " + Long . toString ( currentQuota ) + " totalUsedQuota: " + Long . toString ( totalUsedQuota ) ) ;
if ( estimatedSize < MAX_QUOTA )
{
//increase for 1Mb
long newQuota = estimatedSize ;
Log . d ( TAG , " calling quotaUpdater.updateQuota newQuota: " + Long . toString ( newQuota ) ) ;
quotaUpdater . updateQuota ( newQuota ) ;
}
else
{
// Set the quota to whatever it is and force an error
// TODO: get docs on how to handle this properly
quotaUpdater . updateQuota ( currentQuota ) ;
}
}
// console.log in api level 7: http://developer.android.com/guide/developing/debug-tasks.html
@Override
public void onConsoleMessage ( String message , int lineNumber , String sourceID )
{
// This is a kludgy hack!!!!
Log . d ( TAG , sourceID + " : Line " + Integer . toString ( lineNumber ) + " : " + message ) ;
}
@Override
public void onGeolocationPermissionsShowPrompt ( String origin , Callback callback ) {
// TODO Auto-generated method stub
super . onGeolocationPermissionsShowPrompt ( origin , callback ) ;
callback . invoke ( origin , true , false ) ;
}
}
2010-08-27 22:31:57 +08:00
/ * *
* The webview client receives notifications about appView
* /
2010-08-25 02:19:22 +08:00
public class GapViewClient extends WebViewClient {
2010-08-27 03:15:34 +08:00
2010-09-10 00:01:56 +08:00
DroidGap ctx ;
2010-08-25 02:19:22 +08:00
2010-08-26 23:39:02 +08:00
/ * *
* Constructor .
*
* @param ctx
* /
public GapViewClient ( DroidGap ctx ) {
2010-09-10 00:01:56 +08:00
this . ctx = ctx ;
2010-08-25 02:19:22 +08:00
}
2010-08-26 23:39:02 +08:00
/ * *
* Give the host application a chance to take over the control when a new url
* is about to be loaded in the current WebView .
*
* @param view The WebView that is initiating the callback .
* @param url The url to be loaded .
* @return true to override , false for default behavior
* /
@Override
public boolean shouldOverrideUrlLoading ( WebView view , String url ) {
// If dialing phone (tel:5551212)
if ( url . startsWith ( WebView . SCHEME_TEL ) ) {
try {
Intent intent = new Intent ( Intent . ACTION_DIAL ) ;
intent . setData ( Uri . parse ( url ) ) ;
startActivity ( intent ) ;
} catch ( android . content . ActivityNotFoundException e ) {
System . out . println ( " Error dialing " + url + " : " + e . toString ( ) ) ;
}
return true ;
}
// If displaying map (geo:0,0?q=address)
2010-10-28 23:18:28 +08:00
else if ( url . startsWith ( " geo: " ) ) {
2010-08-26 23:39:02 +08:00
try {
Intent intent = new Intent ( Intent . ACTION_VIEW ) ;
intent . setData ( Uri . parse ( url ) ) ;
startActivity ( intent ) ;
} catch ( android . content . ActivityNotFoundException e ) {
System . out . println ( " Error showing map " + url + " : " + e . toString ( ) ) ;
}
return true ;
}
// If sending email (mailto:abc@corp.com)
else if ( url . startsWith ( WebView . SCHEME_MAILTO ) ) {
try {
Intent intent = new Intent ( Intent . ACTION_VIEW ) ;
intent . setData ( Uri . parse ( url ) ) ;
startActivity ( intent ) ;
} catch ( android . content . ActivityNotFoundException e ) {
System . out . println ( " Error sending email " + url + " : " + e . toString ( ) ) ;
}
return true ;
}
// If sms:5551212
else if ( url . startsWith ( " sms: " ) ) {
try {
Intent intent = new Intent ( Intent . ACTION_VIEW ) ;
intent . setData ( Uri . parse ( url ) ) ;
intent . putExtra ( " address " , url . substring ( 4 ) ) ;
intent . setType ( " vnd.android-dir/mms-sms " ) ;
startActivity ( intent ) ;
} catch ( android . content . ActivityNotFoundException e ) {
System . out . println ( " Error sending sms " + url + " : " + e . toString ( ) ) ;
}
return true ;
}
// If http, https or file
else if ( url . startsWith ( " http:// " ) | | url . startsWith ( " https:// " ) | | url . startsWith ( " file:// " ) ) {
int i = url . lastIndexOf ( '/' ) ;
String newBaseUrl = url ;
if ( i > 0 ) {
newBaseUrl = url . substring ( 0 , i ) ;
}
// If our app or file:, then load into our webview
2010-09-10 00:01:56 +08:00
if ( this . ctx . loadInWebView | | url . startsWith ( " file:// " ) | | this . ctx . baseUrl . equals ( newBaseUrl ) ) {
this . ctx . appView . loadUrl ( url ) ;
2010-08-26 23:39:02 +08:00
}
// If not our application, let default viewer handle
else {
try {
Intent intent = new Intent ( Intent . ACTION_VIEW ) ;
intent . setData ( Uri . parse ( url ) ) ;
startActivity ( intent ) ;
} catch ( android . content . ActivityNotFoundException e ) {
System . out . println ( " Error loading url " + url + " : " + e . toString ( ) ) ;
}
}
return true ;
}
return false ;
}
/ * *
* Notify the host application that a page has finished loading .
*
* @param view The webview initiating the callback .
* @param url The url of the page .
* /
@Override
2010-08-25 02:19:22 +08:00
public void onPageFinished ( WebView view , String url ) {
2010-08-26 23:39:02 +08:00
super . onPageFinished ( view , url ) ;
2010-08-25 02:19:22 +08:00
// Try firing the onNativeReady event in JS. If it fails because the JS is
// not loaded yet then just set a flag so that the onNativeReady can be fired
// from the JS side when the JS gets to that code.
2010-08-26 23:39:02 +08:00
appView . loadUrl ( " javascript:try{ PhoneGap.onNativeReady.fire();}catch(e){_nativeReady = true;} " ) ;
2010-11-12 05:59:35 +08:00
// If splash screen is showing, clear it
if ( this . ctx . splashscreen ! = 0 ) {
this . ctx . splashscreen = 0 ;
appView . setBackgroundResource ( 0 ) ;
}
2010-11-12 01:34:12 +08:00
// Stop "app loading" spinner if showing
if ( this . ctx . hideLoadingDialogOnPageLoad ) {
this . ctx . hideLoadingDialogOnPageLoad = false ;
this . ctx . pluginManager . exec ( " Notification " , " activityStop " , null , " [] " , false ) ;
}
2010-08-25 02:19:22 +08:00
}
}
2010-11-12 04:08:55 +08:00
/ * *
* Called when a key is pressed .
*
* @param keyCode
* @param event
* /
@Override
public boolean onKeyDown ( int keyCode , KeyEvent event ) {
// If back key
if ( keyCode = = KeyEvent . KEYCODE_BACK ) {
// If back key is bound, then send event to JavaScript
if ( mKey . isBound ( ) ) {
this . appView . loadUrl ( " javascript:document.keyEvent.backTrigger() " ) ;
}
// If not bound
else {
// Go to previous page in webview if it is possible to go back
if ( this . appView . canGoBack ( ) ) {
this . appView . goBack ( ) ;
}
// If not, then invoke behavior of super class
else {
return super . onKeyDown ( keyCode , event ) ;
}
}
}
2010-11-12 06:20:32 +08:00
// If menu key
else if ( keyCode = = KeyEvent . KEYCODE_MENU ) {
2010-11-12 04:08:55 +08:00
appView . loadUrl ( " javascript:keyEvent.menuTrigger() " ) ;
}
2010-11-12 06:20:32 +08:00
// If search key
else if ( keyCode = = KeyEvent . KEYCODE_SEARCH ) {
appView . loadUrl ( " javascript:keyEvent.searchTrigger() " ) ;
}
2010-11-12 04:08:55 +08:00
return false ;
2009-12-17 04:50:08 +08:00
}
2010-11-12 04:08:55 +08:00
2010-09-04 03:01:24 +08:00
/ * *
2010-09-07 02:13:09 +08:00
* Any calls to Activity . startActivityForResult must use method below , so
2010-09-04 03:01:24 +08:00
* the result can be routed to them correctly .
*
* This is done to eliminate the need to modify DroidGap . java to receive activity results .
*
* @param intent The intent to start
* @param requestCode Identifies who to send the result to
*
* @throws RuntimeException
* /
@Override
public void startActivityForResult ( Intent intent , int requestCode ) throws RuntimeException {
2010-09-07 02:13:09 +08:00
System . out . println ( " startActivityForResult(intent, " + requestCode + " ) " ) ;
if ( requestCode = = - 1 ) {
super . startActivityForResult ( intent , requestCode ) ;
2010-09-04 03:01:24 +08:00
}
else {
2010-09-07 02:13:09 +08:00
throw new RuntimeException ( " PhoneGap Exception: Call startActivityForResult(Command, Intent) instead. " ) ;
2010-09-04 03:01:24 +08:00
}
}
2010-09-07 02:13:09 +08:00
2010-09-04 03:01:24 +08:00
/ * *
2010-09-07 02:13:09 +08:00
* Launch an activity for which you would like a result when it finished . When this activity exits ,
* your onActivityResult ( ) method will be called .
*
* @param command The command object
* @param intent The intent to start
2010-09-17 00:04:27 +08:00
* @param requestCode The request code that is passed to callback to identify the activity
2010-09-04 03:01:24 +08:00
* /
2010-09-17 00:04:27 +08:00
public void startActivityForResult ( Plugin command , Intent intent , int requestCode ) {
this . activityResultCallback = command ;
2010-09-07 02:13:09 +08:00
super . startActivityForResult ( intent , requestCode ) ;
2010-09-04 03:01:24 +08:00
}
2010-09-07 02:13:09 +08:00
@Override
2010-09-03 00:27:48 +08:00
/ * *
* Called when an activity you launched exits , giving you the requestCode you started it with ,
* the resultCode it returned , and any additional data from it .
*
* @param requestCode The request code originally supplied to startActivityForResult ( ) ,
* allowing you to identify who this result came from .
* @param resultCode The integer result code returned by the child activity through its setResult ( ) .
* @param data An Intent , which can return result data to the caller ( various data can be attached to Intent " extras " ) .
* /
protected void onActivityResult ( int requestCode , int resultCode , Intent intent ) {
super . onActivityResult ( requestCode , resultCode , intent ) ;
2010-09-17 00:04:27 +08:00
Plugin callback = this . activityResultCallback ;
2010-09-04 03:01:24 +08:00
if ( callback ! = null ) {
2010-09-07 02:13:09 +08:00
callback . onActivityResult ( requestCode , resultCode , intent ) ;
2010-09-04 03:01:24 +08:00
}
2010-09-08 02:59:54 +08:00
}
2009-09-12 05:30:24 +08:00
}