diff --git a/framework/src/org/apache/cordova/CordovaActivity.java b/framework/src/org/apache/cordova/CordovaActivity.java index 1dadf0b1..684c81b5 100755 --- a/framework/src/org/apache/cordova/CordovaActivity.java +++ b/framework/src/org/apache/cordova/CordovaActivity.java @@ -22,6 +22,8 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Locale; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import org.json.JSONException; import org.json.JSONObject; @@ -76,17 +78,23 @@ import android.widget.LinearLayout; * deprecated in favor of the config.xml file. * */ -public class CordovaActivity extends Activity { +public class CordovaActivity extends Activity implements CordovaInterface { public static String TAG = "CordovaActivity"; // The webview for our app protected CordovaWebView appView; + private final ExecutorService threadPool = Executors.newCachedThreadPool(); + private static int ACTIVITY_STARTING = 0; private static int ACTIVITY_RUNNING = 1; private static int ACTIVITY_EXITING = 2; private int activityState = 0; // 0=starting, 1=running (after 1st resume), 2=shutting down + // Plugin to call when activity result is received + protected int activityResultRequestCode; + protected CordovaPlugin activityResultCallback; + /* * The variables below are used to cache some of the activity properties. */ @@ -99,14 +107,14 @@ public class CordovaActivity extends Activity { // when another application (activity) is started. protected boolean keepRunning = true; + private String initCallbackClass; + // Read from config.xml: protected CordovaPreferences preferences; protected Whitelist internalWhitelist; protected Whitelist externalWhitelist; protected String launchUrl; protected ArrayList pluginEntries; - protected CordovaInterfaceImpl cordovaInterface; - /** * Called when the activity is first created. @@ -138,10 +146,9 @@ public class CordovaActivity extends Activity { super.onCreate(savedInstanceState); - cordovaInterface = makeCordovaInterface(); if(savedInstanceState != null) { - cordovaInterface.restoreInstanceState(savedInstanceState); + initCallbackClass = savedInstanceState.getString("callbackClass"); } } @@ -149,7 +156,6 @@ public class CordovaActivity extends Activity { appView = makeWebView(); createViews(); appView.init(this, pluginEntries, internalWhitelist, externalWhitelist, preferences); - cordovaInterface.setPluginManager(appView.getPluginManager()); // Wire the hardware volume controls to control media if desired. String volumePref = preferences.getString("DefaultVolumeStream", ""); @@ -200,7 +206,14 @@ public class CordovaActivity extends Activity { } /** - * Construct the default web view object. + * Get the Android activity. + */ + @Override public Activity getActivity() { + return this; + } + + /** + * Construct the CordovaWebView object. * * Override this to customize the webview that is used. */ @@ -214,17 +227,6 @@ public class CordovaActivity extends Activity { } catch (Exception e) { throw new RuntimeException("Failed to create webview. ", e); } - return ret; - } - - protected CordovaInterfaceImpl makeCordovaInterface() { - return new CordovaInterfaceImpl(this) { - @Override - public Object onMessage(String id, Object data) { - // Plumb this to CordovaActivity.onMessage for backwards compatibility - return CordovaActivity.this.onMessage(id, data); - } - }; } /** @@ -315,17 +317,36 @@ public class CordovaActivity extends Activity { public void endActivity() { finish(); } - + @Override public void finish() { this.activityState = ACTIVITY_EXITING; super.finish(); } + + /** + * 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 + * @param requestCode The request code that is passed to callback to identify the activity + */ + public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) { + setActivityResultCallback(command); + try { + startActivityForResult(intent, requestCode); + } catch (RuntimeException e) { // E.g.: ActivityNotFoundException + activityResultCallback = null; + throw e; + } + } + @Override public void startActivityForResult(Intent intent, int requestCode, Bundle options) { // Capture requestCode here so that it is captured in the setActivityResultCallback() case. - cordovaInterface.setActivityResultRequestCode(requestCode); + activityResultRequestCode = requestCode; super.startActivityForResult(intent, requestCode, options); } @@ -342,7 +363,29 @@ public class CordovaActivity extends Activity { protected void onActivityResult(int requestCode, int resultCode, Intent intent) { LOG.d(TAG, "Incoming Result. Request code = " + requestCode); super.onActivityResult(requestCode, resultCode, intent); - cordovaInterface.onActivityResult(requestCode, resultCode, intent); + CordovaPlugin callback = this.activityResultCallback; + if(callback == null && initCallbackClass != null) { + // The application was restarted, but had defined an initial callback + // before being shut down. + callback = appView.getPluginManager().getPlugin(initCallbackClass); + } + initCallbackClass = null; + activityResultCallback = null; + + if (callback != null) { + LOG.d(TAG, "We have a callback to send this result to"); + callback.onActivityResult(requestCode, resultCode, intent); + } else { + LOG.w(TAG, "Got an activity result, but no plugin was registered to receive it."); + } + } + + public void setActivityResultCallback(CordovaPlugin plugin) { + // Cancel any previously pending activity. + if (activityResultCallback != null) { + activityResultCallback.onActivityResult(activityResultRequestCode, Activity.RESULT_CANCELED, null); + } + this.activityResultCallback = plugin; } /** @@ -456,15 +499,24 @@ public class CordovaActivity extends Activity { } catch (JSONException e) { e.printStackTrace(); } - } else if ("exit".equals(id)) { + } + else if ("exit".equals(id)) { this.endActivity(); } return null; } + public ExecutorService getThreadPool() { + return threadPool; + } + protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); - cordovaInterface.onSaveInstanceState(outState); + if(this.activityResultCallback != null) + { + String cClass = this.activityResultCallback.getClass().getName(); + outState.putString("callbackClass", cClass); + } } }