mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-20 23:56:20 +08:00
refactored the Command stuff a bit more, added a spashscreen
This commit is contained in:
parent
1af469c8b1
commit
49de553ee8
@ -1,18 +0,0 @@
|
||||
PhoneGap.addPlugin = function(name, obj) {
|
||||
if ( !window.plugins ) {
|
||||
window.plugins = {};
|
||||
}
|
||||
|
||||
if ( !window.plugins[name] ) {
|
||||
window.plugins[name] = obj;
|
||||
}
|
||||
}
|
||||
|
||||
function Cache() {
|
||||
}
|
||||
|
||||
Cache.prototype.getCachedPathForURI = function(uri, success, fail) {
|
||||
PhoneGap.execAsync(success, fail, 'com.phonegap.api.impl.Cache', 'getCachedPathForURI', [uri]);
|
||||
};
|
||||
|
||||
PhoneGap.addPlugin('cache', new Cache());
|
@ -136,6 +136,19 @@ PhoneGap.addConstructor = function(func) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a plugin object to window.plugins
|
||||
*/
|
||||
PhoneGap.addPlugin = function(name, obj) {
|
||||
if ( !window.plugins ) {
|
||||
window.plugins = {};
|
||||
}
|
||||
|
||||
if ( !window.plugins[name] ) {
|
||||
window.plugins[name] = obj;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* onDOMContentLoaded channel is fired when the DOM content
|
||||
* of the page has been parsed.
|
||||
@ -216,23 +229,22 @@ PhoneGap.callbacks = {};
|
||||
* @param {String[]} [args] Zero or more arguments to pass to the method
|
||||
*/
|
||||
PhoneGap.exec = function(clazz, action, args) {
|
||||
CommandManager.exec(clazz, action, callbackId, args.join('__PHONEGAP__'), false);
|
||||
CommandManager.exec(clazz, action, callbackId, JSON.stringify(args), false);
|
||||
};
|
||||
|
||||
PhoneGap.execAsync = function(success, fail, clazz, action, args) {
|
||||
var callbackId = clazz + PhoneGap.callbackId++;
|
||||
PhoneGap.callbacks[callbackId] = {success:success, fail:fail};
|
||||
CommandManager.exec(clazz, action, callbackId, args.join('__PHONEGAP__'), true);
|
||||
return callbackId;
|
||||
return CommandManager.exec(clazz, action, callbackId, JSON.stringify(args), true);
|
||||
};
|
||||
|
||||
PhoneGap.callbackSuccess = function(callbackId, args) {
|
||||
PhoneGap.callbacks[callbackId].success.apply(this, JSON.parse(args));
|
||||
PhoneGap.callbacks[callbackId].success(args);
|
||||
delete PhoneGap.callbacks[callbackId];
|
||||
};
|
||||
|
||||
PhoneGap.callbackFailure = function(callbackId, args) {
|
||||
PhoneGap.callbacks[callbackId].fail.apply(this, JSON.parse(args));
|
||||
PhoneGap.callbackError = function(callbackId, args) {
|
||||
PhoneGap.callbacks[callbackId].fail(args);
|
||||
delete PhoneGap.callbacks[callbackId];
|
||||
};
|
||||
|
||||
@ -353,7 +365,7 @@ PhoneGap.UUIDcreatePart = function(length) {
|
||||
};
|
||||
|
||||
PhoneGap.close = function(context, func, params) {
|
||||
if (null == params) {
|
||||
if (typeof params === 'undefined') {
|
||||
return function() {
|
||||
return func.apply(context, arguments);
|
||||
}
|
||||
|
5
framework/assets/js/splashscreen.js
Normal file
5
framework/assets/js/splashscreen.js
Normal file
@ -0,0 +1,5 @@
|
||||
PhoneGap.addConstructor(function() {
|
||||
if (typeof navigator.splashScreen == "undefined") {
|
||||
navigator.splashScreen = SplashScreen; // SplashScreen object come from native side through addJavaScriptInterface
|
||||
}
|
||||
});
|
@ -64,21 +64,53 @@
|
||||
-->
|
||||
<setup />
|
||||
|
||||
<target name="move_files">
|
||||
<concat destfile="../example/phonegap.js">
|
||||
<target name="check-javascript" depends="build-javascript">
|
||||
<delete dir="assets/lib"/>
|
||||
<mkdir dir="assets/lib"/>
|
||||
<echo file="assets/lib/lint.js">var alert=function(){},device={},Element={},debug={};</echo>
|
||||
<concat destfile="assets/lib/phonegap-lint.js" append="true">
|
||||
<fileset dir="assets/lib">
|
||||
<include name="lint.js" />
|
||||
</fileset>
|
||||
<fileset dir="assets/www">
|
||||
<include name="phonegap.js" />
|
||||
</fileset>
|
||||
</concat>
|
||||
|
||||
<exec executable="cmd" os="Windows 7">
|
||||
<arg value="/c"/>
|
||||
<arg value="java"/>
|
||||
<arg value="-cp"/>
|
||||
<arg value="${basedir}/util/js.jar"/>
|
||||
<arg value="org.mozilla.javascript.tools.shell.Main"/>
|
||||
<arg value="${basedir}/util/jslint.js"/>
|
||||
<arg value="${basedir}/js/lib/phonegap-lint.js"/>
|
||||
</exec>
|
||||
<exec executable="java" os="Mac OS X">
|
||||
<arg value="-cp"/>
|
||||
<arg value="../util/js.jar"/>
|
||||
<arg value="org.mozilla.javascript.tools.shell.Main"/>
|
||||
<arg value="../util/jslint.js"/>
|
||||
<arg value="assets/lib/phonegap-lint.js"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="build-javascript">
|
||||
<delete file="assets/www/phonegap.js"/>
|
||||
<concat destfile="assets/www/phonegap.js">
|
||||
<fileset dir="assets/js" includes="phonegap.js.base" />
|
||||
<fileset dir="assets/js" includes="*.js" />
|
||||
</concat>
|
||||
</target>
|
||||
|
||||
<target name="jar" depends="move_files, compile">
|
||||
<target name="jar" depends="build-javascript, compile">
|
||||
<jar jarfile="phonegap.jar" basedir="bin/classes" excludes="**/R*.class" />
|
||||
</target>
|
||||
|
||||
<target name="phonegap_debug" depends="move_files, debug">
|
||||
<target name="phonegap_debug" depends="build-javascript, debug">
|
||||
</target>
|
||||
|
||||
<target name="phonegap_release" depends="move_files, release">
|
||||
<target name="phonegap_release" depends="build-javascript, release">
|
||||
</target>
|
||||
|
||||
|
||||
|
@ -12,15 +12,13 @@ public final class R {
|
||||
}
|
||||
public static final class drawable {
|
||||
public static final int icon=0x7f020000;
|
||||
public static final int splash=0x7f020001;
|
||||
}
|
||||
public static final class id {
|
||||
public static final int appView=0x7f050000;
|
||||
public static final int go=0x7f050002;
|
||||
public static final int surface=0x7f050001;
|
||||
}
|
||||
public static final class layout {
|
||||
public static final int main=0x7f030000;
|
||||
public static final int preview=0x7f030001;
|
||||
}
|
||||
public static final class string {
|
||||
public static final int app_name=0x7f040000;
|
||||
|
BIN
framework/res/drawable/splash.png
Executable file
BIN
framework/res/drawable/splash.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent" android:layout_height="fill_parent"
|
||||
android:orientation="horizontal">
|
||||
<SurfaceView android:id="@+id/surface"
|
||||
android:layout_width="fill_parent" android:layout_height="fill_parent"
|
||||
android:layout_weight="1">
|
||||
</SurfaceView>
|
||||
<Button
|
||||
android:id="@+id/go"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
|
||||
android:text="@string/go"
|
||||
android:minWidth="50dip"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginRight="5dip"
|
||||
android:layout_marginTop="5dip"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
@ -38,6 +38,7 @@ import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
@ -53,6 +54,7 @@ import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.webkit.GeolocationPermissions.Callback;
|
||||
import android.webkit.WebSettings.LayoutAlgorithm;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.os.Build.*;
|
||||
import android.provider.MediaStore;
|
||||
@ -61,6 +63,7 @@ public class DroidGap extends Activity {
|
||||
|
||||
private static final String LOG_TAG = "DroidGap";
|
||||
protected WebView appView;
|
||||
protected ImageView splashScreen;
|
||||
private LinearLayout root;
|
||||
|
||||
private Device gap;
|
||||
@ -77,39 +80,53 @@ public class DroidGap extends Activity {
|
||||
private AudioHandler audio;
|
||||
private CallbackServer callbackServer;
|
||||
private CommandManager commandManager;
|
||||
|
||||
|
||||
private Uri imageUri;
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
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!
|
||||
|
||||
LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
|
||||
ViewGroup.LayoutParams.FILL_PARENT, 0.0F);
|
||||
|
||||
LinearLayout.LayoutParams webviewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
|
||||
ViewGroup.LayoutParams.FILL_PARENT, 1.0F);
|
||||
|
||||
|
||||
root = new LinearLayout(this);
|
||||
root.setOrientation(LinearLayout.VERTICAL);
|
||||
root.setBackgroundColor(Color.BLACK);
|
||||
root.setLayoutParams(containerParams);
|
||||
|
||||
appView = new WebView(this);
|
||||
appView.setLayoutParams(webviewParams);
|
||||
|
||||
root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
|
||||
ViewGroup.LayoutParams.FILL_PARENT, 0.0F));
|
||||
|
||||
splashScreen = new ImageView(this);
|
||||
splashScreen.setLayoutParams(new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.FILL_PARENT,
|
||||
ViewGroup.LayoutParams.FILL_PARENT,
|
||||
1.0F));
|
||||
splashScreen.setImageResource(R.drawable.splash);
|
||||
|
||||
root.addView(splashScreen);
|
||||
|
||||
initWebView();
|
||||
|
||||
setContentView(root);
|
||||
}
|
||||
|
||||
private void initWebView() {
|
||||
appView = new WebView(DroidGap.this);
|
||||
|
||||
appView.setLayoutParams(new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.FILL_PARENT,
|
||||
ViewGroup.LayoutParams.FILL_PARENT,
|
||||
1.0F));
|
||||
|
||||
WebViewReflect.checkCompatibility();
|
||||
|
||||
if (android.os.Build.VERSION.RELEASE.startsWith("2."))
|
||||
appView.setWebChromeClient(new EclairClient(this));
|
||||
else
|
||||
{
|
||||
appView.setWebChromeClient(new GapClient(this));
|
||||
|
||||
if (android.os.Build.VERSION.RELEASE.startsWith("2.")) {
|
||||
appView.setWebChromeClient(new EclairClient(DroidGap.this));
|
||||
} else {
|
||||
appView.setWebChromeClient(new GapClient(DroidGap.this));
|
||||
}
|
||||
|
||||
appView.setWebViewClient(new GapViewClient(this));
|
||||
@ -131,23 +148,15 @@ public class DroidGap extends Activity {
|
||||
WebViewReflect.setDomStorage(settings);
|
||||
// Turn off native geolocation object in browser - we use our own :)
|
||||
WebViewReflect.setGeolocationEnabled(settings, true);
|
||||
/* Bind the appView object to the gap class methods */
|
||||
// Bind the appView object to the gap class methods
|
||||
bindBrowser(appView);
|
||||
if(cupcakeStorage != null)
|
||||
cupcakeStorage.setStorage(appPackage);
|
||||
|
||||
root.addView(appView);
|
||||
|
||||
// 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.
|
||||
appView.loadUrl("javascript:try{PhoneGap.onNativeReady.fire();}catch(e){_nativeReady = true;}");
|
||||
|
||||
setContentView(root);
|
||||
}
|
||||
|
||||
public void invoke(String origin, boolean allow, boolean remember) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -260,6 +269,7 @@ public class DroidGap extends Activity {
|
||||
appView.addJavascriptInterface(mKey, "BackButton");
|
||||
appView.addJavascriptInterface(audio, "GapAudio");
|
||||
appView.addJavascriptInterface(callbackServer, "CallbackServer");
|
||||
//appView.addJavascriptInterface(new SplashScreen(this), "SplashScreen");
|
||||
|
||||
if (android.os.Build.VERSION.RELEASE.startsWith("1."))
|
||||
{
|
||||
@ -272,7 +282,7 @@ public class DroidGap extends Activity {
|
||||
|
||||
public void loadUrl(String url)
|
||||
{
|
||||
appView.loadUrl(url);
|
||||
this.appView.loadUrl(url);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -411,33 +421,39 @@ public class DroidGap extends Activity {
|
||||
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event)
|
||||
{
|
||||
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
if (mKey.isBound())
|
||||
{
|
||||
//We fire an event here!
|
||||
appView.loadUrl("javascript:document.keyEvent.backTrigger()");
|
||||
}
|
||||
else
|
||||
{
|
||||
String testUrl = appView.getUrl();
|
||||
appView.goBack();
|
||||
if(appView.getUrl().equals(testUrl))
|
||||
{
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (keyCode == KeyEvent.KEYCODE_MENU)
|
||||
{
|
||||
// This is where we launch the menu
|
||||
appView.loadUrl("javascript:keyEvent.menuTrigger()");
|
||||
}
|
||||
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
if (mKey.isBound())
|
||||
{
|
||||
//We fire an event here!
|
||||
appView.loadUrl("javascript:document.keyEvent.backTrigger()");
|
||||
}
|
||||
else
|
||||
{
|
||||
String testUrl = appView.getUrl();
|
||||
appView.goBack();
|
||||
if(appView.getUrl().equals(testUrl))
|
||||
{
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (keyCode == KeyEvent.KEYCODE_MENU)
|
||||
{
|
||||
// This is where we launch the menu
|
||||
appView.loadUrl("javascript:keyEvent.menuTrigger()");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the splash screen from root view and adds the WebView
|
||||
*/
|
||||
public void hideSplashScreen() {
|
||||
root.removeView(splashScreen);
|
||||
root.addView(appView);
|
||||
}
|
||||
|
||||
// This is required to start the camera activity! It has to come from the previous activity
|
||||
public void startCamera()
|
||||
{
|
||||
@ -469,11 +485,5 @@ public class DroidGap extends Activity {
|
||||
{
|
||||
launcher.failPicture("Did not complete!");
|
||||
}
|
||||
}
|
||||
|
||||
public WebView getView()
|
||||
{
|
||||
return this.appView;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
15
framework/src/com/phonegap/SplashScreen.java
Normal file
15
framework/src/com/phonegap/SplashScreen.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.phonegap;
|
||||
|
||||
public class SplashScreen {
|
||||
private final DroidGap gap;
|
||||
public SplashScreen(DroidGap gap) {
|
||||
this.gap = gap;
|
||||
}
|
||||
public void hide() {
|
||||
gap.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
gap.hideSplashScreen();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,24 +1,41 @@
|
||||
package com.phonegap.api;
|
||||
|
||||
import android.content.Context;
|
||||
import org.json.JSONArray;
|
||||
|
||||
import android.content.Context;
|
||||
import android.webkit.WebView;
|
||||
|
||||
/**
|
||||
* Command interface must be implemented by any plugin classes.
|
||||
*
|
||||
* The execute method is called by the CommandManager.
|
||||
*
|
||||
* @author davejohnson
|
||||
*
|
||||
*/
|
||||
public interface Command {
|
||||
/**
|
||||
* Executes the request and returns JS code to change client state.
|
||||
*
|
||||
* @param action the command to execute
|
||||
* @return a string with JavaScript code or null
|
||||
* Executes the request and returns CommandResult.
|
||||
*
|
||||
* @param action The command to execute.
|
||||
* @param args JSONArry of arguments for the command.
|
||||
* @return A CommandResult object with a status and message.
|
||||
*/
|
||||
CommandResult execute(String action, String[] args);
|
||||
CommandResult execute(String action, JSONArray args);
|
||||
|
||||
/**
|
||||
* Determines if this command can process a request.
|
||||
*
|
||||
* @param action the command to execute
|
||||
*
|
||||
* @return true if this command understands the petition
|
||||
* Sets the context of the Command. This can then be used to do things like
|
||||
* get file paths associated with the Activity.
|
||||
*
|
||||
* @param ctx The context of the main Activity.
|
||||
*/
|
||||
boolean accept(String action);
|
||||
|
||||
void setContext(Context ctx);
|
||||
|
||||
/**
|
||||
* Sets the main View of the application, this is the WebView within which
|
||||
* a PhoneGap app runs.
|
||||
*
|
||||
* @param webView The PhoneGap WebView
|
||||
*/
|
||||
void setView(WebView webView);
|
||||
}
|
||||
|
@ -1,12 +1,21 @@
|
||||
package com.phonegap.api;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
import android.content.Context;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import com.phonegap.DroidGap;
|
||||
|
||||
/**
|
||||
* Given a execution request detects matching {@link Command} and executes it.
|
||||
* CommandManager is exposed to JavaScript in the PhoneGap WebView.
|
||||
*
|
||||
* Calling native plugin code can be done by calling CommandManager.exec(...)
|
||||
* from JavaScript.
|
||||
*
|
||||
* @author davejohnson
|
||||
*
|
||||
*/
|
||||
public final class CommandManager {
|
||||
private static final String EXCEPTION_PREFIX = "[PhoneGap] *ERROR* Exception executing command [";
|
||||
@ -23,42 +32,57 @@ public final class CommandManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives a request for execution and fulfills it as long as one of
|
||||
* the configured {@link Command} can understand it. Command precedence
|
||||
* is important (just one of them will be executed).
|
||||
*
|
||||
* @param instruction any API command
|
||||
* @return JS code to execute by the client or null
|
||||
* Receives a request for execution and fulfills it by finding the appropriate
|
||||
* Java class and calling it's execute method.
|
||||
*
|
||||
* CommandManager.exec can be used either synchronously or async. In either case, a JSON encoded
|
||||
* string is returned that will indicate if any errors have occurred when trying to find
|
||||
* or execute the class denoted by the clazz argument.
|
||||
*
|
||||
* @param clazz String containing the fully qualified class name. e.g. com.phonegap.FooBar
|
||||
* @param action String containt the action that the class is supposed to perform. This is
|
||||
* passed to the plugin execute method and it is up to the plugin developer
|
||||
* how to deal with it.
|
||||
* @param callbackId String containing the id of the callback that is execute in JavaScript if
|
||||
* this is an async plugin call.
|
||||
* @param args An Array literal string containing any arguments needed in the
|
||||
* plugin execute method.
|
||||
* @param async Boolean indicating whether the calling JavaScript code is expecting an
|
||||
* immediate return value. If true, either PhoneGap.callbackSuccess(...) or PhoneGap.callbackError(...)
|
||||
* is called once the plugin code has executed.
|
||||
* @return JSON encoded string with a response message and status.
|
||||
*/
|
||||
public String exec(final String clazz, final String action, final String callbackId,
|
||||
final String args, final boolean async) {
|
||||
final String jsonArgs, final boolean async) {
|
||||
CommandResult cr = null;
|
||||
try {
|
||||
//final WebView wv = this.app;
|
||||
final String _callbackId = callbackId;
|
||||
final String[] aargs = args.split("__PHONEGAP__");
|
||||
Class c = Class.forName(clazz);
|
||||
Class[] interfaces = c.getInterfaces();
|
||||
for (int j=0; j<interfaces.length; j++) {
|
||||
if (interfaces[j].getName().equals("com.phonegap.api.Command")) {
|
||||
final Command ci = (Command)c.newInstance();
|
||||
ci.setContext(this.ctx);
|
||||
if (async) {
|
||||
// Run this async on the UI thread
|
||||
app.post(new Runnable() {
|
||||
public void run() {
|
||||
CommandResult cr = ci.execute(action, aargs);
|
||||
if (cr.getStatus() == 0) {
|
||||
app.loadUrl("javascript:PhoneGap.callbackSuccess('"+callbackId+"', " + cr.getResult()+ ");");
|
||||
} else {
|
||||
app.loadUrl("javascript:PhoneGap.callbackFailure('"+callbackId+"', " + cr.getResult() + ");");
|
||||
}
|
||||
final JSONArray args = new JSONArray(jsonArgs);
|
||||
Class c = getClassByName(clazz);
|
||||
if (isPhoneGapCommand(c)) {
|
||||
// Create a new instance of the plugin and set the context and webview
|
||||
final Command plugin = (Command)c.newInstance();
|
||||
plugin.setContext(this.ctx);
|
||||
plugin.setView(this.app);
|
||||
|
||||
if (async) {
|
||||
// Run this async on the UI thread so that JavaScript can continue on
|
||||
app.post(new Runnable() {
|
||||
public void run() {
|
||||
// Call execute on the plugin so that it can do it's thing
|
||||
CommandResult cr = plugin.execute(action, args);
|
||||
// Check if the
|
||||
if (cr.getStatus() == 0) {
|
||||
app.loadUrl(cr.toSuccessCallbackString(callbackId));
|
||||
} else {
|
||||
app.loadUrl(cr.toErrorCallbackString(callbackId));
|
||||
}
|
||||
});
|
||||
return "";
|
||||
} else {
|
||||
cr = ci.execute(action, aargs);
|
||||
}
|
||||
}
|
||||
});
|
||||
// Return ""
|
||||
return "";
|
||||
} else {
|
||||
// Call execute on the plugin so that it can do it's thing
|
||||
cr = plugin.execute(action, args);
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
@ -70,11 +94,44 @@ public final class CommandManager {
|
||||
} catch (InstantiationException e) {
|
||||
cr = new CommandResult(CommandResult.Status.INSTANTIATIONEXCEPTION,
|
||||
"{ message: 'InstantiationException', status: "+CommandResult.Status.INSTANTIATIONEXCEPTION.ordinal()+" }");
|
||||
} catch (JSONException e) {
|
||||
cr = new CommandResult(CommandResult.Status.JSONEXCEPTION,
|
||||
"{ message: 'JSONException', status: "+CommandResult.Status.JSONEXCEPTION.ordinal()+" }");
|
||||
}
|
||||
// if async we have already returned at this point unless there was an error...
|
||||
if (async) {
|
||||
app.loadUrl("javascript:PhoneGap.callbackFailure('"+callbackId+"', " + cr.getResult() + ");");
|
||||
app.loadUrl(cr.toErrorCallbackString(callbackId));
|
||||
}
|
||||
return ( cr != null ? cr.getResult() : "{ status: 0, message: 'all good' }" );
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param clazz
|
||||
* @return
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
private Class getClassByName(final String clazz) throws ClassNotFoundException {
|
||||
return Class.forName(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the interfaces that a class implements and see if it implements the
|
||||
* com.phonegap.api.Command interface.
|
||||
*
|
||||
* @param c The class to check the interfaces of.
|
||||
* @return Boolean indicating if the class implements com.phonegap.api.Command
|
||||
*/
|
||||
private boolean isPhoneGapCommand(Class c) {
|
||||
boolean isCommand = false;
|
||||
Class[] interfaces = c.getInterfaces();
|
||||
for (int j=0; j<interfaces.length; j++) {
|
||||
if (interfaces[j].getName().equals("com.phonegap.api.Command")) {
|
||||
isCommand = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isCommand;
|
||||
}
|
||||
}
|
@ -17,6 +17,14 @@ public class CommandResult {
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toSuccessCallbackString(String callbackId) {
|
||||
return "javascript:PhoneGap.callbackSuccess('"+callbackId+"', " + this.getResult()+ ");";
|
||||
}
|
||||
|
||||
public String toErrorCallbackString(String callbackId) {
|
||||
return "javascript:PhoneGap.callbackError('"+callbackId+"', " + this.getResult()+ ");";
|
||||
}
|
||||
|
||||
public enum Status {
|
||||
OK,
|
||||
CLASSNOTFOUNDEXCEPTION,
|
||||
@ -24,6 +32,7 @@ public class CommandResult {
|
||||
INSTANTIATIONEXCEPTION,
|
||||
MALFORMEDURLEXCEPTION,
|
||||
IOEXCEPTION,
|
||||
INVALIDACTION
|
||||
INVALIDACTION,
|
||||
JSONEXCEPTION
|
||||
}
|
||||
}
|
||||
|
@ -1,109 +0,0 @@
|
||||
package com.phonegap.api.impl;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.phonegap.api.Command;
|
||||
import com.phonegap.api.CommandResult;
|
||||
|
||||
public final class Cache implements Command {
|
||||
|
||||
private Context ctx;
|
||||
|
||||
public boolean accept(String action) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setContext(Context ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public CommandResult execute(String action, String[] args) {
|
||||
|
||||
CommandResult.Status status = CommandResult.Status.OK;
|
||||
String result = "";
|
||||
|
||||
String uri = args[0];
|
||||
String fileName = md5(uri);
|
||||
|
||||
if (action.equals("getCachedPathForURI") && args.length == 1)
|
||||
{
|
||||
// First check if the file exists already
|
||||
String fileDir = ctx.getFilesDir().getAbsolutePath();
|
||||
String filePath = fileDir + "/" + fileName;
|
||||
|
||||
File f = new File(filePath);
|
||||
if (f.exists()) {
|
||||
result = "{ file: '"+filePath+"', status: 0 }";
|
||||
} else {
|
||||
|
||||
URL u;
|
||||
InputStream is = null;
|
||||
DataInputStream dis;
|
||||
FileOutputStream out = null;
|
||||
byte[] buffer = new byte[1024];
|
||||
int length = -1;
|
||||
|
||||
try {
|
||||
u = new URL(uri);
|
||||
is = u.openStream(); // throws an IOException
|
||||
dis = new DataInputStream(new BufferedInputStream(is));
|
||||
out = ctx.openFileOutput(fileName, Context.MODE_PRIVATE);
|
||||
while ((length = dis.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, length);
|
||||
}
|
||||
out.flush();
|
||||
result = "{ file: '"+fileName+"', status: 0 }";
|
||||
} catch (MalformedURLException e) {
|
||||
status = CommandResult.Status.MALFORMEDURLEXCEPTION;
|
||||
result = "{ message: 'MalformedURLException', status: "+status.ordinal()+" }";
|
||||
} catch (IOException e) {
|
||||
status = CommandResult.Status.IOEXCEPTION;
|
||||
result = "{ message: 'IOException', status: "+status.ordinal()+" }";
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
status = CommandResult.Status.IOEXCEPTION;
|
||||
result = "{ message: 'IOException', status: "+status.ordinal()+" }";
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status = CommandResult.Status.INVALIDACTION;
|
||||
result = "{ message: 'InvalidAction', status: "+status.ordinal()+" }";
|
||||
}
|
||||
return new CommandResult(status, result);
|
||||
}
|
||||
|
||||
public String md5(String s) {
|
||||
try {
|
||||
// Create MD5 Hash
|
||||
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
|
||||
digest.update(s.getBytes());
|
||||
byte messageDigest[] = digest.digest();
|
||||
|
||||
// Create Hex String
|
||||
StringBuffer hexString = new StringBuffer();
|
||||
for (int i=0; i<messageDigest.length; i++)
|
||||
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
|
||||
return hexString.toString();
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user