mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-26 20:33:07 +08:00
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cordova-android
This commit is contained in:
commit
d87f404d6e
4
NOTICE
4
NOTICE
@ -1,5 +1,5 @@
|
|||||||
Apache Callback
|
Apache Cordova
|
||||||
Copyright 2011 The Apache Software Foundation
|
Copyright 2012 The Apache Software Foundation
|
||||||
|
|
||||||
This product includes software developed by
|
This product includes software developed by
|
||||||
The Apache Software Foundation (http://www.apache.org)
|
The Apache Software Foundation (http://www.apache.org)
|
||||||
|
@ -20,6 +20,10 @@ Requires
|
|||||||
- Android SDK [http://developer.android.com](http://developer.android.com)
|
- Android SDK [http://developer.android.com](http://developer.android.com)
|
||||||
- Apache Commons Codec [http://commons.apache.org/codec/](http://commons.apache.org/codec/)
|
- Apache Commons Codec [http://commons.apache.org/codec/](http://commons.apache.org/codec/)
|
||||||
|
|
||||||
|
Test Requirements
|
||||||
|
---
|
||||||
|
- JUnit - [https://github.com/KentBeck/junit](https://github.com/KentBeck/junit)
|
||||||
|
|
||||||
Building
|
Building
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -98,6 +102,9 @@ Importing a Cordova Android Project into Eclipse
|
|||||||
5. Right click on the project root: Run as > Run Configurations
|
5. Right click on the project root: Run as > Run Configurations
|
||||||
6. Click on the Target tab and select Manual (this way you can choose the emulator or device to build to)
|
6. Click on the Target tab and select Manual (this way you can choose the emulator or device to build to)
|
||||||
|
|
||||||
|
Running Tests
|
||||||
|
----
|
||||||
|
Please see details under test/README.md.
|
||||||
|
|
||||||
Further Reading
|
Further Reading
|
||||||
---
|
---
|
||||||
|
@ -5723,4 +5723,4 @@ window.cordova = require('cordova');
|
|||||||
}(window));
|
}(window));
|
||||||
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
<!-- <access origin=".*"/> Allow all domains, suggested development use only -->
|
<!-- <access origin=".*"/> Allow all domains, suggested development use only -->
|
||||||
|
|
||||||
<log level="DEBUG"/>
|
<log level="DEBUG"/>
|
||||||
<preference name="classicRender" value="true" />
|
<preference name="useBrowserHistory" value="false" />
|
||||||
</cordova>
|
</cordova>
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.phonegap.api;
|
package com.phonegap.api;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
import org.apache.cordova.api.CordovaInterface;
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
|
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
@ -30,7 +31,7 @@ import android.webkit.WebView;
|
|||||||
*/
|
*/
|
||||||
public class PluginManager extends org.apache.cordova.api.PluginManager {
|
public class PluginManager extends org.apache.cordova.api.PluginManager {
|
||||||
|
|
||||||
public PluginManager(WebView app, CordovaInterface ctx) {
|
public PluginManager(WebView app, CordovaInterface ctx) throws Exception {
|
||||||
super(app, ctx);
|
super((CordovaWebView) app, ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ import org.json.JSONArray;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
|
||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
@ -43,14 +42,14 @@ public class AccelListener extends Plugin implements SensorEventListener {
|
|||||||
public static int STARTING = 1;
|
public static int STARTING = 1;
|
||||||
public static int RUNNING = 2;
|
public static int RUNNING = 2;
|
||||||
public static int ERROR_FAILED_TO_START = 3;
|
public static int ERROR_FAILED_TO_START = 3;
|
||||||
|
|
||||||
private float x,y,z; // most recent acceleration values
|
private float x,y,z; // most recent acceleration values
|
||||||
private long timestamp; // time of most recent value
|
private long timestamp; // time of most recent value
|
||||||
private int status; // status of listener
|
private int status; // status of listener
|
||||||
private int accuracy = SensorManager.SENSOR_STATUS_UNRELIABLE;
|
private int accuracy = SensorManager.SENSOR_STATUS_UNRELIABLE;
|
||||||
|
|
||||||
private SensorManager sensorManager; // Sensor manager
|
private SensorManager sensorManager; // Sensor manager
|
||||||
private Sensor mSensor; // Acceleration sensor returned by sensor manager
|
private Sensor mSensor; // Acceleration sensor returned by sensor manager
|
||||||
|
|
||||||
private String callbackId; // Keeps track of the single "start" callback ID passed in from JS
|
private String callbackId; // Keeps track of the single "start" callback ID passed in from JS
|
||||||
|
|
||||||
@ -71,18 +70,19 @@ public class AccelListener extends Plugin implements SensorEventListener {
|
|||||||
*
|
*
|
||||||
* @param ctx The context of the main Activity.
|
* @param ctx The context of the main Activity.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void setContext(CordovaInterface ctx) {
|
public void setContext(CordovaInterface ctx) {
|
||||||
super.setContext(ctx);
|
super.setContext(ctx);
|
||||||
this.sensorManager = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE);
|
this.sensorManager = (SensorManager) ctx.getActivity().getSystemService(Context.SENSOR_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the request and returns PluginResult.
|
* Executes the request and returns PluginResult.
|
||||||
*
|
*
|
||||||
* @param action The action to execute.
|
* @param action The action to execute.
|
||||||
* @param args JSONArry of arguments for the plugin.
|
* @param args JSONArry of arguments for the plugin.
|
||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
* @return A PluginResult object with a status and message.
|
* @return A PluginResult object with a status and message.
|
||||||
*/
|
*/
|
||||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||||
PluginResult.Status status = PluginResult.Status.NO_RESULT;
|
PluginResult.Status status = PluginResult.Status.NO_RESULT;
|
||||||
@ -123,9 +123,9 @@ public class AccelListener extends Plugin implements SensorEventListener {
|
|||||||
//
|
//
|
||||||
/**
|
/**
|
||||||
* Start listening for acceleration sensor.
|
* Start listening for acceleration sensor.
|
||||||
*
|
*
|
||||||
* @return status of listener
|
* @return status of listener
|
||||||
*/
|
*/
|
||||||
private int start() {
|
private int start() {
|
||||||
// If already starting or running, then just return
|
// If already starting or running, then just return
|
||||||
if ((this.status == AccelListener.RUNNING) || (this.status == AccelListener.STARTING)) {
|
if ((this.status == AccelListener.RUNNING) || (this.status == AccelListener.STARTING)) {
|
||||||
@ -139,24 +139,24 @@ public class AccelListener extends Plugin implements SensorEventListener {
|
|||||||
|
|
||||||
// If found, then register as listener
|
// If found, then register as listener
|
||||||
if ((list != null) && (list.size() > 0)) {
|
if ((list != null) && (list.size() > 0)) {
|
||||||
this.mSensor = list.get(0);
|
this.mSensor = list.get(0);
|
||||||
this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_UI);
|
this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_UI);
|
||||||
this.setStatus(AccelListener.STARTING);
|
this.setStatus(AccelListener.STARTING);
|
||||||
} else {
|
} else {
|
||||||
this.setStatus(AccelListener.ERROR_FAILED_TO_START);
|
this.setStatus(AccelListener.ERROR_FAILED_TO_START);
|
||||||
this.fail(AccelListener.ERROR_FAILED_TO_START, "No sensors found to register accelerometer listening to.");
|
this.fail(AccelListener.ERROR_FAILED_TO_START, "No sensors found to register accelerometer listening to.");
|
||||||
return this.status;
|
return this.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until running
|
// Wait until running
|
||||||
long timeout = 2000;
|
long timeout = 2000;
|
||||||
while ((this.status == STARTING) && (timeout > 0)) {
|
while ((this.status == STARTING) && (timeout > 0)) {
|
||||||
timeout = timeout - 100;
|
timeout = timeout - 100;
|
||||||
try {
|
try {
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (timeout == 0) {
|
if (timeout == 0) {
|
||||||
this.setStatus(AccelListener.ERROR_FAILED_TO_START);
|
this.setStatus(AccelListener.ERROR_FAILED_TO_START);
|
||||||
@ -210,7 +210,6 @@ public class AccelListener extends Plugin implements SensorEventListener {
|
|||||||
if (this.status == AccelListener.STOPPED) {
|
if (this.status == AccelListener.STOPPED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setStatus(AccelListener.RUNNING);
|
this.setStatus(AccelListener.RUNNING);
|
||||||
|
|
||||||
if (this.accuracy >= SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM) {
|
if (this.accuracy >= SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM) {
|
||||||
@ -252,7 +251,6 @@ public class AccelListener extends Plugin implements SensorEventListener {
|
|||||||
private void setStatus(int status) {
|
private void setStatus(int status) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSONObject getAccelerationJSON() {
|
private JSONObject getAccelerationJSON() {
|
||||||
JSONObject r = new JSONObject();
|
JSONObject r = new JSONObject();
|
||||||
try {
|
try {
|
||||||
|
@ -48,6 +48,13 @@ public class App extends Plugin {
|
|||||||
if (action.equals("clearCache")) {
|
if (action.equals("clearCache")) {
|
||||||
this.clearCache();
|
this.clearCache();
|
||||||
}
|
}
|
||||||
|
else if (action.equals("show")) { // TODO @bc - Not in master branch. When should this be called?
|
||||||
|
ctx.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
webView.postMessage("spinner", "stop");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
else if (action.equals("loadUrl")) {
|
else if (action.equals("loadUrl")) {
|
||||||
this.loadUrl(args.getString(0), args.optJSONObject(1));
|
this.loadUrl(args.getString(0), args.optJSONObject(1));
|
||||||
}
|
}
|
||||||
@ -84,7 +91,7 @@ public class App extends Plugin {
|
|||||||
* Clear the resource cache.
|
* Clear the resource cache.
|
||||||
*/
|
*/
|
||||||
public void clearCache() {
|
public void clearCache() {
|
||||||
((DroidGap)this.ctx).clearCache();
|
this.webView.clearCache(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,7 +111,7 @@ public class App extends Plugin {
|
|||||||
HashMap<String, Object> params = new HashMap<String, Object>();
|
HashMap<String, Object> params = new HashMap<String, Object>();
|
||||||
if (props != null) {
|
if (props != null) {
|
||||||
JSONArray keys = props.names();
|
JSONArray keys = props.names();
|
||||||
for (int i=0; i<keys.length(); i++) {
|
for (int i = 0; i < keys.length(); i++) {
|
||||||
String key = keys.getString(i);
|
String key = keys.getString(i);
|
||||||
if (key.equals("wait")) {
|
if (key.equals("wait")) {
|
||||||
wait = props.getInt(key);
|
wait = props.getInt(key);
|
||||||
@ -144,21 +151,22 @@ public class App extends Plugin {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
((DroidGap)this.ctx).showWebPage(url, openExternal, clearHistory, params);
|
this.webView.showWebPage(url, openExternal, clearHistory, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel loadUrl before it has been loaded.
|
* Cancel loadUrl before it has been loaded (Only works on a CordovaInterface class)
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void cancelLoadUrl() {
|
public void cancelLoadUrl() {
|
||||||
((DroidGap)this.ctx).cancelLoadUrl();
|
this.ctx.cancelLoadUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear page history for the app.
|
* Clear page history for the app.
|
||||||
*/
|
*/
|
||||||
public void clearHistory() {
|
public void clearHistory() {
|
||||||
((DroidGap)this.ctx).clearHistory();
|
this.webView.clearHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,7 +174,7 @@ public class App extends Plugin {
|
|||||||
* This is the same as pressing the backbutton on Android device.
|
* This is the same as pressing the backbutton on Android device.
|
||||||
*/
|
*/
|
||||||
public void backHistory() {
|
public void backHistory() {
|
||||||
((DroidGap)this.ctx).backHistory();
|
this.webView.backHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -176,8 +184,8 @@ public class App extends Plugin {
|
|||||||
* @param override T=override, F=cancel override
|
* @param override T=override, F=cancel override
|
||||||
*/
|
*/
|
||||||
public void overrideBackbutton(boolean override) {
|
public void overrideBackbutton(boolean override) {
|
||||||
LOG.i("DroidGap", "WARNING: Back Button Default Behaviour will be overridden. The backbutton event will be fired!");
|
LOG.i("App", "WARNING: Back Button Default Behaviour will be overridden. The backbutton event will be fired!");
|
||||||
((DroidGap)this.ctx).bound = override;
|
this.ctx.bindBackButton(override);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -186,13 +194,14 @@ public class App extends Plugin {
|
|||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public boolean isBackbuttonOverridden() {
|
public boolean isBackbuttonOverridden() {
|
||||||
return ((DroidGap)this.ctx).bound;
|
return this.ctx.isBackButtonBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exit the Android application.
|
* Exit the Android application.
|
||||||
*/
|
*/
|
||||||
public void exitApp() {
|
public void exitApp() {
|
||||||
((DroidGap)this.ctx).endActivity();
|
this.webView.postMessage("exit", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ import org.apache.cordova.api.Plugin;
|
|||||||
import org.apache.cordova.api.PluginResult;
|
import org.apache.cordova.api.PluginResult;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,20 +42,19 @@ import java.util.HashMap;
|
|||||||
public class AudioHandler extends Plugin {
|
public class AudioHandler extends Plugin {
|
||||||
|
|
||||||
public static String TAG = "AudioHandler";
|
public static String TAG = "AudioHandler";
|
||||||
HashMap<String,AudioPlayer> players; // Audio player object
|
HashMap<String, AudioPlayer> players; // Audio player object
|
||||||
ArrayList<AudioPlayer> pausedForPhone; // Audio players that were paused when phone call came in
|
ArrayList<AudioPlayer> pausedForPhone; // Audio players that were paused when phone call came in
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
public AudioHandler() {
|
public AudioHandler() {
|
||||||
this.players = new HashMap<String,AudioPlayer>();
|
this.players = new HashMap<String, AudioPlayer>();
|
||||||
this.pausedForPhone = new ArrayList<AudioPlayer>();
|
this.pausedForPhone = new ArrayList<AudioPlayer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the request and returns PluginResult.
|
* Executes the request and returns PluginResult.
|
||||||
*
|
|
||||||
* @param action The action to execute.
|
* @param action The action to execute.
|
||||||
* @param args JSONArry of arguments for the plugin.
|
* @param args JSONArry of arguments for the plugin.
|
||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
@ -111,7 +109,6 @@ public class AudioHandler extends Plugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies if action to be executed returns a value and should be run synchronously.
|
* Identifies if action to be executed returns a value and should be run synchronously.
|
||||||
*
|
|
||||||
* @param action The action to execute
|
* @param action The action to execute
|
||||||
* @return T=returns value
|
* @return T=returns value
|
||||||
*/
|
*/
|
||||||
@ -140,8 +137,9 @@ public class AudioHandler extends Plugin {
|
|||||||
*
|
*
|
||||||
* @param id The message id
|
* @param id The message id
|
||||||
* @param data The message data
|
* @param data The message data
|
||||||
|
* @return Object to stop propagation or null
|
||||||
*/
|
*/
|
||||||
public void onMessage(String id, Object data) {
|
public Object onMessage(String id, Object data) {
|
||||||
|
|
||||||
// If phone message
|
// If phone message
|
||||||
if (id.equals("telephone")) {
|
if (id.equals("telephone")) {
|
||||||
@ -167,6 +165,7 @@ public class AudioHandler extends Plugin {
|
|||||||
this.pausedForPhone.clear();
|
this.pausedForPhone.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
@ -175,7 +174,6 @@ public class AudioHandler extends Plugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Release the audio player instance to save memory.
|
* Release the audio player instance to save memory.
|
||||||
*
|
|
||||||
* @param id The id of the audio player
|
* @param id The id of the audio player
|
||||||
*/
|
*/
|
||||||
private boolean release(String id) {
|
private boolean release(String id) {
|
||||||
@ -190,7 +188,6 @@ public class AudioHandler extends Plugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Start recording and save the specified file.
|
* Start recording and save the specified file.
|
||||||
*
|
|
||||||
* @param id The id of the audio player
|
* @param id The id of the audio player
|
||||||
* @param file The name of the file
|
* @param file The name of the file
|
||||||
*/
|
*/
|
||||||
@ -206,7 +203,6 @@ public class AudioHandler extends Plugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop recording and save to the file specified when recording started.
|
* Stop recording and save to the file specified when recording started.
|
||||||
*
|
|
||||||
* @param id The id of the audio player
|
* @param id The id of the audio player
|
||||||
*/
|
*/
|
||||||
public void stopRecordingAudio(String id) {
|
public void stopRecordingAudio(String id) {
|
||||||
@ -219,7 +215,6 @@ public class AudioHandler extends Plugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Start or resume playing audio file.
|
* Start or resume playing audio file.
|
||||||
*
|
|
||||||
* @param id The id of the audio player
|
* @param id The id of the audio player
|
||||||
* @param file The name of the audio file.
|
* @param file The name of the audio file.
|
||||||
*/
|
*/
|
||||||
@ -234,8 +229,6 @@ public class AudioHandler extends Plugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Seek to a location.
|
* Seek to a location.
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param id The id of the audio player
|
* @param id The id of the audio player
|
||||||
* @param miliseconds int: number of milliseconds to skip 1000 = 1 second
|
* @param miliseconds int: number of milliseconds to skip 1000 = 1 second
|
||||||
*/
|
*/
|
||||||
@ -248,7 +241,6 @@ public class AudioHandler extends Plugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Pause playing.
|
* Pause playing.
|
||||||
*
|
|
||||||
* @param id The id of the audio player
|
* @param id The id of the audio player
|
||||||
*/
|
*/
|
||||||
public void pausePlayingAudio(String id) {
|
public void pausePlayingAudio(String id) {
|
||||||
@ -260,7 +252,6 @@ public class AudioHandler extends Plugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop playing the audio file.
|
* Stop playing the audio file.
|
||||||
*
|
|
||||||
* @param id The id of the audio player
|
* @param id The id of the audio player
|
||||||
*/
|
*/
|
||||||
public void stopPlayingAudio(String id) {
|
public void stopPlayingAudio(String id) {
|
||||||
@ -274,21 +265,19 @@ public class AudioHandler extends Plugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current position of playback.
|
* Get current position of playback.
|
||||||
*
|
|
||||||
* @param id The id of the audio player
|
* @param id The id of the audio player
|
||||||
* @return position in msec
|
* @return position in msec
|
||||||
*/
|
*/
|
||||||
public float getCurrentPositionAudio(String id) {
|
public float getCurrentPositionAudio(String id) {
|
||||||
AudioPlayer audio = this.players.get(id);
|
AudioPlayer audio = this.players.get(id);
|
||||||
if (audio != null) {
|
if (audio != null) {
|
||||||
return(audio.getCurrentPosition()/1000.0f);
|
return (audio.getCurrentPosition() / 1000.0f);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the duration of the audio file.
|
* Get the duration of the audio file.
|
||||||
*
|
|
||||||
* @param id The id of the audio player
|
* @param id The id of the audio player
|
||||||
* @param file The name of the audio file.
|
* @param file The name of the audio file.
|
||||||
* @return The duration in msec.
|
* @return The duration in msec.
|
||||||
@ -298,14 +287,14 @@ public class AudioHandler extends Plugin {
|
|||||||
// Get audio file
|
// Get audio file
|
||||||
AudioPlayer audio = this.players.get(id);
|
AudioPlayer audio = this.players.get(id);
|
||||||
if (audio != null) {
|
if (audio != null) {
|
||||||
return(audio.getDuration(file));
|
return (audio.getDuration(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not already open, then open the file
|
// If not already open, then open the file
|
||||||
else {
|
else {
|
||||||
audio = new AudioPlayer(this, id);
|
audio = new AudioPlayer(this, id);
|
||||||
this.players.put(id, audio);
|
this.players.put(id, audio);
|
||||||
return(audio.getDuration(file));
|
return (audio.getDuration(file));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,8 +303,9 @@ public class AudioHandler extends Plugin {
|
|||||||
*
|
*
|
||||||
* @param output 1=earpiece, 2=speaker
|
* @param output 1=earpiece, 2=speaker
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public void setAudioOutputDevice(int output) {
|
public void setAudioOutputDevice(int output) {
|
||||||
AudioManager audiMgr = (AudioManager) this.ctx.getSystemService(Context.AUDIO_SERVICE);
|
AudioManager audiMgr = (AudioManager) this.ctx.getActivity().getSystemService(Context.AUDIO_SERVICE);
|
||||||
if (output == 2) {
|
if (output == 2) {
|
||||||
audiMgr.setRouting(AudioManager.MODE_NORMAL, AudioManager.ROUTE_SPEAKER, AudioManager.ROUTE_ALL);
|
audiMgr.setRouting(AudioManager.MODE_NORMAL, AudioManager.ROUTE_SPEAKER, AudioManager.ROUTE_ALL);
|
||||||
}
|
}
|
||||||
@ -332,8 +322,9 @@ public class AudioHandler extends Plugin {
|
|||||||
*
|
*
|
||||||
* @return 1=earpiece, 2=speaker
|
* @return 1=earpiece, 2=speaker
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public int getAudioOutputDevice() {
|
public int getAudioOutputDevice() {
|
||||||
AudioManager audiMgr = (AudioManager) this.ctx.getSystemService(Context.AUDIO_SERVICE);
|
AudioManager audiMgr = (AudioManager) this.ctx.getActivity().getSystemService(Context.AUDIO_SERVICE);
|
||||||
if (audiMgr.getRouting(AudioManager.MODE_NORMAL) == AudioManager.ROUTE_EARPIECE) {
|
if (audiMgr.getRouting(AudioManager.MODE_NORMAL) == AudioManager.ROUTE_EARPIECE) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,8 @@ import java.io.IOException;
|
|||||||
* Only one file can be played or recorded per class instance.
|
* Only one file can be played or recorded per class instance.
|
||||||
*
|
*
|
||||||
* Local audio files must reside in one of two places:
|
* Local audio files must reside in one of two places:
|
||||||
* android_asset: file name must start with /android_asset/sound.mp3
|
* android_asset: file name must start with /android_asset/sound.mp3
|
||||||
* sdcard: file name is just sound.mp3
|
* sdcard: file name is just sound.mp3
|
||||||
*/
|
*/
|
||||||
public class AudioPlayer implements OnCompletionListener, OnPreparedListener, OnErrorListener {
|
public class AudioPlayer implements OnCompletionListener, OnPreparedListener, OnErrorListener {
|
||||||
|
|
||||||
@ -63,24 +63,24 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
private static int MEDIA_ERR_NETWORK = 2;
|
private static int MEDIA_ERR_NETWORK = 2;
|
||||||
private static int MEDIA_ERR_DECODE = 3;
|
private static int MEDIA_ERR_DECODE = 3;
|
||||||
private static int MEDIA_ERR_NONE_SUPPORTED = 4;
|
private static int MEDIA_ERR_NONE_SUPPORTED = 4;
|
||||||
|
|
||||||
|
private AudioHandler handler; // The AudioHandler object
|
||||||
|
private String id; // The id of this player (used to identify Media object in JavaScript)
|
||||||
|
private int state = MEDIA_NONE; // State of recording or playback
|
||||||
|
private String audioFile = null; // File name to play or record to
|
||||||
|
private float duration = -1; // Duration of audio
|
||||||
|
|
||||||
private AudioHandler handler; // The AudioHandler object
|
private MediaRecorder recorder = null; // Audio recording object
|
||||||
private String id; // The id of this player (used to identify Media object in JavaScript)
|
private String tempFile = null; // Temporary recording file name
|
||||||
private int state = MEDIA_NONE; // State of recording or playback
|
|
||||||
private String audioFile = null; // File name to play or record to
|
private MediaPlayer mPlayer = null; // Audio player object
|
||||||
private float duration = -1; // Duration of audio
|
private boolean prepareOnly = false;
|
||||||
|
|
||||||
private MediaRecorder recorder = null; // Audio recording object
|
|
||||||
private String tempFile = null; // Temporary recording file name
|
|
||||||
|
|
||||||
private MediaPlayer mPlayer = null; // Audio player object
|
|
||||||
private boolean prepareOnly = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param handler The audio handler object
|
* @param handler The audio handler object
|
||||||
* @param id The id of this audio player
|
* @param id The id of this audio player
|
||||||
*/
|
*/
|
||||||
public AudioPlayer(AudioHandler handler, String id) {
|
public AudioPlayer(AudioHandler handler, String id) {
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
@ -88,7 +88,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
||||||
this.tempFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tmprecording.mp3";
|
this.tempFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tmprecording.mp3";
|
||||||
} else {
|
} else {
|
||||||
this.tempFile = "/data/data/" + handler.ctx.getPackageName() + "/cache/tmprecording.mp3";
|
this.tempFile = "/data/data/" + handler.ctx.getActivity().getPackageName() + "/cache/tmprecording.mp3";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +96,6 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
* Destroy player and stop audio playing or recording.
|
* Destroy player and stop audio playing or recording.
|
||||||
*/
|
*/
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
|
|
||||||
// Stop any play or record
|
// Stop any play or record
|
||||||
if (this.mPlayer != null) {
|
if (this.mPlayer != null) {
|
||||||
if ((this.state == MEDIA_RUNNING) || (this.state == MEDIA_PAUSED)) {
|
if ((this.state == MEDIA_RUNNING) || (this.state == MEDIA_PAUSED)) {
|
||||||
@ -115,15 +114,14 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Start recording the specified file.
|
* Start recording the specified file.
|
||||||
*
|
*
|
||||||
* @param file The name of the file
|
* @param file The name of the file
|
||||||
*/
|
*/
|
||||||
public void startRecording(String file) {
|
public void startRecording(String file) {
|
||||||
if (this.mPlayer != null) {
|
if (this.mPlayer != null) {
|
||||||
Log.d(LOG_TAG, "AudioPlayer Error: Can't record in play mode.");
|
Log.d(LOG_TAG, "AudioPlayer Error: Can't record in play mode.");
|
||||||
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
|
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we're not already recording
|
// Make sure we're not already recording
|
||||||
else if (this.recorder == null) {
|
else if (this.recorder == null) {
|
||||||
this.audioFile = file;
|
this.audioFile = file;
|
||||||
@ -162,7 +160,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
f.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath()
|
f.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath()
|
||||||
+ File.separator + file));
|
+ File.separator + file));
|
||||||
} else {
|
} else {
|
||||||
f.renameTo(new File("/data/data/" + handler.ctx.getPackageName() + "/cache/" + file));
|
f.renameTo(new File("/data/data/" + handler.ctx.getActivity().getPackageName() + "/cache/" + file));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -187,13 +185,13 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Start or resume playing audio file.
|
* Start or resume playing audio file.
|
||||||
*
|
*
|
||||||
* @param file The name of the audio file.
|
* @param file The name of the audio file.
|
||||||
*/
|
*/
|
||||||
public void startPlaying(String file) {
|
public void startPlaying(String file) {
|
||||||
if (this.recorder != null) {
|
if (this.recorder != null) {
|
||||||
Log.d(LOG_TAG, "AudioPlayer Error: Can't play in record mode.");
|
Log.d(LOG_TAG, "AudioPlayer Error: Can't play in record mode.");
|
||||||
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
|
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a new request to play audio, or stopped
|
// If this is a new request to play audio, or stopped
|
||||||
@ -222,7 +220,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
else {
|
else {
|
||||||
if (file.startsWith("/android_asset/")) {
|
if (file.startsWith("/android_asset/")) {
|
||||||
String f = file.substring(15);
|
String f = file.substring(15);
|
||||||
android.content.res.AssetFileDescriptor fd = this.handler.ctx.getBaseContext().getAssets().openFd(f);
|
android.content.res.AssetFileDescriptor fd = this.handler.ctx.getActivity().getAssets().openFd(f);
|
||||||
this.mPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
|
this.mPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -242,10 +240,9 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
// Get duration
|
// Get duration
|
||||||
this.duration = getDurationInSeconds();
|
this.duration = getDurationInSeconds();
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
|
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,8 +255,8 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
this.setState(MEDIA_RUNNING);
|
this.setState(MEDIA_RUNNING);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log.d(LOG_TAG, "AudioPlayer Error: startPlaying() called during invalid state: "+this.state);
|
Log.d(LOG_TAG, "AudioPlayer Error: startPlaying() called during invalid state: " + this.state);
|
||||||
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_ABORTED+"});");
|
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_ABORTED + "});");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -271,7 +268,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
if (this.mPlayer != null) {
|
if (this.mPlayer != null) {
|
||||||
this.mPlayer.seekTo(milliseconds);
|
this.mPlayer.seekTo(milliseconds);
|
||||||
Log.d(LOG_TAG, "Send a onStatus update for the new seek");
|
Log.d(LOG_TAG, "Send a onStatus update for the new seek");
|
||||||
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_POSITION+", "+milliseconds/1000.0f+");");
|
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_POSITION + ", " + milliseconds / 1000.0f + ");");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,8 +283,8 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
this.setState(MEDIA_PAUSED);
|
this.setState(MEDIA_PAUSED);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log.d(LOG_TAG, "AudioPlayer Error: pausePlaying() called during invalid state: "+this.state);
|
Log.d(LOG_TAG, "AudioPlayer Error: pausePlaying() called during invalid state: " + this.state);
|
||||||
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_NONE_ACTIVE+"});");
|
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_NONE_ACTIVE + "});");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,15 +297,15 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
this.setState(MEDIA_STOPPED);
|
this.setState(MEDIA_STOPPED);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log.d(LOG_TAG, "AudioPlayer Error: stopPlaying() called during invalid state: "+this.state);
|
Log.d(LOG_TAG, "AudioPlayer Error: stopPlaying() called during invalid state: " + this.state);
|
||||||
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_ERROR+", { \"code\":"+MEDIA_ERR_NONE_ACTIVE+"});");
|
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_ERROR + ", { \"code\":" + MEDIA_ERR_NONE_ACTIVE + "});");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback to be invoked when playback of a media source has completed.
|
* Callback to be invoked when playback of a media source has completed.
|
||||||
*
|
*
|
||||||
* @param mPlayer The MediaPlayer that reached the end of the file
|
* @param mPlayer The MediaPlayer that reached the end of the file
|
||||||
*/
|
*/
|
||||||
public void onCompletion(MediaPlayer mPlayer) {
|
public void onCompletion(MediaPlayer mPlayer) {
|
||||||
this.setState(MEDIA_STOPPED);
|
this.setState(MEDIA_STOPPED);
|
||||||
@ -316,13 +313,13 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current position of playback.
|
* Get current position of playback.
|
||||||
*
|
*
|
||||||
* @return position in msec or -1 if not playing
|
* @return position in msec or -1 if not playing
|
||||||
*/
|
*/
|
||||||
public long getCurrentPosition() {
|
public long getCurrentPosition() {
|
||||||
if ((this.state == MEDIA_RUNNING) || (this.state == MEDIA_PAUSED)) {
|
if ((this.state == MEDIA_RUNNING) || (this.state == MEDIA_PAUSED)) {
|
||||||
int curPos = this.mPlayer.getCurrentPosition();
|
int curPos = this.mPlayer.getCurrentPosition();
|
||||||
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_POSITION+", "+curPos/1000.0f+");");
|
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_POSITION + ", " + curPos / 1000.0f + ");");
|
||||||
return curPos;
|
return curPos;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -333,9 +330,9 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
/**
|
/**
|
||||||
* Determine if playback file is streaming or local.
|
* Determine if playback file is streaming or local.
|
||||||
* It is streaming if file name starts with "http://"
|
* It is streaming if file name starts with "http://"
|
||||||
*
|
*
|
||||||
* @param file The file name
|
* @param file The file name
|
||||||
* @return T=streaming, F=local
|
* @return T=streaming, F=local
|
||||||
*/
|
*/
|
||||||
public boolean isStreaming(String file) {
|
public boolean isStreaming(String file) {
|
||||||
if (file.contains("http://") || file.contains("https://")) {
|
if (file.contains("http://") || file.contains("https://")) {
|
||||||
@ -346,19 +343,19 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the duration of the audio file.
|
* Get the duration of the audio file.
|
||||||
*
|
*
|
||||||
* @param file The name of the audio file.
|
* @param file The name of the audio file.
|
||||||
* @return The duration in msec.
|
* @return The duration in msec.
|
||||||
* -1=can't be determined
|
* -1=can't be determined
|
||||||
* -2=not allowed
|
* -2=not allowed
|
||||||
*/
|
*/
|
||||||
public float getDuration(String file) {
|
public float getDuration(String file) {
|
||||||
|
|
||||||
// Can't get duration of recording
|
// Can't get duration of recording
|
||||||
if (this.recorder != null) {
|
if (this.recorder != null) {
|
||||||
return(-2); // not allowed
|
return (-2); // not allowed
|
||||||
}
|
}
|
||||||
|
|
||||||
// If audio file already loaded and started, then return duration
|
// If audio file already loaded and started, then return duration
|
||||||
@ -378,9 +375,9 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback to be invoked when the media source is ready for playback.
|
* Callback to be invoked when the media source is ready for playback.
|
||||||
*
|
*
|
||||||
* @param mPlayer The MediaPlayer that is ready for playback
|
* @param mPlayer The MediaPlayer that is ready for playback
|
||||||
*/
|
*/
|
||||||
public void onPrepared(MediaPlayer mPlayer) {
|
public void onPrepared(MediaPlayer mPlayer) {
|
||||||
// Listen for playback completion
|
// Listen for playback completion
|
||||||
@ -401,13 +398,13 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
this.prepareOnly = false;
|
this.prepareOnly = false;
|
||||||
|
|
||||||
// Send status notification to JavaScript
|
// Send status notification to JavaScript
|
||||||
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_DURATION+","+this.duration+");");
|
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_DURATION + "," + this.duration + ");");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* By default Android returns the length of audio in mills but we want seconds
|
* By default Android returns the length of audio in mills but we want seconds
|
||||||
*
|
*
|
||||||
* @return length of clip in seconds
|
* @return length of clip in seconds
|
||||||
*/
|
*/
|
||||||
private float getDurationInSeconds() {
|
private float getDurationInSeconds() {
|
||||||
@ -417,31 +414,31 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
/**
|
/**
|
||||||
* Callback to be invoked when there has been an error during an asynchronous operation
|
* Callback to be invoked when there has been an error during an asynchronous operation
|
||||||
* (other errors will throw exceptions at method call time).
|
* (other errors will throw exceptions at method call time).
|
||||||
*
|
*
|
||||||
* @param mPlayer the MediaPlayer the error pertains to
|
* @param mPlayer the MediaPlayer the error pertains to
|
||||||
* @param arg1 the type of error that has occurred: (MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_SERVER_DIED)
|
* @param arg1 the type of error that has occurred: (MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_SERVER_DIED)
|
||||||
* @param arg2 an extra code, specific to the error.
|
* @param arg2 an extra code, specific to the error.
|
||||||
*/
|
*/
|
||||||
public boolean onError(MediaPlayer mPlayer, int arg1, int arg2) {
|
public boolean onError(MediaPlayer mPlayer, int arg1, int arg2) {
|
||||||
Log.d(LOG_TAG, "AudioPlayer.onError(" + arg1 + ", " + arg2+")");
|
Log.d(LOG_TAG, "AudioPlayer.onError(" + arg1 + ", " + arg2 + ")");
|
||||||
|
|
||||||
// TODO: Not sure if this needs to be sent?
|
// TODO: Not sure if this needs to be sent?
|
||||||
this.mPlayer.stop();
|
this.mPlayer.stop();
|
||||||
this.mPlayer.release();
|
this.mPlayer.release();
|
||||||
|
|
||||||
// Send error notification to JavaScript
|
// Send error notification to JavaScript
|
||||||
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', { \"code\":"+arg1+"});");
|
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', { \"code\":" + arg1 + "});");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the state and send it to JavaScript.
|
* Set the state and send it to JavaScript.
|
||||||
*
|
*
|
||||||
* @param state
|
* @param state
|
||||||
*/
|
*/
|
||||||
private void setState(int state) {
|
private void setState(int state) {
|
||||||
if (this.state != state) {
|
if (this.state != state) {
|
||||||
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', "+MEDIA_STATE+", "+state+");");
|
this.handler.sendJavascript("cordova.require('cordova/plugin/Media').onStatus('" + this.id + "', " + MEDIA_STATE + ", " + state + ");");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.state = state;
|
this.state = state;
|
||||||
@ -449,7 +446,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the audio state.
|
* Get the audio state.
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public int getState() {
|
public int getState() {
|
||||||
|
@ -24,7 +24,6 @@ import org.json.JSONArray;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -65,7 +64,7 @@ public class BatteryListener extends Plugin {
|
|||||||
this.batteryCallbackId = callbackId;
|
this.batteryCallbackId = callbackId;
|
||||||
|
|
||||||
// We need to listen to power events to update battery status
|
// We need to listen to power events to update battery status
|
||||||
IntentFilter intentFilter = new IntentFilter() ;
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||||
if (this.receiver == null) {
|
if (this.receiver == null) {
|
||||||
this.receiver = new BroadcastReceiver() {
|
this.receiver = new BroadcastReceiver() {
|
||||||
@ -74,7 +73,7 @@ public class BatteryListener extends Plugin {
|
|||||||
updateBatteryInfo(intent);
|
updateBatteryInfo(intent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ctx.registerReceiver(this.receiver, intentFilter);
|
ctx.getActivity().registerReceiver(this.receiver, intentFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't return any result now, since status results will be sent when events come in from broadcast receiver
|
// Don't return any result now, since status results will be sent when events come in from broadcast receiver
|
||||||
@ -106,7 +105,7 @@ public class BatteryListener extends Plugin {
|
|||||||
private void removeBatteryListener() {
|
private void removeBatteryListener() {
|
||||||
if (this.receiver != null) {
|
if (this.receiver != null) {
|
||||||
try {
|
try {
|
||||||
this.ctx.unregisterReceiver(this.receiver);
|
this.ctx.getActivity().unregisterReceiver(this.receiver);
|
||||||
this.receiver = null;
|
this.receiver = null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(LOG_TAG, "Error unregistering battery receiver: " + e.getMessage(), e);
|
Log.e(LOG_TAG, "Error unregistering battery receiver: " + e.getMessage(), e);
|
||||||
|
@ -53,6 +53,7 @@ import java.util.LinkedList;
|
|||||||
*/
|
*/
|
||||||
public class CallbackServer implements Runnable {
|
public class CallbackServer implements Runnable {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private static final String LOG_TAG = "CallbackServer";
|
private static final String LOG_TAG = "CallbackServer";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,7 +95,7 @@ public class CallbackServer implements Runnable {
|
|||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
public CallbackServer() {
|
public CallbackServer() {
|
||||||
//System.out.println("CallbackServer()");
|
//Log.d(LOG_TAG, "CallbackServer()");
|
||||||
this.active = false;
|
this.active = false;
|
||||||
this.empty = true;
|
this.empty = true;
|
||||||
this.port = 0;
|
this.port = 0;
|
||||||
@ -103,7 +104,7 @@ public class CallbackServer implements Runnable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Init callback server and start XHR if running local app.
|
* Init callback server and start XHR if running local app.
|
||||||
*
|
*
|
||||||
* If Cordova app is loaded from file://, then we can use XHR
|
* If Cordova app is loaded from file://, then we can use XHR
|
||||||
* otherwise we have to use polling due to cross-domain security restrictions.
|
* otherwise we have to use polling due to cross-domain security restrictions.
|
||||||
*
|
*
|
||||||
@ -143,7 +144,6 @@ public class CallbackServer implements Runnable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return if polling is being used instead of XHR.
|
* Return if polling is being used instead of XHR.
|
||||||
*
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean usePolling() {
|
public boolean usePolling() {
|
||||||
@ -152,7 +152,6 @@ public class CallbackServer implements Runnable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the port that this server is running on.
|
* Get the port that this server is running on.
|
||||||
*
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int getPort() {
|
public int getPort() {
|
||||||
@ -161,7 +160,6 @@ public class CallbackServer implements Runnable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the security token that this server requires when calling getJavascript().
|
* Get the security token that this server requires when calling getJavascript().
|
||||||
*
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String getToken() {
|
public String getToken() {
|
||||||
@ -172,7 +170,7 @@ public class CallbackServer implements Runnable {
|
|||||||
* Start the server on a new thread.
|
* Start the server on a new thread.
|
||||||
*/
|
*/
|
||||||
public void startServer() {
|
public void startServer() {
|
||||||
//System.out.println("CallbackServer.startServer()");
|
//Log.d(LOG_TAG, "CallbackServer.startServer()");
|
||||||
this.active = false;
|
this.active = false;
|
||||||
|
|
||||||
// Start server on new thread
|
// Start server on new thread
|
||||||
@ -193,7 +191,7 @@ public class CallbackServer implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start running the server.
|
* Start running the server.
|
||||||
* This is called automatically when the server thread is started.
|
* This is called automatically when the server thread is started.
|
||||||
*/
|
*/
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -204,90 +202,90 @@ public class CallbackServer implements Runnable {
|
|||||||
String request;
|
String request;
|
||||||
ServerSocket waitSocket = new ServerSocket(0);
|
ServerSocket waitSocket = new ServerSocket(0);
|
||||||
this.port = waitSocket.getLocalPort();
|
this.port = waitSocket.getLocalPort();
|
||||||
//System.out.println("CallbackServer -- using port " +this.port);
|
//Log.d(LOG_TAG, "CallbackServer -- using port " +this.port);
|
||||||
this.token = java.util.UUID.randomUUID().toString();
|
this.token = java.util.UUID.randomUUID().toString();
|
||||||
//System.out.println("CallbackServer -- using token "+this.token);
|
//Log.d(LOG_TAG, "CallbackServer -- using token "+this.token);
|
||||||
|
|
||||||
while (this.active) {
|
while (this.active) {
|
||||||
//System.out.println("CallbackServer: Waiting for data on socket");
|
//Log.d(LOG_TAG, "CallbackServer: Waiting for data on socket");
|
||||||
Socket connection = waitSocket.accept();
|
Socket connection = waitSocket.accept();
|
||||||
BufferedReader xhrReader = new BufferedReader(new InputStreamReader(connection.getInputStream()),40);
|
BufferedReader xhrReader = new BufferedReader(new InputStreamReader(connection.getInputStream()), 40);
|
||||||
DataOutputStream output = new DataOutputStream(connection.getOutputStream());
|
DataOutputStream output = new DataOutputStream(connection.getOutputStream());
|
||||||
request = xhrReader.readLine();
|
request = xhrReader.readLine();
|
||||||
String response = "";
|
String response = "";
|
||||||
//System.out.println("CallbackServerRequest="+request);
|
//Log.d(LOG_TAG, "CallbackServerRequest="+request);
|
||||||
if (this.active && (request != null)) {
|
if (this.active && (request != null)) {
|
||||||
if (request.contains("GET")) {
|
if (request.contains("GET")) {
|
||||||
|
|
||||||
// Get requested file
|
// Get requested file
|
||||||
String[] requestParts = request.split(" ");
|
String[] requestParts = request.split(" ");
|
||||||
|
|
||||||
// Must have security token
|
// Must have security token
|
||||||
if ((requestParts.length == 3) && (requestParts[1].substring(1).equals(this.token))) {
|
if ((requestParts.length == 3) && (requestParts[1].substring(1).equals(this.token))) {
|
||||||
//System.out.println("CallbackServer -- Processing GET request");
|
//Log.d(LOG_TAG, "CallbackServer -- Processing GET request");
|
||||||
|
|
||||||
// Wait until there is some data to send, or send empty data every 10 sec
|
// Wait until there is some data to send, or send empty data every 10 sec
|
||||||
// to prevent XHR timeout on the client
|
// to prevent XHR timeout on the client
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
while (this.empty) {
|
while (this.empty) {
|
||||||
try {
|
try {
|
||||||
this.wait(10000); // prevent timeout from happening
|
this.wait(10000); // prevent timeout from happening
|
||||||
//System.out.println("CallbackServer>>> break <<<");
|
//Log.d(LOG_TAG, "CallbackServer>>> break <<<");
|
||||||
break;
|
break;
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) { }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If server is still running
|
// If server is still running
|
||||||
if (this.active) {
|
if (this.active) {
|
||||||
|
|
||||||
// If no data, then send 404 back to client before it times out
|
// If no data, then send 404 back to client before it times out
|
||||||
if (this.empty) {
|
if (this.empty) {
|
||||||
//System.out.println("CallbackServer -- sending data 0");
|
//Log.d(LOG_TAG, "CallbackServer -- sending data 0");
|
||||||
response = "HTTP/1.1 404 NO DATA\r\n\r\n "; // need to send content otherwise some Android devices fail, so send space
|
response = "HTTP/1.1 404 NO DATA\r\n\r\n "; // need to send content otherwise some Android devices fail, so send space
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//System.out.println("CallbackServer -- sending item");
|
//Log.d(LOG_TAG, "CallbackServer -- sending item");
|
||||||
response = "HTTP/1.1 200 OK\r\n\r\n";
|
response = "HTTP/1.1 200 OK\r\n\r\n";
|
||||||
String js = this.getJavascript();
|
String js = this.getJavascript();
|
||||||
if (js != null) {
|
if (js != null) {
|
||||||
response += encode(js, "UTF-8");
|
response += encode(js, "UTF-8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
response = "HTTP/1.1 503 Service Unavailable\r\n\r\n ";
|
response = "HTTP/1.1 503 Service Unavailable\r\n\r\n ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
response = "HTTP/1.1 403 Forbidden\r\n\r\n ";
|
response = "HTTP/1.1 403 Forbidden\r\n\r\n ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
response = "HTTP/1.1 400 Bad Request\r\n\r\n ";
|
response = "HTTP/1.1 400 Bad Request\r\n\r\n ";
|
||||||
}
|
}
|
||||||
//System.out.println("CallbackServer: response="+response);
|
//Log.d(LOG_TAG, "CallbackServer: response="+response);
|
||||||
//System.out.println("CallbackServer: closing output");
|
//Log.d(LOG_TAG, "CallbackServer: closing output");
|
||||||
output.writeBytes(response);
|
output.writeBytes(response);
|
||||||
output.flush();
|
output.flush();
|
||||||
}
|
}
|
||||||
output.close();
|
output.close();
|
||||||
xhrReader.close();
|
xhrReader.close();
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
this.active = false;
|
this.active = false;
|
||||||
//System.out.println("CallbackServer.startServer() - EXIT");
|
//Log.d(LOG_TAG, "CallbackServer.startServer() - EXIT");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop server.
|
* Stop server.
|
||||||
* This stops the thread that the server is running on.
|
* This stops the thread that the server is running on.
|
||||||
*/
|
*/
|
||||||
public void stopServer() {
|
public void stopServer() {
|
||||||
//System.out.println("CallbackServer.stopServer()");
|
//Log.d(LOG_TAG, "CallbackServer.stopServer()");
|
||||||
if (this.active) {
|
if (this.active) {
|
||||||
this.active = false;
|
this.active = false;
|
||||||
|
|
||||||
@ -307,11 +305,11 @@ public class CallbackServer implements Runnable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of JavaScript statements.
|
* Get the number of JavaScript statements.
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
synchronized(this) {
|
synchronized (this) {
|
||||||
int size = this.javascript.size();
|
int size = this.javascript.size();
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@ -319,11 +317,11 @@ public class CallbackServer implements Runnable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next JavaScript statement and remove from list.
|
* Get the next JavaScript statement and remove from list.
|
||||||
*
|
*
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
public String getJavascript() {
|
public String getJavascript() {
|
||||||
synchronized(this) {
|
synchronized (this) {
|
||||||
if (this.javascript.size() == 0) {
|
if (this.javascript.size() == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -337,7 +335,7 @@ public class CallbackServer implements Runnable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a JavaScript statement to the list.
|
* Add a JavaScript statement to the list.
|
||||||
*
|
*
|
||||||
* @param statement
|
* @param statement
|
||||||
*/
|
*/
|
||||||
public void sendJavascript(String statement) {
|
public void sendJavascript(String statement) {
|
||||||
|
@ -26,6 +26,7 @@ import java.io.IOException;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
//import org.apache.cordova.api.CordovaInterface;
|
||||||
import org.apache.cordova.api.LOG;
|
import org.apache.cordova.api.LOG;
|
||||||
import org.apache.cordova.api.Plugin;
|
import org.apache.cordova.api.Plugin;
|
||||||
import org.apache.cordova.api.PluginResult;
|
import org.apache.cordova.api.PluginResult;
|
||||||
@ -34,6 +35,7 @@ import org.json.JSONException;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
|
//import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
@ -78,12 +80,23 @@ public class CameraLauncher extends Plugin {
|
|||||||
public String callbackId;
|
public String callbackId;
|
||||||
private int numPics;
|
private int numPics;
|
||||||
|
|
||||||
|
//This should never be null!
|
||||||
|
//private CordovaInterface cordova;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
public CameraLauncher() {
|
public CameraLauncher() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public void setContext(CordovaInterface mCtx) {
|
||||||
|
// super.setContext(mCtx);
|
||||||
|
// if (CordovaInterface.class.isInstance(mCtx))
|
||||||
|
// cordova = (CordovaInterface) mCtx;
|
||||||
|
// else
|
||||||
|
// LOG.d(LOG_TAG, "ERROR: You must use the CordovaInterface for this to work correctly. Please implement it in your activity");
|
||||||
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the request and returns PluginResult.
|
* Executes the request and returns PluginResult.
|
||||||
*
|
*
|
||||||
@ -163,7 +176,11 @@ public class CameraLauncher extends Plugin {
|
|||||||
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
|
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
|
||||||
this.imageUri = Uri.fromFile(photo);
|
this.imageUri = Uri.fromFile(photo);
|
||||||
|
|
||||||
this.ctx.startActivityForResult((Plugin) this, intent, (CAMERA+1)*16 + returnType+1);
|
if (this.ctx != null) {
|
||||||
|
this.ctx.startActivityForResult((Plugin) this, intent, (CAMERA + 1) * 16 + returnType + 1);
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// LOG.d(LOG_TAG, "ERROR: You must use the CordovaInterface for this to work correctly. Please implement it in your activity");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -175,9 +192,9 @@ public class CameraLauncher extends Plugin {
|
|||||||
private File createCaptureFile(int encodingType) {
|
private File createCaptureFile(int encodingType) {
|
||||||
File photo = null;
|
File photo = null;
|
||||||
if (encodingType == JPEG) {
|
if (encodingType == JPEG) {
|
||||||
photo = new File(DirectoryManager.getTempDirectoryPath(ctx.getContext()), "Pic.jpg");
|
photo = new File(DirectoryManager.getTempDirectoryPath(this.ctx.getActivity()), "Pic.jpg");
|
||||||
} else if (encodingType == PNG) {
|
} else if (encodingType == PNG) {
|
||||||
photo = new File(DirectoryManager.getTempDirectoryPath(ctx.getContext()), "Pic.png");
|
photo = new File(DirectoryManager.getTempDirectoryPath(this.ctx.getActivity()), "Pic.png");
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Invalid Encoding Type: " + encodingType);
|
throw new IllegalArgumentException("Invalid Encoding Type: " + encodingType);
|
||||||
}
|
}
|
||||||
@ -211,8 +228,10 @@ public class CameraLauncher extends Plugin {
|
|||||||
|
|
||||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
this.ctx.startActivityForResult((Plugin) this, Intent.createChooser(intent,
|
if (this.ctx != null) {
|
||||||
new String(title)), (srcType+1)*16 + returnType + 1);
|
this.ctx.startActivityForResult((Plugin) this, Intent.createChooser(intent,
|
||||||
|
new String(title)), (srcType + 1) * 16 + returnType + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -246,8 +265,8 @@ public class CameraLauncher extends Plugin {
|
|||||||
// kept and Bitmap.SCALE_TO_FIT specified when scaling, but this
|
// kept and Bitmap.SCALE_TO_FIT specified when scaling, but this
|
||||||
// would result in whitespace in the new image.
|
// would result in whitespace in the new image.
|
||||||
else {
|
else {
|
||||||
double newRatio = newWidth / (double)newHeight;
|
double newRatio = newWidth / (double) newHeight;
|
||||||
double origRatio = origWidth / (double)origHeight;
|
double origRatio = origWidth / (double) origHeight;
|
||||||
|
|
||||||
if (origRatio > newRatio) {
|
if (origRatio > newRatio) {
|
||||||
newHeight = (newWidth * origHeight) / origWidth;
|
newHeight = (newWidth * origHeight) / origWidth;
|
||||||
@ -272,21 +291,20 @@ public class CameraLauncher extends Plugin {
|
|||||||
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||||
|
|
||||||
// Get src and dest types from request code
|
// Get src and dest types from request code
|
||||||
int srcType = (requestCode/16) - 1;
|
int srcType = (requestCode / 16) - 1;
|
||||||
int destType = (requestCode % 16) - 1;
|
int destType = (requestCode % 16) - 1;
|
||||||
int rotate = 0;
|
int rotate = 0;
|
||||||
|
|
||||||
// Create an ExifHelper to save the exif data that is lost during compression
|
|
||||||
ExifHelper exif = new ExifHelper();
|
|
||||||
try {
|
|
||||||
if (this.encodingType == JPEG) {
|
|
||||||
exif.createInFile(DirectoryManager.getTempDirectoryPath(ctx.getContext()) + "/Pic.jpg");
|
|
||||||
exif.readExifData();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Create an ExifHelper to save the exif data that is lost during compression
|
||||||
|
ExifHelper exif = new ExifHelper();
|
||||||
|
try {
|
||||||
|
if (this.encodingType == JPEG) {
|
||||||
|
exif.createInFile(DirectoryManager.getTempDirectoryPath(this.ctx.getActivity()) + "/Pic.jpg");
|
||||||
|
exif.readExifData();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
// If CAMERA
|
// If CAMERA
|
||||||
if (srcType == CAMERA) {
|
if (srcType == CAMERA) {
|
||||||
// If image available
|
// If image available
|
||||||
@ -295,10 +313,10 @@ public class CameraLauncher extends Plugin {
|
|||||||
// Read in bitmap of captured image
|
// Read in bitmap of captured image
|
||||||
Bitmap bitmap;
|
Bitmap bitmap;
|
||||||
try {
|
try {
|
||||||
bitmap = android.provider.MediaStore.Images.Media.getBitmap(this.ctx.getContentResolver(), imageUri);
|
bitmap = android.provider.MediaStore.Images.Media.getBitmap(this.ctx.getActivity().getContentResolver(), imageUri);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
Uri uri = intent.getData();
|
Uri uri = intent.getData();
|
||||||
android.content.ContentResolver resolver = this.ctx.getContentResolver();
|
android.content.ContentResolver resolver = this.ctx.getActivity().getContentResolver();
|
||||||
bitmap = android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
|
bitmap = android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,18 +329,18 @@ public class CameraLauncher extends Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If sending filename back
|
// If sending filename back
|
||||||
else if (destType == FILE_URI){
|
else if (destType == FILE_URI) {
|
||||||
// Create entry in media store for image
|
// Create entry in media store for image
|
||||||
// (Don't use insertImage() because it uses default compression setting of 50 - no way to change it)
|
// (Don't use insertImage() because it uses default compression setting of 50 - no way to change it)
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(android.provider.MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
|
values.put(android.provider.MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
|
||||||
Uri uri = null;
|
Uri uri = null;
|
||||||
try {
|
try {
|
||||||
uri = this.ctx.getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
|
uri = this.ctx.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
|
||||||
} catch (UnsupportedOperationException e) {
|
} catch (UnsupportedOperationException e) {
|
||||||
LOG.d(LOG_TAG, "Can't write to external media storage.");
|
LOG.d(LOG_TAG, "Can't write to external media storage.");
|
||||||
try {
|
try {
|
||||||
uri = this.ctx.getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
|
uri = this.ctx.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
|
||||||
} catch (UnsupportedOperationException ex) {
|
} catch (UnsupportedOperationException ex) {
|
||||||
LOG.d(LOG_TAG, "Can't write to internal media storage.");
|
LOG.d(LOG_TAG, "Can't write to internal media storage.");
|
||||||
this.failPicture("Error capturing image - no media storage found.");
|
this.failPicture("Error capturing image - no media storage found.");
|
||||||
@ -331,7 +349,7 @@ public class CameraLauncher extends Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add compressed version of captured image to returned media store Uri
|
// Add compressed version of captured image to returned media store Uri
|
||||||
OutputStream os = this.ctx.getContentResolver().openOutputStream(uri);
|
OutputStream os = this.ctx.getActivity().getContentResolver().openOutputStream(uri);
|
||||||
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
|
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
|
||||||
os.close();
|
os.close();
|
||||||
|
|
||||||
@ -370,9 +388,9 @@ public class CameraLauncher extends Plugin {
|
|||||||
else if ((srcType == PHOTOLIBRARY) || (srcType == SAVEDPHOTOALBUM)) {
|
else if ((srcType == PHOTOLIBRARY) || (srcType == SAVEDPHOTOALBUM)) {
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
Uri uri = intent.getData();
|
Uri uri = intent.getData();
|
||||||
android.content.ContentResolver resolver = this.ctx.getContentResolver();
|
android.content.ContentResolver resolver = this.ctx.getActivity().getContentResolver();
|
||||||
|
|
||||||
// If you ask for video or all media type you will automatically get back a file URI
|
// If you ask for video or all media type you will automatically get back a file URI
|
||||||
// and there will be no attempt to resize any returned data
|
// and there will be no attempt to resize any returned data
|
||||||
if (this.mediaType != PICTURE) {
|
if (this.mediaType != PICTURE) {
|
||||||
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
|
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
|
||||||
@ -382,21 +400,21 @@ public class CameraLauncher extends Plugin {
|
|||||||
if (destType == DATA_URL) {
|
if (destType == DATA_URL) {
|
||||||
try {
|
try {
|
||||||
Bitmap bitmap = android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
|
Bitmap bitmap = android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
|
||||||
String[] cols = { MediaStore.Images.Media.ORIENTATION };
|
String[] cols = { MediaStore.Images.Media.ORIENTATION };
|
||||||
Cursor cursor = this.ctx.getContentResolver().query(intent.getData(),
|
Cursor cursor = this.ctx.getActivity().getContentResolver().query(intent.getData(),
|
||||||
cols,
|
cols,
|
||||||
null, null, null);
|
null, null, null);
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
cursor.moveToPosition(0);
|
cursor.moveToPosition(0);
|
||||||
rotate = cursor.getInt(0);
|
rotate = cursor.getInt(0);
|
||||||
cursor.close();
|
cursor.close();
|
||||||
}
|
}
|
||||||
if (rotate != 0) {
|
if (rotate != 0) {
|
||||||
Matrix matrix = new Matrix();
|
Matrix matrix = new Matrix();
|
||||||
matrix.setRotate(rotate);
|
matrix.setRotate(rotate);
|
||||||
bitmap = bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||||
}
|
}
|
||||||
bitmap = scaleBitmap(bitmap);
|
bitmap = scaleBitmap(bitmap);
|
||||||
this.processPicture(bitmap);
|
this.processPicture(bitmap);
|
||||||
bitmap.recycle();
|
bitmap.recycle();
|
||||||
bitmap = null;
|
bitmap = null;
|
||||||
@ -415,7 +433,7 @@ public class CameraLauncher extends Plugin {
|
|||||||
Bitmap bitmap = android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
|
Bitmap bitmap = android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
|
||||||
bitmap = scaleBitmap(bitmap);
|
bitmap = scaleBitmap(bitmap);
|
||||||
|
|
||||||
String fileName = DirectoryManager.getTempDirectoryPath(ctx.getContext()) + "/resize.jpg";
|
String fileName = DirectoryManager.getTempDirectoryPath(this.ctx.getActivity()) + "/resize.jpg";
|
||||||
OutputStream os = new FileOutputStream(fileName);
|
OutputStream os = new FileOutputStream(fileName);
|
||||||
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
|
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
|
||||||
os.close();
|
os.close();
|
||||||
@ -429,7 +447,7 @@ public class CameraLauncher extends Plugin {
|
|||||||
bitmap.recycle();
|
bitmap.recycle();
|
||||||
bitmap = null;
|
bitmap = null;
|
||||||
|
|
||||||
// The resized image is cached by the app in order to get around this and not have to delete you
|
// The resized image is cached by the app in order to get around this and not have to delete you
|
||||||
// application cache I'm adding the current system time to the end of the file url.
|
// application cache I'm adding the current system time to the end of the file url.
|
||||||
this.success(new PluginResult(PluginResult.Status.OK, ("file://" + fileName + "?" + System.currentTimeMillis())), this.callbackId);
|
this.success(new PluginResult(PluginResult.Status.OK, ("file://" + fileName + "?" + System.currentTimeMillis())), this.callbackId);
|
||||||
System.gc();
|
System.gc();
|
||||||
@ -459,7 +477,7 @@ public class CameraLauncher extends Plugin {
|
|||||||
* @return a cursor
|
* @return a cursor
|
||||||
*/
|
*/
|
||||||
private Cursor queryImgDB() {
|
private Cursor queryImgDB() {
|
||||||
return this.ctx.getContentResolver().query(
|
return this.ctx.getActivity().getContentResolver().query(
|
||||||
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
||||||
new String[] { MediaStore.Images.Media._ID },
|
new String[] { MediaStore.Images.Media._ID },
|
||||||
null,
|
null,
|
||||||
@ -488,7 +506,7 @@ public class CameraLauncher extends Plugin {
|
|||||||
cursor.moveToLast();
|
cursor.moveToLast();
|
||||||
int id = Integer.valueOf(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media._ID))) - 1;
|
int id = Integer.valueOf(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media._ID))) - 1;
|
||||||
Uri uri = Uri.parse(MediaStore.Images.Media.EXTERNAL_CONTENT_URI + "/" + id);
|
Uri uri = Uri.parse(MediaStore.Images.Media.EXTERNAL_CONTENT_URI + "/" + id);
|
||||||
this.ctx.getContentResolver().delete(uri, null, null);
|
this.ctx.getActivity().getContentResolver().delete(uri, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,7 +519,7 @@ public class CameraLauncher extends Plugin {
|
|||||||
ByteArrayOutputStream jpeg_data = new ByteArrayOutputStream();
|
ByteArrayOutputStream jpeg_data = new ByteArrayOutputStream();
|
||||||
try {
|
try {
|
||||||
if (bitmap.compress(CompressFormat.JPEG, mQuality, jpeg_data)) {
|
if (bitmap.compress(CompressFormat.JPEG, mQuality, jpeg_data)) {
|
||||||
byte[] code = jpeg_data.toByteArray();
|
byte[] code = jpeg_data.toByteArray();
|
||||||
byte[] output = Base64.encodeBase64(code);
|
byte[] output = Base64.encodeBase64(code);
|
||||||
String js_out = new String(output);
|
String js_out = new String(output);
|
||||||
this.success(new PluginResult(PluginResult.Status.OK, js_out), this.callbackId);
|
this.success(new PluginResult(PluginResult.Status.OK, js_out), this.callbackId);
|
||||||
@ -509,8 +527,7 @@ public class CameraLauncher extends Plugin {
|
|||||||
output = null;
|
output = null;
|
||||||
code = null;
|
code = null;
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch(Exception e) {
|
|
||||||
this.failPicture("Error compressing image.");
|
this.failPicture("Error compressing image.");
|
||||||
}
|
}
|
||||||
jpeg_data = null;
|
jpeg_data = null;
|
||||||
|
@ -38,11 +38,10 @@ import android.media.MediaPlayer;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
||||||
public class Capture extends Plugin {
|
public class Capture extends Plugin {
|
||||||
|
|
||||||
private static final String VIDEO_3GPP = "video/3gpp";
|
private static final String VIDEO_3GPP = "video/3gpp";
|
||||||
private static final String VIDEO_MP4 = "video/mp4";
|
private static final String VIDEO_MP4 = "video/mp4";
|
||||||
private static final String AUDIO_3GPP = "audio/3gpp";
|
private static final String AUDIO_3GPP = "audio/3gpp";
|
||||||
private static final String IMAGE_JPEG = "image/jpeg";
|
private static final String IMAGE_JPEG = "image/jpeg";
|
||||||
|
|
||||||
@ -52,8 +51,8 @@ public class Capture extends Plugin {
|
|||||||
private static final String LOG_TAG = "Capture";
|
private static final String LOG_TAG = "Capture";
|
||||||
|
|
||||||
private static final int CAPTURE_INTERNAL_ERR = 0;
|
private static final int CAPTURE_INTERNAL_ERR = 0;
|
||||||
private static final int CAPTURE_APPLICATION_BUSY = 1;
|
// private static final int CAPTURE_APPLICATION_BUSY = 1;
|
||||||
private static final int CAPTURE_INVALID_ARGUMENT = 2;
|
// private static final int CAPTURE_INVALID_ARGUMENT = 2;
|
||||||
private static final int CAPTURE_NO_MEDIA_FILES = 3;
|
private static final int CAPTURE_NO_MEDIA_FILES = 3;
|
||||||
private static final int CAPTURE_NOT_SUPPORTED = 20;
|
private static final int CAPTURE_NOT_SUPPORTED = 20;
|
||||||
|
|
||||||
@ -63,6 +62,16 @@ public class Capture extends Plugin {
|
|||||||
private JSONArray results; // The array of results to be returned to the user
|
private JSONArray results; // The array of results to be returned to the user
|
||||||
private Uri imageUri; // Uri of captured image
|
private Uri imageUri; // Uri of captured image
|
||||||
|
|
||||||
|
//private CordovaInterface cordova;
|
||||||
|
|
||||||
|
// public void setContext(Context mCtx)
|
||||||
|
// {
|
||||||
|
// if (CordovaInterface.class.isInstance(mCtx))
|
||||||
|
// cordova = (CordovaInterface) mCtx;
|
||||||
|
// else
|
||||||
|
// LOG.d(LOG_TAG, "ERROR: You must use the CordovaInterface for this to work correctly. Please implement it in your activity");
|
||||||
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||||
this.callbackId = callbackId;
|
this.callbackId = callbackId;
|
||||||
@ -132,8 +141,7 @@ public class Capture extends Plugin {
|
|||||||
else if (mimeType.equals(VIDEO_3GPP) || mimeType.equals(VIDEO_MP4)) {
|
else if (mimeType.equals(VIDEO_3GPP) || mimeType.equals(VIDEO_MP4)) {
|
||||||
obj = getAudioVideoData(filePath, obj, true);
|
obj = getAudioVideoData(filePath, obj, true);
|
||||||
}
|
}
|
||||||
}
|
} catch (JSONException e) {
|
||||||
catch (JSONException e) {
|
|
||||||
Log.d(LOG_TAG, "Error: setting media file data object");
|
Log.d(LOG_TAG, "Error: setting media file data object");
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
@ -169,13 +177,12 @@ public class Capture extends Plugin {
|
|||||||
try {
|
try {
|
||||||
player.setDataSource(filePath);
|
player.setDataSource(filePath);
|
||||||
player.prepare();
|
player.prepare();
|
||||||
obj.put("duration", player.getDuration()/1000);
|
obj.put("duration", player.getDuration() / 1000);
|
||||||
if (video) {
|
if (video) {
|
||||||
obj.put("height", player.getVideoHeight());
|
obj.put("height", player.getVideoHeight());
|
||||||
obj.put("width", player.getVideoWidth());
|
obj.put("width", player.getVideoWidth());
|
||||||
}
|
}
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e) {
|
|
||||||
Log.d(LOG_TAG, "Error: loading video file");
|
Log.d(LOG_TAG, "Error: loading video file");
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
@ -197,7 +204,7 @@ public class Capture extends Plugin {
|
|||||||
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
|
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
|
||||||
|
|
||||||
// Specify file so that large image is captured and returned
|
// Specify file so that large image is captured and returned
|
||||||
File photo = new File(DirectoryManager.getTempDirectoryPath(ctx.getContext()), "Capture.jpg");
|
File photo = new File(DirectoryManager.getTempDirectoryPath(this.ctx.getActivity()), "Capture.jpg");
|
||||||
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
|
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
|
||||||
this.imageUri = Uri.fromFile(photo);
|
this.imageUri = Uri.fromFile(photo);
|
||||||
|
|
||||||
@ -250,11 +257,11 @@ public class Capture extends Plugin {
|
|||||||
try {
|
try {
|
||||||
// Create an ExifHelper to save the exif data that is lost during compression
|
// Create an ExifHelper to save the exif data that is lost during compression
|
||||||
ExifHelper exif = new ExifHelper();
|
ExifHelper exif = new ExifHelper();
|
||||||
exif.createInFile(DirectoryManager.getTempDirectoryPath(ctx.getContext()) + "/Capture.jpg");
|
exif.createInFile(DirectoryManager.getTempDirectoryPath(this.ctx.getActivity()) + "/Capture.jpg");
|
||||||
exif.readExifData();
|
exif.readExifData();
|
||||||
|
|
||||||
// Read in bitmap of captured image
|
// Read in bitmap of captured image
|
||||||
Bitmap bitmap = android.provider.MediaStore.Images.Media.getBitmap(this.ctx.getContentResolver(), imageUri);
|
Bitmap bitmap = android.provider.MediaStore.Images.Media.getBitmap(this.ctx.getActivity().getContentResolver(), imageUri);
|
||||||
|
|
||||||
// Create entry in media store for image
|
// Create entry in media store for image
|
||||||
// (Don't use insertImage() because it uses default compression setting of 50 - no way to change it)
|
// (Don't use insertImage() because it uses default compression setting of 50 - no way to change it)
|
||||||
@ -262,11 +269,11 @@ public class Capture extends Plugin {
|
|||||||
values.put(android.provider.MediaStore.Images.Media.MIME_TYPE, IMAGE_JPEG);
|
values.put(android.provider.MediaStore.Images.Media.MIME_TYPE, IMAGE_JPEG);
|
||||||
Uri uri = null;
|
Uri uri = null;
|
||||||
try {
|
try {
|
||||||
uri = this.ctx.getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
|
uri = this.ctx.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
|
||||||
} catch (UnsupportedOperationException e) {
|
} catch (UnsupportedOperationException e) {
|
||||||
LOG.d(LOG_TAG, "Can't write to external media storage.");
|
LOG.d(LOG_TAG, "Can't write to external media storage.");
|
||||||
try {
|
try {
|
||||||
uri = this.ctx.getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
|
uri = this.ctx.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
|
||||||
} catch (UnsupportedOperationException ex) {
|
} catch (UnsupportedOperationException ex) {
|
||||||
LOG.d(LOG_TAG, "Can't write to internal media storage.");
|
LOG.d(LOG_TAG, "Can't write to internal media storage.");
|
||||||
this.fail(createErrorObject(CAPTURE_INTERNAL_ERR, "Error capturing image - no media storage found."));
|
this.fail(createErrorObject(CAPTURE_INTERNAL_ERR, "Error capturing image - no media storage found."));
|
||||||
@ -275,7 +282,7 @@ public class Capture extends Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add compressed version of captured image to returned media store Uri
|
// Add compressed version of captured image to returned media store Uri
|
||||||
OutputStream os = this.ctx.getContentResolver().openOutputStream(uri);
|
OutputStream os = this.ctx.getActivity().getContentResolver().openOutputStream(uri);
|
||||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
|
||||||
os.close();
|
os.close();
|
||||||
|
|
||||||
@ -347,7 +354,7 @@ public class Capture extends Plugin {
|
|||||||
* @return a JSONObject that represents a File
|
* @return a JSONObject that represents a File
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private JSONObject createMediaFile(Uri data){
|
private JSONObject createMediaFile(Uri data) {
|
||||||
File fp = new File(FileUtils.getRealPathFromURI(data, this.ctx));
|
File fp = new File(FileUtils.getRealPathFromURI(data, this.ctx));
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
|
|
||||||
@ -355,9 +362,8 @@ public class Capture extends Plugin {
|
|||||||
// File properties
|
// File properties
|
||||||
obj.put("name", fp.getName());
|
obj.put("name", fp.getName());
|
||||||
obj.put("fullPath", "file://" + fp.getAbsolutePath());
|
obj.put("fullPath", "file://" + fp.getAbsolutePath());
|
||||||
|
// Because of an issue with MimeTypeMap.getMimeTypeFromExtension() all .3gpp files
|
||||||
// Because of an issue with MimeTypeMap.getMimeTypeFromExtension() all .3gpp files
|
// are reported as video/3gpp. I'm doing this hacky check of the URI to see if it
|
||||||
// are reported as video/3gpp. I'm doing this hacky check of the URI to see if it
|
|
||||||
// is stored in the audio or video content store.
|
// is stored in the audio or video content store.
|
||||||
if (fp.getAbsoluteFile().toString().endsWith(".3gp") || fp.getAbsoluteFile().toString().endsWith(".3gpp")) {
|
if (fp.getAbsoluteFile().toString().endsWith(".3gp") || fp.getAbsoluteFile().toString().endsWith(".3gpp")) {
|
||||||
if (data.toString().contains("/audio/")) {
|
if (data.toString().contains("/audio/")) {
|
||||||
|
@ -27,7 +27,6 @@ import org.json.JSONArray;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
|
||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
@ -72,7 +71,7 @@ public class CompassListener extends Plugin implements SensorEventListener {
|
|||||||
*/
|
*/
|
||||||
public void setContext(CordovaInterface ctx) {
|
public void setContext(CordovaInterface ctx) {
|
||||||
super.setContext(ctx);
|
super.setContext(ctx);
|
||||||
this.sensorManager = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE);
|
this.sensorManager = (SensorManager) ctx.getActivity().getSystemService(Context.SENSOR_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -184,6 +183,7 @@ public class CompassListener extends Plugin implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get compass sensor from sensor manager
|
// Get compass sensor from sensor manager
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
|
List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
|
||||||
|
|
||||||
// If found, then register as listener
|
// If found, then register as listener
|
||||||
@ -212,7 +212,6 @@ public class CompassListener extends Plugin implements SensorEventListener {
|
|||||||
this.setStatus(CompassListener.STOPPED);
|
this.setStatus(CompassListener.STOPPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import android.content.Context;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
|
|
||||||
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@ -36,7 +37,7 @@ import org.json.JSONObject;
|
|||||||
public abstract class ContactAccessor {
|
public abstract class ContactAccessor {
|
||||||
|
|
||||||
protected final String LOG_TAG = "ContactsAccessor";
|
protected final String LOG_TAG = "ContactsAccessor";
|
||||||
protected Context mApp;
|
protected CordovaInterface mApp;
|
||||||
protected WebView mView;
|
protected WebView mView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,7 +76,7 @@ public abstract class ContactAccessor {
|
|||||||
map.put("urls", true);
|
map.put("urls", true);
|
||||||
map.put("photos", true);
|
map.put("photos", true);
|
||||||
map.put("categories", true);
|
map.put("categories", true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (int i=0; i<fields.length(); i++) {
|
for (int i=0; i<fields.length(); i++) {
|
||||||
key = fields.getString(i);
|
key = fields.getString(i);
|
||||||
@ -121,7 +122,7 @@ public abstract class ContactAccessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (JSONException e) {
|
catch (JSONException e) {
|
||||||
Log.e(LOG_TAG, e.getMessage(), e);
|
Log.e(LOG_TAG, e.getMessage(), e);
|
||||||
}
|
}
|
||||||
@ -147,7 +148,7 @@ public abstract class ContactAccessor {
|
|||||||
value = null;
|
value = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (JSONException e) {
|
catch (JSONException e) {
|
||||||
Log.d(LOG_TAG, "Could not get = " + e.getMessage());
|
Log.d(LOG_TAG, "Could not get = " + e.getMessage());
|
||||||
}
|
}
|
||||||
@ -176,8 +177,8 @@ public abstract class ContactAccessor {
|
|||||||
*/
|
*/
|
||||||
public abstract boolean remove(String id);
|
public abstract boolean remove(String id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that represents the where clause to be used in the database query
|
* A class that represents the where clause to be used in the database query
|
||||||
*/
|
*/
|
||||||
class WhereOptions {
|
class WhereOptions {
|
||||||
private String where;
|
private String where;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -69,7 +69,7 @@ public class ContactManager extends Plugin {
|
|||||||
* older phones.
|
* older phones.
|
||||||
*/
|
*/
|
||||||
if (this.contactAccessor == null) {
|
if (this.contactAccessor == null) {
|
||||||
this.contactAccessor = new ContactAccessorSdk5(this.webView, this.ctx.getContext());
|
this.contactAccessor = new ContactAccessorSdk5(this.webView, this.ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -17,16 +17,18 @@
|
|||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
import org.apache.cordova.api.LOG;
|
import org.apache.cordova.api.LOG;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
//import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
//import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.View;
|
//import android.view.View;
|
||||||
import android.webkit.ConsoleMessage;
|
import android.webkit.ConsoleMessage;
|
||||||
import android.webkit.JsPromptResult;
|
import android.webkit.JsPromptResult;
|
||||||
import android.webkit.JsResult;
|
import android.webkit.JsResult;
|
||||||
@ -41,18 +43,38 @@ import android.widget.EditText;
|
|||||||
*/
|
*/
|
||||||
public class CordovaChromeClient extends WebChromeClient {
|
public class CordovaChromeClient extends WebChromeClient {
|
||||||
|
|
||||||
|
|
||||||
private String TAG = "CordovaLog";
|
private String TAG = "CordovaLog";
|
||||||
private long MAX_QUOTA = 100 * 1024 * 1024;
|
private long MAX_QUOTA = 100 * 1024 * 1024;
|
||||||
private DroidGap ctx;
|
private CordovaInterface ctx;
|
||||||
|
private CordovaWebView appView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param ctx
|
||||||
*/
|
*/
|
||||||
public CordovaChromeClient(Context ctx) {
|
public CordovaChromeClient(CordovaInterface ctx) {
|
||||||
this.ctx = (DroidGap) ctx;
|
this.ctx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param ctx
|
||||||
|
* @param app
|
||||||
|
*/
|
||||||
|
public CordovaChromeClient(CordovaInterface ctx, CordovaWebView app) {
|
||||||
|
this.ctx = ctx;
|
||||||
|
this.appView = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param view
|
||||||
|
*/
|
||||||
|
public void setWebView(CordovaWebView view) {
|
||||||
|
this.appView = view;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,35 +87,35 @@ public class CordovaChromeClient extends WebChromeClient {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
|
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
|
||||||
AlertDialog.Builder dlg = new AlertDialog.Builder(this.ctx);
|
AlertDialog.Builder dlg = new AlertDialog.Builder(this.ctx.getActivity());
|
||||||
dlg.setMessage(message);
|
dlg.setMessage(message);
|
||||||
dlg.setTitle("Alert");
|
dlg.setTitle("Alert");
|
||||||
//Don't let alerts break the back button
|
//Don't let alerts break the back button
|
||||||
dlg.setCancelable(true);
|
dlg.setCancelable(true);
|
||||||
dlg.setPositiveButton(android.R.string.ok,
|
dlg.setPositiveButton(android.R.string.ok,
|
||||||
new AlertDialog.OnClickListener() {
|
new AlertDialog.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
result.confirm();
|
result.confirm();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dlg.setOnCancelListener(
|
dlg.setOnCancelListener(
|
||||||
new DialogInterface.OnCancelListener() {
|
new DialogInterface.OnCancelListener() {
|
||||||
public void onCancel(DialogInterface dialog) {
|
public void onCancel(DialogInterface dialog) {
|
||||||
result.confirm();
|
result.confirm();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
||||||
//DO NOTHING
|
//DO NOTHING
|
||||||
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
||||||
if(keyCode == KeyEvent.KEYCODE_BACK)
|
if (keyCode == KeyEvent.KEYCODE_BACK)
|
||||||
{
|
{
|
||||||
result.confirm();
|
result.confirm();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dlg.create();
|
dlg.create();
|
||||||
dlg.show();
|
dlg.show();
|
||||||
return true;
|
return true;
|
||||||
@ -109,40 +131,40 @@ public class CordovaChromeClient extends WebChromeClient {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
|
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
|
||||||
AlertDialog.Builder dlg = new AlertDialog.Builder(this.ctx);
|
AlertDialog.Builder dlg = new AlertDialog.Builder(this.ctx.getActivity());
|
||||||
dlg.setMessage(message);
|
dlg.setMessage(message);
|
||||||
dlg.setTitle("Confirm");
|
dlg.setTitle("Confirm");
|
||||||
dlg.setCancelable(true);
|
dlg.setCancelable(true);
|
||||||
dlg.setPositiveButton(android.R.string.ok,
|
dlg.setPositiveButton(android.R.string.ok,
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
result.confirm();
|
result.confirm();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dlg.setNegativeButton(android.R.string.cancel,
|
dlg.setNegativeButton(android.R.string.cancel,
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
result.cancel();
|
result.cancel();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dlg.setOnCancelListener(
|
dlg.setOnCancelListener(
|
||||||
new DialogInterface.OnCancelListener() {
|
new DialogInterface.OnCancelListener() {
|
||||||
public void onCancel(DialogInterface dialog) {
|
public void onCancel(DialogInterface dialog) {
|
||||||
result.cancel();
|
result.cancel();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
||||||
//DO NOTHING
|
//DO NOTHING
|
||||||
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
||||||
if(keyCode == KeyEvent.KEYCODE_BACK)
|
if (keyCode == KeyEvent.KEYCODE_BACK)
|
||||||
{
|
{
|
||||||
result.cancel();
|
result.cancel();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dlg.create();
|
dlg.create();
|
||||||
dlg.show();
|
dlg.show();
|
||||||
return true;
|
return true;
|
||||||
@ -168,11 +190,11 @@ public class CordovaChromeClient extends WebChromeClient {
|
|||||||
// Security check to make sure any requests are coming from the page initially
|
// Security check to make sure any requests are coming from the page initially
|
||||||
// loaded in webview and not another loaded in an iframe.
|
// loaded in webview and not another loaded in an iframe.
|
||||||
boolean reqOk = false;
|
boolean reqOk = false;
|
||||||
if (url.startsWith("file://") || url.indexOf(this.ctx.baseUrl) == 0 || ctx.isUrlWhiteListed(url)) {
|
if (url.startsWith("file://") || url.indexOf(this.appView.baseUrl) == 0 || this.appView.isUrlWhiteListed(url)) {
|
||||||
reqOk = true;
|
reqOk = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calling PluginManager.exec() to call a native service using
|
// Calling PluginManager.exec() to call a native service using
|
||||||
// prompt(this.stringify(args), "gap:"+this.stringify([service, action, callbackId, true]));
|
// prompt(this.stringify(args), "gap:"+this.stringify([service, action, callbackId, true]));
|
||||||
if (reqOk && defaultValue != null && defaultValue.length() > 3 && defaultValue.substring(0, 4).equals("gap:")) {
|
if (reqOk && defaultValue != null && defaultValue.length() > 3 && defaultValue.substring(0, 4).equals("gap:")) {
|
||||||
JSONArray array;
|
JSONArray array;
|
||||||
@ -182,72 +204,66 @@ public class CordovaChromeClient extends WebChromeClient {
|
|||||||
String action = array.getString(1);
|
String action = array.getString(1);
|
||||||
String callbackId = array.getString(2);
|
String callbackId = array.getString(2);
|
||||||
boolean async = array.getBoolean(3);
|
boolean async = array.getBoolean(3);
|
||||||
String r = ctx.pluginManager.exec(service, action, callbackId, message, async);
|
String r = this.appView.pluginManager.exec(service, action, callbackId, message, async);
|
||||||
result.confirm(r);
|
result.confirm(r);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Polling for JavaScript messages
|
// Polling for JavaScript messages
|
||||||
else if (reqOk && defaultValue != null && defaultValue.equals("gap_poll:")) {
|
else if (reqOk && defaultValue != null && defaultValue.equals("gap_poll:")) {
|
||||||
String r = ctx.callbackServer.getJavascript();
|
String r = this.appView.callbackServer.getJavascript();
|
||||||
result.confirm(r);
|
result.confirm(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do NO-OP so older code doesn't display dialog
|
||||||
|
else if (defaultValue.equals("gap_init:")) {
|
||||||
|
result.confirm("OK");
|
||||||
|
}
|
||||||
|
|
||||||
// Calling into CallbackServer
|
// Calling into CallbackServer
|
||||||
else if (reqOk && defaultValue != null && defaultValue.equals("gap_callbackServer:")) {
|
else if (reqOk && defaultValue != null && defaultValue.equals("gap_callbackServer:")) {
|
||||||
String r = "";
|
String r = "";
|
||||||
if (message.equals("usePolling")) {
|
if (message.equals("usePolling")) {
|
||||||
r = ""+ ctx.callbackServer.usePolling();
|
r = "" + this.appView.callbackServer.usePolling();
|
||||||
}
|
}
|
||||||
else if (message.equals("restartServer")) {
|
else if (message.equals("restartServer")) {
|
||||||
ctx.callbackServer.restartServer();
|
this.appView.callbackServer.restartServer();
|
||||||
}
|
}
|
||||||
else if (message.equals("getPort")) {
|
else if (message.equals("getPort")) {
|
||||||
r = Integer.toString(ctx.callbackServer.getPort());
|
r = Integer.toString(this.appView.callbackServer.getPort());
|
||||||
}
|
}
|
||||||
else if (message.equals("getToken")) {
|
else if (message.equals("getToken")) {
|
||||||
r = ctx.callbackServer.getToken();
|
r = this.appView.callbackServer.getToken();
|
||||||
}
|
}
|
||||||
result.confirm(r);
|
result.confirm(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cordova JS has initialized, so show webview
|
|
||||||
// (This solves white flash seen when rendering HTML)
|
|
||||||
else if (reqOk && defaultValue != null && defaultValue.equals("gap_init:")) {
|
|
||||||
if (ctx.splashscreen != 0) {
|
|
||||||
ctx.root.setBackgroundResource(0);
|
|
||||||
}
|
|
||||||
ctx.appView.setVisibility(View.VISIBLE);
|
|
||||||
ctx.spinnerStop();
|
|
||||||
result.confirm("OK");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show dialog
|
// Show dialog
|
||||||
else {
|
else {
|
||||||
final JsPromptResult res = result;
|
final JsPromptResult res = result;
|
||||||
AlertDialog.Builder dlg = new AlertDialog.Builder(this.ctx);
|
AlertDialog.Builder dlg = new AlertDialog.Builder(this.ctx.getActivity());
|
||||||
dlg.setMessage(message);
|
dlg.setMessage(message);
|
||||||
final EditText input = new EditText(this.ctx);
|
final EditText input = new EditText(this.ctx.getActivity());
|
||||||
if (defaultValue != null) {
|
if (defaultValue != null) {
|
||||||
input.setText(defaultValue);
|
input.setText(defaultValue);
|
||||||
}
|
}
|
||||||
dlg.setView(input);
|
dlg.setView(input);
|
||||||
dlg.setCancelable(false);
|
dlg.setCancelable(false);
|
||||||
dlg.setPositiveButton(android.R.string.ok,
|
dlg.setPositiveButton(android.R.string.ok,
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
String usertext = input.getText().toString();
|
String usertext = input.getText().toString();
|
||||||
res.confirm(usertext);
|
res.confirm(usertext);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dlg.setNegativeButton(android.R.string.cancel,
|
dlg.setNegativeButton(android.R.string.cancel,
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
res.cancel();
|
res.cancel();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dlg.create();
|
dlg.create();
|
||||||
dlg.show();
|
dlg.show();
|
||||||
}
|
}
|
||||||
@ -270,7 +286,7 @@ public class CordovaChromeClient extends WebChromeClient {
|
|||||||
{
|
{
|
||||||
LOG.d(TAG, "DroidGap: onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota);
|
LOG.d(TAG, "DroidGap: onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota);
|
||||||
|
|
||||||
if( estimatedSize < MAX_QUOTA)
|
if (estimatedSize < MAX_QUOTA)
|
||||||
{
|
{
|
||||||
//increase for 1Mb
|
//increase for 1Mb
|
||||||
long newQuota = estimatedSize;
|
long newQuota = estimatedSize;
|
||||||
@ -286,6 +302,7 @@ public class CordovaChromeClient extends WebChromeClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// console.log in api level 7: http://developer.android.com/guide/developing/debug-tasks.html
|
// console.log in api level 7: http://developer.android.com/guide/developing/debug-tasks.html
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public void onConsoleMessage(String message, int lineNumber, String sourceID)
|
public void onConsoleMessage(String message, int lineNumber, String sourceID)
|
||||||
{
|
{
|
||||||
@ -296,7 +313,7 @@ public class CordovaChromeClient extends WebChromeClient {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onConsoleMessage(ConsoleMessage consoleMessage)
|
public boolean onConsoleMessage(ConsoleMessage consoleMessage)
|
||||||
{
|
{
|
||||||
if(consoleMessage.message() != null)
|
if (consoleMessage.message() != null)
|
||||||
LOG.d(TAG, consoleMessage.message());
|
LOG.d(TAG, consoleMessage.message());
|
||||||
return super.onConsoleMessage(consoleMessage);
|
return super.onConsoleMessage(consoleMessage);
|
||||||
}
|
}
|
||||||
@ -312,6 +329,4 @@ public class CordovaChromeClient extends WebChromeClient {
|
|||||||
super.onGeolocationPermissionsShowPrompt(origin, callback);
|
super.onGeolocationPermissionsShowPrompt(origin, callback);
|
||||||
callback.invoke(origin, true, false);
|
callback.invoke(origin, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
663
framework/src/org/apache/cordova/CordovaWebView.java
Executable file
663
framework/src/org/apache/cordova/CordovaWebView.java
Executable file
@ -0,0 +1,663 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Stack;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
|
import org.apache.cordova.api.LOG;
|
||||||
|
import org.apache.cordova.api.PluginManager;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.XmlResourceParser;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.webkit.WebSettings;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
import android.webkit.WebSettings.LayoutAlgorithm;
|
||||||
|
|
||||||
|
public class CordovaWebView extends WebView {
|
||||||
|
|
||||||
|
public static final String TAG = "CordovaWebView";
|
||||||
|
|
||||||
|
/** The whitelist **/
|
||||||
|
private ArrayList<Pattern> whiteList = new ArrayList<Pattern>();
|
||||||
|
private HashMap<String, Boolean> whiteListCache = new HashMap<String, Boolean>();
|
||||||
|
public PluginManager pluginManager;
|
||||||
|
public CallbackServer callbackServer;
|
||||||
|
|
||||||
|
/** Actvities and other important classes **/
|
||||||
|
private CordovaInterface mCtx;
|
||||||
|
CordovaWebViewClient viewClient;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private CordovaChromeClient chromeClient;
|
||||||
|
|
||||||
|
//This is for the polyfil history
|
||||||
|
private String url;
|
||||||
|
String baseUrl;
|
||||||
|
private Stack<String> urls = new Stack<String>();
|
||||||
|
|
||||||
|
boolean useBrowserHistory = false;
|
||||||
|
|
||||||
|
// Flag to track that a loadUrl timeout occurred
|
||||||
|
int loadUrlTimeout = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
*/
|
||||||
|
public CordovaWebView(Context context) {
|
||||||
|
super(context);
|
||||||
|
if (CordovaInterface.class.isInstance(context))
|
||||||
|
{
|
||||||
|
this.mCtx = (CordovaInterface) context;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.d(TAG, "Your activity must implement CordovaInterface to work");
|
||||||
|
}
|
||||||
|
this.loadConfiguration();
|
||||||
|
this.setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param attrs
|
||||||
|
*/
|
||||||
|
public CordovaWebView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
if (CordovaInterface.class.isInstance(context))
|
||||||
|
{
|
||||||
|
this.mCtx = (CordovaInterface) context;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.d(TAG, "Your activity must implement CordovaInterface to work");
|
||||||
|
}
|
||||||
|
this.setWebChromeClient(new CordovaChromeClient(this.mCtx, this));
|
||||||
|
this.setWebViewClient(new CordovaWebViewClient(this.mCtx, this));
|
||||||
|
this.loadConfiguration();
|
||||||
|
this.setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param attrs
|
||||||
|
* @param defStyle
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public CordovaWebView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
if (CordovaInterface.class.isInstance(context))
|
||||||
|
{
|
||||||
|
this.mCtx = (CordovaInterface) context;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.d(TAG, "Your activity must implement CordovaInterface to work");
|
||||||
|
}
|
||||||
|
this.setWebChromeClient(new CordovaChromeClient(this.mCtx, this));
|
||||||
|
this.setWebViewClient(new CordovaWebViewClient(this.mCtx, this));
|
||||||
|
this.loadConfiguration();
|
||||||
|
this.setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param attrs
|
||||||
|
* @param defStyle
|
||||||
|
* @param privateBrowsing
|
||||||
|
*/
|
||||||
|
public CordovaWebView(Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing) {
|
||||||
|
super(context, attrs, defStyle, privateBrowsing);
|
||||||
|
if (CordovaInterface.class.isInstance(context))
|
||||||
|
{
|
||||||
|
this.mCtx = (CordovaInterface) context;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.d(TAG, "Your activity must implement CordovaInterface to work");
|
||||||
|
}
|
||||||
|
this.setWebChromeClient(new CordovaChromeClient(this.mCtx));
|
||||||
|
this.setWebViewClient(new CordovaWebViewClient(this.mCtx));
|
||||||
|
this.loadConfiguration();
|
||||||
|
this.setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize webview.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private void setup() {
|
||||||
|
|
||||||
|
this.setInitialScale(0);
|
||||||
|
this.setVerticalScrollBarEnabled(false);
|
||||||
|
this.requestFocusFromTouch();
|
||||||
|
|
||||||
|
// Enable JavaScript
|
||||||
|
WebSettings settings = this.getSettings();
|
||||||
|
settings.setJavaScriptEnabled(true);
|
||||||
|
settings.setJavaScriptCanOpenWindowsAutomatically(true);
|
||||||
|
settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
|
||||||
|
|
||||||
|
//Set the nav dump for HTC
|
||||||
|
settings.setNavDump(true);
|
||||||
|
|
||||||
|
// Enable database
|
||||||
|
settings.setDatabaseEnabled(true);
|
||||||
|
String databasePath = this.mCtx.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
|
||||||
|
settings.setDatabasePath(databasePath);
|
||||||
|
|
||||||
|
// Enable DOM storage
|
||||||
|
settings.setDomStorageEnabled(true);
|
||||||
|
|
||||||
|
// Enable built-in geolocation
|
||||||
|
settings.setGeolocationEnabled(true);
|
||||||
|
|
||||||
|
//Start up the plugin manager
|
||||||
|
try {
|
||||||
|
this.pluginManager = new PluginManager(this, this.mCtx);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the WebViewClient.
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
*/
|
||||||
|
public void setWebViewClient(CordovaWebViewClient client) {
|
||||||
|
this.viewClient = client;
|
||||||
|
super.setWebViewClient(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the WebChromeClient.
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
*/
|
||||||
|
public void setWebChromeClient(CordovaChromeClient client) {
|
||||||
|
this.chromeClient = client;
|
||||||
|
super.setWebChromeClient(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add entry to approved list of URLs (whitelist)
|
||||||
|
*
|
||||||
|
* @param origin URL regular expression to allow
|
||||||
|
* @param subdomains T=include all subdomains under origin
|
||||||
|
*/
|
||||||
|
public void addWhiteListEntry(String origin, boolean subdomains) {
|
||||||
|
try {
|
||||||
|
// Unlimited access to network resources
|
||||||
|
if (origin.compareTo("*") == 0) {
|
||||||
|
LOG.d(TAG, "Unlimited access to network resources");
|
||||||
|
this.whiteList.add(Pattern.compile(".*"));
|
||||||
|
} else { // specific access
|
||||||
|
// check if subdomains should be included
|
||||||
|
// TODO: we should not add more domains if * has already been added
|
||||||
|
if (subdomains) {
|
||||||
|
// XXX making it stupid friendly for people who forget to include protocol/SSL
|
||||||
|
if (origin.startsWith("http")) {
|
||||||
|
this.whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://(.*\\.)?")));
|
||||||
|
} else {
|
||||||
|
this.whiteList.add(Pattern.compile("^https?://(.*\\.)?" + origin));
|
||||||
|
}
|
||||||
|
LOG.d(TAG, "Origin to allow with subdomains: %s", origin);
|
||||||
|
} else {
|
||||||
|
// XXX making it stupid friendly for people who forget to include protocol/SSL
|
||||||
|
if (origin.startsWith("http")) {
|
||||||
|
this.whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://")));
|
||||||
|
} else {
|
||||||
|
this.whiteList.add(Pattern.compile("^https?://" + origin));
|
||||||
|
}
|
||||||
|
LOG.d(TAG, "Origin to allow: %s", origin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.d(TAG, "Failed to add origin %s", origin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if URL is in approved list of URLs to load.
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isUrlWhiteListed(String url) {
|
||||||
|
|
||||||
|
// Check to see if we have matched url previously
|
||||||
|
if (this.whiteListCache.get(url) != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for match in white list
|
||||||
|
Iterator<Pattern> pit = this.whiteList.iterator();
|
||||||
|
while (pit.hasNext()) {
|
||||||
|
Pattern p = pit.next();
|
||||||
|
Matcher m = p.matcher(url);
|
||||||
|
|
||||||
|
// If match found, then cache it to speed up subsequent comparisons
|
||||||
|
if (m.find()) {
|
||||||
|
this.whiteListCache.put(url, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the url into the webview.
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void loadUrl(String url) {
|
||||||
|
if (url.equals("about:blank") || url.startsWith("javascript:")) {
|
||||||
|
this.loadUrlNow(url);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
String initUrl = this.getProperty("url", null);
|
||||||
|
|
||||||
|
// If first page of app, then set URL to load to be the one passed in
|
||||||
|
if (initUrl == null || (this.urls.size() > 0)) {
|
||||||
|
this.loadUrlIntoView(url);
|
||||||
|
}
|
||||||
|
// Otherwise use the URL specified in the activity's extras bundle
|
||||||
|
else {
|
||||||
|
this.loadUrlIntoView(initUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the url into the webview after waiting for period of time.
|
||||||
|
* This is used to display the splashscreen for certain amount of time.
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @param time The number of ms to wait before loading webview
|
||||||
|
*/
|
||||||
|
public void loadUrl(final String url, int time) {
|
||||||
|
String initUrl = this.getProperty("url", null);
|
||||||
|
|
||||||
|
// If first page of app, then set URL to load to be the one passed in
|
||||||
|
if (initUrl == null || (this.urls.size() > 0)) {
|
||||||
|
this.loadUrlIntoView(url, time);
|
||||||
|
}
|
||||||
|
// Otherwise use the URL specified in the activity's extras bundle
|
||||||
|
else {
|
||||||
|
this.loadUrlIntoView(initUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the url into the webview.
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
public void loadUrlIntoView(final String url) {
|
||||||
|
LOG.d(TAG, ">>> loadUrl(" + url + ")");
|
||||||
|
|
||||||
|
this.url = url;
|
||||||
|
if (this.baseUrl == null) {
|
||||||
|
int i = url.lastIndexOf('/');
|
||||||
|
if (i > 0) {
|
||||||
|
this.baseUrl = url.substring(0, i + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.baseUrl = this.url + "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pluginManager.init();
|
||||||
|
|
||||||
|
if (!this.useBrowserHistory) {
|
||||||
|
this.urls.push(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a timeout timer for loadUrl
|
||||||
|
final CordovaWebView me = this;
|
||||||
|
final int currentLoadUrlTimeout = me.loadUrlTimeout;
|
||||||
|
final int loadUrlTimeoutValue = Integer.parseInt(this.getProperty("loadUrlTimeoutValue", "20000"));
|
||||||
|
|
||||||
|
// Timeout error method
|
||||||
|
final Runnable loadError = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
me.stopLoading();
|
||||||
|
LOG.e(TAG, "CordovaWebView: TIMEOUT ERROR!");
|
||||||
|
if (viewClient != null) {
|
||||||
|
viewClient.onReceivedError(me, -6, "The connection to the server was unsuccessful.", url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Timeout timer method
|
||||||
|
final Runnable timeoutCheck = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
synchronized (this) {
|
||||||
|
wait(loadUrlTimeoutValue);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If timeout, then stop loading and handle error
|
||||||
|
if (me.loadUrlTimeout == currentLoadUrlTimeout) {
|
||||||
|
me.mCtx.getActivity().runOnUiThread(loadError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Load url
|
||||||
|
this.mCtx.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
Thread thread = new Thread(timeoutCheck);
|
||||||
|
thread.start();
|
||||||
|
me.loadUrlNow(url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load URL in webview.
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
private void loadUrlNow(String url) {
|
||||||
|
LOG.d(TAG, ">>> loadUrlNow()");
|
||||||
|
super.loadUrl(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the url into the webview after waiting for period of time.
|
||||||
|
* This is used to display the splashscreen for certain amount of time.
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @param time The number of ms to wait before loading webview
|
||||||
|
*/
|
||||||
|
public void loadUrlIntoView(final String url, final int time) {
|
||||||
|
|
||||||
|
// If not first page of app, then load immediately
|
||||||
|
// Add support for browser history if we use it.
|
||||||
|
if ((url.startsWith("javascript:")) || this.urls.size() > 0 || this.canGoBack()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// If first page, then show splashscreen
|
||||||
|
else {
|
||||||
|
|
||||||
|
LOG.d(TAG, "DroidGap.loadUrl(%s, %d)", url, time);
|
||||||
|
|
||||||
|
// Send message to show splashscreen now if desired
|
||||||
|
this.postMessage("splashscreen", "show");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load url
|
||||||
|
this.loadUrlIntoView(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send JavaScript statement back to JavaScript.
|
||||||
|
* (This is a convenience method)
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
public void sendJavascript(String statement) {
|
||||||
|
if (this.callbackServer != null) {
|
||||||
|
this.callbackServer.sendJavascript(statement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message to all plugins.
|
||||||
|
*
|
||||||
|
* @param id The message id
|
||||||
|
* @param data The message data
|
||||||
|
*/
|
||||||
|
public void postMessage(String id, Object data) {
|
||||||
|
if (this.pluginManager != null) {
|
||||||
|
this.pluginManager.postMessage(id, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the top url on the stack without removing it from
|
||||||
|
* the stack.
|
||||||
|
*/
|
||||||
|
public String peekAtUrlStack() {
|
||||||
|
if (this.urls.size() > 0) {
|
||||||
|
return this.urls.peek();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a url to the stack
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
public void pushUrl(String url) {
|
||||||
|
this.urls.push(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go to previous page in history. (We manage our own history)
|
||||||
|
*
|
||||||
|
* @return true if we went back, false if we are already at top
|
||||||
|
*/
|
||||||
|
public boolean backHistory() {
|
||||||
|
|
||||||
|
// Check webview first to see if there is a history
|
||||||
|
// This is needed to support curPage#diffLink, since they are added to appView's history, but not our history url array (JQMobile behavior)
|
||||||
|
if (super.canGoBack()) {
|
||||||
|
super.goBack();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If our managed history has prev url
|
||||||
|
if (this.urls.size() > 1) {
|
||||||
|
this.urls.pop(); // Pop current url
|
||||||
|
String url = this.urls.pop(); // Pop prev url that we want to load, since it will be added back by loadUrl()
|
||||||
|
this.loadUrl(url);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if there is a history item.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean canGoBack() {
|
||||||
|
if (super.canGoBack()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (this.urls.size() > 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the specified URL in the Cordova webview or a new browser instance.
|
||||||
|
*
|
||||||
|
* NOTE: If openExternal is false, only URLs listed in whitelist can be loaded.
|
||||||
|
*
|
||||||
|
* @param url The url to load.
|
||||||
|
* @param openExternal Load url in browser instead of Cordova webview.
|
||||||
|
* @param clearHistory Clear the history stack, so new page becomes top of history
|
||||||
|
* @param params DroidGap parameters for new app
|
||||||
|
*/
|
||||||
|
public void showWebPage(String url, boolean openExternal, boolean clearHistory, HashMap<String, Object> params) {
|
||||||
|
LOG.d(TAG, "showWebPage(%s, %b, %b, HashMap", url, openExternal, clearHistory);
|
||||||
|
|
||||||
|
// If clearing history
|
||||||
|
if (clearHistory) {
|
||||||
|
this.clearHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If loading into our webview
|
||||||
|
if (!openExternal) {
|
||||||
|
|
||||||
|
// Make sure url is in whitelist
|
||||||
|
if (url.startsWith("file://") || url.indexOf(this.baseUrl) == 0 || isUrlWhiteListed(url)) {
|
||||||
|
// TODO: What about params?
|
||||||
|
|
||||||
|
// Clear out current url from history, since it will be replacing it
|
||||||
|
if (clearHistory) {
|
||||||
|
this.urls.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load new URL
|
||||||
|
this.loadUrl(url);
|
||||||
|
}
|
||||||
|
// Load in default viewer if not
|
||||||
|
else {
|
||||||
|
LOG.w(TAG, "showWebPage: Cannot load URL into webview since it is not in white list. Loading into browser instead. (URL=" + url + ")");
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.setData(Uri.parse(url));
|
||||||
|
mCtx.getActivity().startActivity(intent);
|
||||||
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
|
LOG.e(TAG, "Error loading url " + url, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load in default view intent
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.setData(Uri.parse(url));
|
||||||
|
mCtx.getActivity().startActivity(intent);
|
||||||
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
|
LOG.e(TAG, "Error loading url " + url, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Cordova configuration from res/xml/cordova.xml.
|
||||||
|
* Approved list of URLs that can be loaded into DroidGap
|
||||||
|
* <access origin="http://server regexp" subdomains="true" />
|
||||||
|
* Log level: ERROR, WARN, INFO, DEBUG, VERBOSE (default=ERROR)
|
||||||
|
* <log level="DEBUG" />
|
||||||
|
*/
|
||||||
|
private void loadConfiguration() {
|
||||||
|
int id = getResources().getIdentifier("cordova", "xml", this.mCtx.getActivity().getPackageName());
|
||||||
|
if (id == 0) {
|
||||||
|
LOG.i("CordovaLog", "cordova.xml missing. Ignoring...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
XmlResourceParser xml = getResources().getXml(id);
|
||||||
|
int eventType = -1;
|
||||||
|
while (eventType != XmlResourceParser.END_DOCUMENT) {
|
||||||
|
if (eventType == XmlResourceParser.START_TAG) {
|
||||||
|
String strNode = xml.getName();
|
||||||
|
if (strNode.equals("access")) {
|
||||||
|
String origin = xml.getAttributeValue(null, "origin");
|
||||||
|
String subdomains = xml.getAttributeValue(null, "subdomains");
|
||||||
|
if (origin != null) {
|
||||||
|
this.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strNode.equals("log")) {
|
||||||
|
String level = xml.getAttributeValue(null, "level");
|
||||||
|
LOG.i("CordovaLog", "Found log level %s", level);
|
||||||
|
if (level != null) {
|
||||||
|
LOG.setLogLevel(level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strNode.equals("preference")) {
|
||||||
|
String name = xml.getAttributeValue(null, "name");
|
||||||
|
String value = xml.getAttributeValue(null, "value");
|
||||||
|
|
||||||
|
LOG.i("CordovaLog", "Found preference for %s=%s", name, value);
|
||||||
|
|
||||||
|
// Save preferences in Intent
|
||||||
|
this.mCtx.getActivity().getIntent().putExtra(name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
eventType = xml.next();
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init preferences
|
||||||
|
if ("true".equals(this.getProperty("useBrowserHistory", "true"))) {
|
||||||
|
this.useBrowserHistory = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.useBrowserHistory = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("true".equals(this.getProperty("fullscreen", "false"))) {
|
||||||
|
this.mCtx.getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||||
|
this.mCtx.getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get string property for activity.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @param defaultValue
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getProperty(String name, String defaultValue) {
|
||||||
|
Bundle bundle = this.mCtx.getActivity().getIntent().getExtras();
|
||||||
|
if (bundle == null) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
Object p = bundle.get(name);
|
||||||
|
if (p == null) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
return p.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import java.util.Hashtable;
|
||||||
|
|
||||||
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
import org.apache.cordova.api.LOG;
|
import org.apache.cordova.api.LOG;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
@ -39,18 +44,42 @@ import android.webkit.WebViewClient;
|
|||||||
public class CordovaWebViewClient extends WebViewClient {
|
public class CordovaWebViewClient extends WebViewClient {
|
||||||
|
|
||||||
private static final String TAG = "Cordova";
|
private static final String TAG = "Cordova";
|
||||||
DroidGap ctx;
|
CordovaInterface ctx;
|
||||||
|
CordovaWebView appView;
|
||||||
private boolean doClearHistory = false;
|
private boolean doClearHistory = false;
|
||||||
|
|
||||||
|
/** The authorization tokens. */
|
||||||
|
private Hashtable<String, AuthenticationToken> authenticationTokens = new Hashtable<String, AuthenticationToken>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param ctx
|
||||||
*/
|
*/
|
||||||
public CordovaWebViewClient(DroidGap ctx) {
|
public CordovaWebViewClient(CordovaInterface ctx) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param ctx
|
||||||
|
* @param view
|
||||||
|
*/
|
||||||
|
public CordovaWebViewClient(CordovaInterface ctx, CordovaWebView view) {
|
||||||
|
this.ctx = ctx;
|
||||||
|
this.appView = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param view
|
||||||
|
*/
|
||||||
|
public void setWebView(CordovaWebView view) {
|
||||||
|
this.appView = view;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Give the host application a chance to take over the control when a new url
|
* Give the host application a chance to take over the control when a new url
|
||||||
* is about to be loaded in the current WebView.
|
* is about to be loaded in the current WebView.
|
||||||
@ -63,7 +92,7 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||||
|
|
||||||
// First give any plugins the chance to handle the url themselves
|
// First give any plugins the chance to handle the url themselves
|
||||||
if ((this.ctx.pluginManager != null) && this.ctx.pluginManager.onOverrideUrlLoading(url)) {
|
if ((this.appView.pluginManager != null) && this.appView.pluginManager.onOverrideUrlLoading(url)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If dialing phone (tel:5551212)
|
// If dialing phone (tel:5551212)
|
||||||
@ -71,9 +100,9 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
try {
|
try {
|
||||||
Intent intent = new Intent(Intent.ACTION_DIAL);
|
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||||
intent.setData(Uri.parse(url));
|
intent.setData(Uri.parse(url));
|
||||||
ctx.startActivity(intent);
|
this.ctx.getActivity().startActivity(intent);
|
||||||
} catch (android.content.ActivityNotFoundException e) {
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
LOG.e(TAG, "Error dialing "+url+": "+ e.toString());
|
LOG.e(TAG, "Error dialing " + url + ": " + e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,9 +111,9 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
try {
|
try {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
intent.setData(Uri.parse(url));
|
intent.setData(Uri.parse(url));
|
||||||
ctx.startActivity(intent);
|
this.ctx.getActivity().startActivity(intent);
|
||||||
} catch (android.content.ActivityNotFoundException e) {
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
LOG.e(TAG, "Error showing map "+url+": "+ e.toString());
|
LOG.e(TAG, "Error showing map " + url + ": " + e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,9 +122,9 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
try {
|
try {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
intent.setData(Uri.parse(url));
|
intent.setData(Uri.parse(url));
|
||||||
ctx.startActivity(intent);
|
this.ctx.getActivity().startActivity(intent);
|
||||||
} catch (android.content.ActivityNotFoundException e) {
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
LOG.e(TAG, "Error sending email "+url+": "+ e.toString());
|
LOG.e(TAG, "Error sending email " + url + ": " + e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,12 +151,12 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
intent.setData(Uri.parse("sms:"+address));
|
intent.setData(Uri.parse("sms:" + address));
|
||||||
intent.putExtra("address", address);
|
intent.putExtra("address", address);
|
||||||
intent.setType("vnd.android-dir/mms-sms");
|
intent.setType("vnd.android-dir/mms-sms");
|
||||||
ctx.startActivity(intent);
|
this.ctx.getActivity().startActivity(intent);
|
||||||
} catch (android.content.ActivityNotFoundException e) {
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
LOG.e(TAG, "Error sending sms "+url+":"+ e.toString());
|
LOG.e(TAG, "Error sending sms " + url + ":" + e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,8 +165,12 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
|
|
||||||
// If our app or file:, then load into a new Cordova webview container by starting a new instance of our activity.
|
// If our app or file:, then load into a new Cordova webview container by starting a new instance of our activity.
|
||||||
// Our app continues to run. When BACK is pressed, our app is redisplayed.
|
// Our app continues to run. When BACK is pressed, our app is redisplayed.
|
||||||
if (url.startsWith("file://") || url.indexOf(this.ctx.baseUrl) == 0 || ctx.isUrlWhiteListed(url)) {
|
if (url.startsWith("file://") || url.indexOf(this.appView.baseUrl) == 0 || this.appView.isUrlWhiteListed(url)) {
|
||||||
this.ctx.loadUrl(url);
|
//This will fix iFrames
|
||||||
|
if (appView.useBrowserHistory)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
this.appView.loadUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not our application, let default viewer handle
|
// If not our application, let default viewer handle
|
||||||
@ -145,9 +178,9 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
try {
|
try {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
intent.setData(Uri.parse(url));
|
intent.setData(Uri.parse(url));
|
||||||
ctx.startActivity(intent);
|
this.ctx.getActivity().startActivity(intent);
|
||||||
} catch (android.content.ActivityNotFoundException e) {
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
LOG.e(TAG, "Error loading url "+url, e);
|
LOG.e(TAG, "Error loading url " + url, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,44 +192,62 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
* The method reacts on all registered authentication tokens. There is one and only one authentication token for any host + realm combination
|
* The method reacts on all registered authentication tokens. There is one and only one authentication token for any host + realm combination
|
||||||
*
|
*
|
||||||
* @param view
|
* @param view
|
||||||
* the view
|
|
||||||
* @param handler
|
* @param handler
|
||||||
* the handler
|
|
||||||
* @param host
|
* @param host
|
||||||
* the host
|
|
||||||
* @param realm
|
* @param realm
|
||||||
* the realm
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,
|
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
|
||||||
String realm) {
|
|
||||||
|
|
||||||
// get the authentication token
|
// Get the authentication token
|
||||||
AuthenticationToken token = ctx.getAuthenticationToken(host,realm);
|
AuthenticationToken token = this.getAuthenticationToken(host, realm);
|
||||||
|
if (token != null) {
|
||||||
if(token != null) {
|
|
||||||
handler.proceed(token.getUserName(), token.getPassword());
|
handler.proceed(token.getUserName(), token.getPassword());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the host application that a page has started loading.
|
||||||
|
* This method is called once for each main frame load so a page with iframes or framesets will call onPageStarted
|
||||||
|
* one time for the main frame. This also means that onPageStarted will not be called when the contents of an
|
||||||
|
* embedded frame changes, i.e. clicking a link whose target is an iframe.
|
||||||
|
*
|
||||||
|
* @param view The webview initiating the callback.
|
||||||
|
* @param url The url of the page.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
||||||
// Clear history so history.back() doesn't do anything.
|
// Clear history so history.back() doesn't do anything.
|
||||||
// So we can reinit() native side CallbackServer & PluginManager.
|
// So we can reinit() native side CallbackServer & PluginManager.
|
||||||
view.clearHistory();
|
if (!this.appView.useBrowserHistory) {
|
||||||
this.doClearHistory = true;
|
view.clearHistory();
|
||||||
|
this.doClearHistory = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create callback server and plugin manager
|
||||||
|
if (this.appView.callbackServer == null) {
|
||||||
|
this.appView.callbackServer = new CallbackServer();
|
||||||
|
this.appView.callbackServer.init(url);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.appView.callbackServer.reinit(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Broadcast message that page has loaded
|
||||||
|
this.appView.postMessage("onPageStarted", url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the host application that a page has finished loading.
|
* Notify the host application that a page has finished loading.
|
||||||
*
|
* This method is called only for main frame. When onPageFinished() is called, the rendering picture may not be updated yet.
|
||||||
|
*
|
||||||
* @param view The webview initiating the callback.
|
* @param view The webview initiating the callback.
|
||||||
* @param url The url of the page.
|
* @param url The url of the page.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onPageFinished(WebView view, String url) {
|
public void onPageFinished(WebView view, String url) {
|
||||||
super.onPageFinished(view, url);
|
super.onPageFinished(view, url);
|
||||||
|
LOG.d(TAG, "onPageFinished(" + url + ")");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Because of a timing issue we need to clear this history in onPageFinished as well as
|
* Because of a timing issue we need to clear this history in onPageFinished as well as
|
||||||
@ -210,29 +261,28 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear timeout flag
|
// Clear timeout flag
|
||||||
this.ctx.loadUrlTimeout++;
|
this.appView.loadUrlTimeout++;
|
||||||
|
|
||||||
// Try firing the onNativeReady event in JS. If it fails because the JS is
|
// 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
|
// 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.
|
// from the JS side when the JS gets to that code.
|
||||||
if (!url.equals("about:blank")) {
|
if (!url.equals("about:blank")) {
|
||||||
ctx.appView.loadUrl("javascript:try{ cordova.require('cordova/channel').onNativeReady.fire();}catch(e){_nativeReady = true;}");
|
this.appView.loadUrl("javascript:try{ cordova.require('cordova/channel').onNativeReady.fire();}catch(e){_nativeReady = true;}");
|
||||||
this.ctx.postMessage("onNativeReady", null);
|
this.appView.postMessage("onNativeReady", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Broadcast message that page has loaded
|
||||||
|
this.appView.postMessage("onPageFinished", url);
|
||||||
|
|
||||||
// Make app visible after 2 sec in case there was a JS error and Cordova JS never initialized correctly
|
// Make app visible after 2 sec in case there was a JS error and Cordova JS never initialized correctly
|
||||||
if (ctx.appView.getVisibility() == View.INVISIBLE) {
|
if (this.appView.getVisibility() == View.INVISIBLE) {
|
||||||
Thread t = new Thread(new Runnable() {
|
Thread t = new Thread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(2000);
|
Thread.sleep(2000);
|
||||||
ctx.runOnUiThread(new Runnable() {
|
ctx.getActivity().runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (ctx.splashscreen != 0) {
|
appView.postMessage("spinner", "stop");
|
||||||
ctx.root.setBackgroundResource(0);
|
|
||||||
}
|
|
||||||
ctx.appView.setVisibility(View.VISIBLE);
|
|
||||||
ctx.spinnerStop();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@ -242,13 +292,12 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
t.start();
|
t.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Shutdown if blank loaded
|
// Shutdown if blank loaded
|
||||||
if (url.equals("about:blank")) {
|
if (url.equals("about:blank")) {
|
||||||
if (this.ctx.callbackServer != null) {
|
if (this.appView.callbackServer != null) {
|
||||||
this.ctx.callbackServer.destroy();
|
this.appView.callbackServer.destroy();
|
||||||
}
|
}
|
||||||
this.ctx.endActivity();
|
appView.postMessage("exit", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,22 +312,38 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
|
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
|
||||||
LOG.d(TAG, "DroidGap: GapViewClient.onReceivedError: Error code=%s Description=%s URL=%s", errorCode, description, failingUrl);
|
LOG.d(TAG, "CordovaWebViewClient.onReceivedError: Error code=%s Description=%s URL=%s", errorCode, description, failingUrl);
|
||||||
|
|
||||||
// Clear timeout flag
|
// Clear timeout flag
|
||||||
this.ctx.loadUrlTimeout++;
|
this.appView.loadUrlTimeout++;
|
||||||
|
|
||||||
// Stop "app loading" spinner if showing
|
|
||||||
this.ctx.spinnerStop();
|
|
||||||
|
|
||||||
// Handle error
|
// Handle error
|
||||||
this.ctx.onReceivedError(errorCode, description, failingUrl);
|
JSONObject data = new JSONObject();
|
||||||
|
try {
|
||||||
|
data.put("errorCode", errorCode);
|
||||||
|
data.put("description", description);
|
||||||
|
data.put("url", failingUrl);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
this.appView.postMessage("onReceivedError", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the host application that an SSL error occurred while loading a resource.
|
||||||
|
* The host application must call either handler.cancel() or handler.proceed().
|
||||||
|
* Note that the decision may be retained for use in response to future SSL errors.
|
||||||
|
* The default behavior is to cancel the load.
|
||||||
|
*
|
||||||
|
* @param view The WebView that is initiating the callback.
|
||||||
|
* @param handler An SslErrorHandler object that will handle the user's response.
|
||||||
|
* @param error The SSL error object.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
|
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
|
||||||
|
|
||||||
final String packageName = this.ctx.getPackageName();
|
final String packageName = this.ctx.getActivity().getPackageName();
|
||||||
final PackageManager pm = this.ctx.getPackageManager();
|
final PackageManager pm = this.ctx.getActivity().getPackageManager();
|
||||||
ApplicationInfo appInfo;
|
ApplicationInfo appInfo;
|
||||||
try {
|
try {
|
||||||
appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
|
appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
|
||||||
@ -296,14 +361,94 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the host application to update its visited links database.
|
||||||
|
*
|
||||||
|
* @param view The WebView that is initiating the callback.
|
||||||
|
* @param url The url being visited.
|
||||||
|
* @param isReload True if this url is being reloaded.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
|
public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
|
||||||
/*
|
/*
|
||||||
* If you do a document.location.href the url does not get pushed on the stack
|
* If you do a document.location.href the url does not get pushed on the stack
|
||||||
* so we do a check here to see if the url should be pushed.
|
* so we do a check here to see if the url should be pushed.
|
||||||
*/
|
*/
|
||||||
if (!this.ctx.peekAtUrlStack().equals(url)) {
|
if (!this.appView.peekAtUrlStack().equals(url)) {
|
||||||
this.ctx.pushUrl(url);
|
this.appView.pushUrl(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the authentication token.
|
||||||
|
*
|
||||||
|
* @param authenticationToken
|
||||||
|
* @param host
|
||||||
|
* @param realm
|
||||||
|
*/
|
||||||
|
public void setAuthenticationToken(AuthenticationToken authenticationToken, String host, String realm) {
|
||||||
|
if (host == null) {
|
||||||
|
host = "";
|
||||||
|
}
|
||||||
|
if (realm == null) {
|
||||||
|
realm = "";
|
||||||
|
}
|
||||||
|
this.authenticationTokens.put(host.concat(realm), authenticationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the authentication token.
|
||||||
|
*
|
||||||
|
* @param host
|
||||||
|
* @param realm
|
||||||
|
*
|
||||||
|
* @return the authentication token or null if did not exist
|
||||||
|
*/
|
||||||
|
public AuthenticationToken removeAuthenticationToken(String host, String realm) {
|
||||||
|
return this.authenticationTokens.remove(host.concat(realm));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the authentication token.
|
||||||
|
*
|
||||||
|
* In order it tries:
|
||||||
|
* 1- host + realm
|
||||||
|
* 2- host
|
||||||
|
* 3- realm
|
||||||
|
* 4- no host, no realm
|
||||||
|
*
|
||||||
|
* @param host
|
||||||
|
* @param realm
|
||||||
|
*
|
||||||
|
* @return the authentication token
|
||||||
|
*/
|
||||||
|
public AuthenticationToken getAuthenticationToken(String host, String realm) {
|
||||||
|
AuthenticationToken token = null;
|
||||||
|
token = this.authenticationTokens.get(host.concat(realm));
|
||||||
|
|
||||||
|
if (token == null) {
|
||||||
|
// try with just the host
|
||||||
|
token = this.authenticationTokens.get(host);
|
||||||
|
|
||||||
|
// Try the realm
|
||||||
|
if (token == null) {
|
||||||
|
token = this.authenticationTokens.get(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no host found, just query for default
|
||||||
|
if (token == null) {
|
||||||
|
token = this.authenticationTokens.get("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all authentication tokens.
|
||||||
|
*/
|
||||||
|
public void clearAuthenticationTokens() {
|
||||||
|
this.authenticationTokens.clear();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ public class Device extends Plugin {
|
|||||||
* Unregister receiver.
|
* Unregister receiver.
|
||||||
*/
|
*/
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
this.ctx.unregisterReceiver(this.telephonyReceiver);
|
this.ctx.getActivity().unregisterReceiver(this.telephonyReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
@ -123,9 +123,9 @@ public class Device extends Plugin {
|
|||||||
* DroidGap.onMessage("telephone", "ringing" | "offhook" | "idle")
|
* DroidGap.onMessage("telephone", "ringing" | "offhook" | "idle")
|
||||||
*/
|
*/
|
||||||
private void initTelephonyReceiver() {
|
private void initTelephonyReceiver() {
|
||||||
IntentFilter intentFilter = new IntentFilter() ;
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
|
intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
|
||||||
final CordovaInterface myctx = this.ctx;
|
//final CordovaInterface myctx = this.ctx;
|
||||||
this.telephonyReceiver = new BroadcastReceiver() {
|
this.telephonyReceiver = new BroadcastReceiver() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -137,15 +137,15 @@ public class Device extends Plugin {
|
|||||||
String extraData = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
|
String extraData = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
|
||||||
if (extraData.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
|
if (extraData.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
|
||||||
LOG.i(TAG, "Telephone RINGING");
|
LOG.i(TAG, "Telephone RINGING");
|
||||||
myctx.postMessage("telephone", "ringing");
|
webView.postMessage("telephone", "ringing");
|
||||||
}
|
}
|
||||||
else if (extraData.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
|
else if (extraData.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
|
||||||
LOG.i(TAG, "Telephone OFFHOOK");
|
LOG.i(TAG, "Telephone OFFHOOK");
|
||||||
myctx.postMessage("telephone", "offhook");
|
webView.postMessage("telephone", "offhook");
|
||||||
}
|
}
|
||||||
else if (extraData.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
|
else if (extraData.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
|
||||||
LOG.i(TAG, "Telephone IDLE");
|
LOG.i(TAG, "Telephone IDLE");
|
||||||
myctx.postMessage("telephone", "idle");
|
webView.postMessage("telephone", "idle");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,7 +153,7 @@ public class Device extends Plugin {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Register the receiver
|
// Register the receiver
|
||||||
this.ctx.registerReceiver(this.telephonyReceiver, intentFilter);
|
this.ctx.getActivity().registerReceiver(this.telephonyReceiver, intentFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -171,7 +171,7 @@ public class Device extends Plugin {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String getUuid() {
|
public String getUuid() {
|
||||||
String uuid = Settings.Secure.getString(this.ctx.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
|
String uuid = Settings.Secure.getString(this.ctx.getActivity().getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,15 +205,14 @@ public class Device extends Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getSDKVersion() {
|
public String getSDKVersion() {
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
String sdkversion = android.os.Build.VERSION.SDK;
|
String sdkversion = android.os.Build.VERSION.SDK;
|
||||||
return sdkversion;
|
return sdkversion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getTimeZoneID() {
|
public String getTimeZoneID() {
|
||||||
TimeZone tz = TimeZone.getDefault();
|
TimeZone tz = TimeZone.getDefault();
|
||||||
return(tz.getID());
|
return (tz.getID());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,11 +32,11 @@ import android.os.StatFs;
|
|||||||
*/
|
*/
|
||||||
public class DirectoryManager {
|
public class DirectoryManager {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private static final String LOG_TAG = "DirectoryManager";
|
private static final String LOG_TAG = "DirectoryManager";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if a file or directory exists.
|
* Determine if a file or directory exists.
|
||||||
*
|
|
||||||
* @param name The name of the file to check.
|
* @param name The name of the file to check.
|
||||||
* @return T=exists, F=not found
|
* @return T=exists, F=not found
|
||||||
*/
|
*/
|
||||||
@ -50,7 +50,7 @@ public class DirectoryManager {
|
|||||||
status = newPath.exists();
|
status = newPath.exists();
|
||||||
}
|
}
|
||||||
// If no SD card
|
// If no SD card
|
||||||
else{
|
else {
|
||||||
status = false;
|
status = false;
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
@ -58,7 +58,7 @@ public class DirectoryManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the free disk space
|
* Get the free disk space
|
||||||
*
|
*
|
||||||
* @return Size in KB or -1 if not available
|
* @return Size in KB or -1 if not available
|
||||||
*/
|
*/
|
||||||
protected static long getFreeDiskSpace(boolean checkInternal) {
|
protected static long getFreeDiskSpace(boolean checkInternal) {
|
||||||
@ -82,7 +82,7 @@ public class DirectoryManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a path return the number of free KB
|
* Given a path return the number of free KB
|
||||||
*
|
*
|
||||||
* @param path to the file system
|
* @param path to the file system
|
||||||
* @return free space in KB
|
* @return free space in KB
|
||||||
*/
|
*/
|
||||||
@ -90,12 +90,12 @@ public class DirectoryManager {
|
|||||||
StatFs stat = new StatFs(path);
|
StatFs stat = new StatFs(path);
|
||||||
long blockSize = stat.getBlockSize();
|
long blockSize = stat.getBlockSize();
|
||||||
long availableBlocks = stat.getAvailableBlocks();
|
long availableBlocks = stat.getAvailableBlocks();
|
||||||
return availableBlocks*blockSize/1024;
|
return availableBlocks * blockSize / 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if SD card exists.
|
* Determine if SD card exists.
|
||||||
*
|
*
|
||||||
* @return T=exists, F=not found
|
* @return T=exists, F=not found
|
||||||
*/
|
*/
|
||||||
protected static boolean testSaveLocationExists() {
|
protected static boolean testSaveLocationExists() {
|
||||||
@ -127,7 +127,7 @@ public class DirectoryManager {
|
|||||||
newPath = new File(file2);
|
newPath = new File(file2);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
newPath = new File(file1+"/"+file2);
|
newPath = new File(file1 + "/" + file2);
|
||||||
}
|
}
|
||||||
return newPath;
|
return newPath;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -51,7 +51,6 @@ import android.net.Uri;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.webkit.CookieManager;
|
import android.webkit.CookieManager;
|
||||||
|
|
||||||
|
|
||||||
public class FileTransfer extends Plugin {
|
public class FileTransfer extends Plugin {
|
||||||
|
|
||||||
private static final String LOG_TAG = "FileTransfer";
|
private static final String LOG_TAG = "FileTransfer";
|
||||||
@ -76,8 +75,7 @@ public class FileTransfer extends Plugin {
|
|||||||
try {
|
try {
|
||||||
source = args.getString(0);
|
source = args.getString(0);
|
||||||
target = args.getString(1);
|
target = args.getString(1);
|
||||||
}
|
} catch (JSONException e) {
|
||||||
catch (JSONException e) {
|
|
||||||
Log.d(LOG_TAG, "Missing source or target");
|
Log.d(LOG_TAG, "Missing source or target");
|
||||||
return new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Missing source or target");
|
return new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Missing source or target");
|
||||||
}
|
}
|
||||||
@ -353,11 +351,11 @@ public class FileTransfer extends Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void checkClientTrusted(X509Certificate[] chain,
|
public void checkClientTrusted(X509Certificate[] chain,
|
||||||
String authType) throws CertificateException {
|
String authType) throws CertificateException {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkServerTrusted(X509Certificate[] chain,
|
public void checkServerTrusted(X509Certificate[] chain,
|
||||||
String authType) throws CertificateException {
|
String authType) throws CertificateException {
|
||||||
}
|
}
|
||||||
} };
|
} };
|
||||||
|
|
||||||
@ -419,7 +417,7 @@ public class FileTransfer extends Plugin {
|
|||||||
*/
|
*/
|
||||||
private String getArgument(JSONArray args, int position, String defaultString) {
|
private String getArgument(JSONArray args, int position, String defaultString) {
|
||||||
String arg = defaultString;
|
String arg = defaultString;
|
||||||
if(args.length() >= position) {
|
if (args.length() >= position) {
|
||||||
arg = args.optString(position);
|
arg = args.optString(position);
|
||||||
if (arg == null || "null".equals(arg)) {
|
if (arg == null || "null".equals(arg)) {
|
||||||
arg = defaultString;
|
arg = defaultString;
|
||||||
@ -428,7 +426,6 @@ public class FileTransfer extends Plugin {
|
|||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloads a file form a given URL and saves it to the specified directory.
|
* Downloads a file form a given URL and saves it to the specified directory.
|
||||||
*
|
*
|
||||||
@ -447,7 +444,7 @@ public class FileTransfer extends Plugin {
|
|||||||
file.getParentFile().mkdirs();
|
file.getParentFile().mkdirs();
|
||||||
|
|
||||||
// connect to server
|
// connect to server
|
||||||
if(this.ctx.isUrlWhiteListed(source))
|
if (webView.isUrlWhiteListed(source))
|
||||||
{
|
{
|
||||||
URL url = new URL(source);
|
URL url = new URL(source);
|
||||||
connection = (HttpURLConnection) url.openConnection();
|
connection = (HttpURLConnection) url.openConnection();
|
||||||
@ -464,20 +461,24 @@ public class FileTransfer extends Plugin {
|
|||||||
|
|
||||||
Log.d(LOG_TAG, "Download file: " + url);
|
Log.d(LOG_TAG, "Download file: " + url);
|
||||||
|
|
||||||
InputStream inputStream = connection.getInputStream();
|
connection.connect();
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int bytesRead = 0;
|
|
||||||
|
|
||||||
FileOutputStream outputStream = new FileOutputStream(file);
|
Log.d(LOG_TAG, "Download file:" + url);
|
||||||
|
|
||||||
// write bytes to file
|
InputStream inputStream = connection.getInputStream();
|
||||||
while ( (bytesRead = inputStream.read(buffer)) > 0 ) {
|
byte[] buffer = new byte[1024];
|
||||||
outputStream.write(buffer,0, bytesRead);
|
int bytesRead = 0;
|
||||||
}
|
|
||||||
|
|
||||||
outputStream.close();
|
FileOutputStream outputStream = new FileOutputStream(file);
|
||||||
|
|
||||||
Log.d(LOG_TAG, "Saved file: " + target);
|
// write bytes to file
|
||||||
|
while ((bytesRead = inputStream.read(buffer)) > 0) {
|
||||||
|
outputStream.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
outputStream.close();
|
||||||
|
|
||||||
|
Log.d(LOG_TAG, "Saved file: " + target);
|
||||||
|
|
||||||
// create FileEntry object
|
// create FileEntry object
|
||||||
FileUtils fileUtil = new FileUtils();
|
FileUtils fileUtil = new FileUtils();
|
||||||
@ -521,7 +522,7 @@ public class FileTransfer extends Plugin {
|
|||||||
private InputStream getPathFromUri(String path) throws FileNotFoundException {
|
private InputStream getPathFromUri(String path) throws FileNotFoundException {
|
||||||
if (path.startsWith("content:")) {
|
if (path.startsWith("content:")) {
|
||||||
Uri uri = Uri.parse(path);
|
Uri uri = Uri.parse(path);
|
||||||
return ctx.getContentResolver().openInputStream(uri);
|
return ctx.getActivity().getContentResolver().openInputStream(uri);
|
||||||
}
|
}
|
||||||
else if (path.startsWith("file://")) {
|
else if (path.startsWith("file://")) {
|
||||||
int question = path.indexOf("?");
|
int question = path.indexOf("?");
|
||||||
|
@ -37,18 +37,21 @@ import org.json.JSONArray;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
//import android.content.Context;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.webkit.MimeTypeMap;
|
import android.webkit.MimeTypeMap;
|
||||||
|
|
||||||
|
//import android.app.Activity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides SD card file and directory services to JavaScript.
|
* This class provides SD card file and directory services to JavaScript.
|
||||||
* Only files on the SD card can be accessed.
|
* Only files on the SD card can be accessed.
|
||||||
*/
|
*/
|
||||||
public class FileUtils extends Plugin {
|
public class FileUtils extends Plugin {
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private static final String LOG_TAG = "FileUtils";
|
private static final String LOG_TAG = "FileUtils";
|
||||||
private static final String _DATA = "_data"; // The column name where the file path is stored
|
private static final String _DATA = "_data"; // The column name where the file path is stored
|
||||||
|
|
||||||
@ -129,7 +132,7 @@ public class FileUtils extends Plugin {
|
|||||||
else if (action.equals("requestFileSystem")) {
|
else if (action.equals("requestFileSystem")) {
|
||||||
long size = args.optLong(1);
|
long size = args.optLong(1);
|
||||||
if (size != 0) {
|
if (size != 0) {
|
||||||
if (size > (DirectoryManager.getFreeDiskSpace(true)*1024)) {
|
if (size > (DirectoryManager.getFreeDiskSpace(true) * 1024)) {
|
||||||
return new PluginResult(PluginResult.Status.ERROR, FileUtils.QUOTA_EXCEEDED_ERR);
|
return new PluginResult(PluginResult.Status.ERROR, FileUtils.QUOTA_EXCEEDED_ERR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,9 +223,9 @@ public class FileUtils extends Plugin {
|
|||||||
*/
|
*/
|
||||||
private void notifyDelete(String filePath) {
|
private void notifyDelete(String filePath) {
|
||||||
String newFilePath = stripFileProtocol(filePath);
|
String newFilePath = stripFileProtocol(filePath);
|
||||||
int result = this.ctx.getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
int result = this.ctx.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
||||||
MediaStore.Images.Media.DATA + " = ?",
|
MediaStore.Images.Media.DATA + " = ?",
|
||||||
new String[] {newFilePath});
|
new String[] { filePath });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -235,6 +238,7 @@ public class FileUtils extends Plugin {
|
|||||||
* @throws IOException if the user can't read the file
|
* @throws IOException if the user can't read the file
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
private JSONObject resolveLocalFileSystemURI(String url) throws IOException, JSONException {
|
private JSONObject resolveLocalFileSystemURI(String url) throws IOException, JSONException {
|
||||||
String decoded = URLDecoder.decode(url, "UTF-8");
|
String decoded = URLDecoder.decode(url, "UTF-8");
|
||||||
|
|
||||||
@ -242,7 +246,7 @@ public class FileUtils extends Plugin {
|
|||||||
|
|
||||||
// Handle the special case where you get an Android content:// uri.
|
// Handle the special case where you get an Android content:// uri.
|
||||||
if (decoded.startsWith("content:")) {
|
if (decoded.startsWith("content:")) {
|
||||||
Cursor cursor = this.ctx.managedQuery(Uri.parse(decoded), new String[] { MediaStore.Images.Media.DATA }, null, null, null);
|
Cursor cursor = this.ctx.getActivity().managedQuery(Uri.parse(decoded), new String[] { MediaStore.Images.Media.DATA }, null, null, null);
|
||||||
// Note: MediaStore.Images/Audio/Video.Media.DATA is always "_data"
|
// Note: MediaStore.Images/Audio/Video.Media.DATA is always "_data"
|
||||||
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
||||||
cursor.moveToFirst();
|
cursor.moveToFirst();
|
||||||
@ -293,7 +297,7 @@ public class FileUtils extends Plugin {
|
|||||||
|
|
||||||
if (fp.isDirectory()) {
|
if (fp.isDirectory()) {
|
||||||
File[] files = fp.listFiles();
|
File[] files = fp.listFiles();
|
||||||
for (int i=0; i<files.length; i++) {
|
for (int i = 0; i < files.length; i++) {
|
||||||
entries.put(getEntry(files[i]));
|
entries.put(getEntry(files[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -319,7 +323,6 @@ public class FileUtils extends Plugin {
|
|||||||
fileName = stripFileProtocol(fileName);
|
fileName = stripFileProtocol(fileName);
|
||||||
newParent = stripFileProtocol(newParent);
|
newParent = stripFileProtocol(newParent);
|
||||||
|
|
||||||
|
|
||||||
// Check for invalid file name
|
// Check for invalid file name
|
||||||
if (newName != null && newName.contains(":")) {
|
if (newName != null && newName.contains(":")) {
|
||||||
throw new EncodingException("Bad file name");
|
throw new EncodingException("Bad file name");
|
||||||
@ -376,7 +379,7 @@ public class FileUtils extends Plugin {
|
|||||||
File destFile = null;
|
File destFile = null;
|
||||||
|
|
||||||
// I know this looks weird but it is to work around a JSON bug.
|
// I know this looks weird but it is to work around a JSON bug.
|
||||||
if ("null".equals(newName) || "".equals(newName) ) {
|
if ("null".equals(newName) || "".equals(newName)) {
|
||||||
newName = null;
|
newName = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,7 +401,7 @@ public class FileUtils extends Plugin {
|
|||||||
* @throws InvalidModificationException
|
* @throws InvalidModificationException
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
*/
|
*/
|
||||||
private JSONObject copyFile(File srcFile, File destFile) throws IOException, InvalidModificationException, JSONException {
|
private JSONObject copyFile(File srcFile, File destFile) throws IOException, InvalidModificationException, JSONException {
|
||||||
// Renaming a file to an existing directory should fail
|
// Renaming a file to an existing directory should fail
|
||||||
if (destFile.exists() && destFile.isDirectory()) {
|
if (destFile.exists() && destFile.isDirectory()) {
|
||||||
throw new InvalidModificationException("Can't rename a file to a directory");
|
throw new InvalidModificationException("Can't rename a file to a directory");
|
||||||
@ -476,7 +479,7 @@ public class FileUtils extends Plugin {
|
|||||||
// This weird test is to determine if we are copying or moving a directory into itself.
|
// This weird test is to determine if we are copying or moving a directory into itself.
|
||||||
// Copy /sdcard/myDir to /sdcard/myDir-backup is okay but
|
// Copy /sdcard/myDir to /sdcard/myDir-backup is okay but
|
||||||
// Copy /sdcard/myDir to /sdcard/myDir/backup should thow an INVALID_MODIFICATION_ERR
|
// Copy /sdcard/myDir to /sdcard/myDir/backup should thow an INVALID_MODIFICATION_ERR
|
||||||
if (dest.startsWith(src) && dest.indexOf(File.separator, src.length()-1) != -1) {
|
if (dest.startsWith(src) && dest.indexOf(File.separator, src.length() - 1) != -1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -725,9 +728,9 @@ public class FileUtils extends Plugin {
|
|||||||
private boolean atRootDirectory(String filePath) {
|
private boolean atRootDirectory(String filePath) {
|
||||||
filePath = stripFileProtocol(filePath);
|
filePath = stripFileProtocol(filePath);
|
||||||
|
|
||||||
if (filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + ctx.getPackageName() + "/cache") ||
|
if (filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + ctx.getActivity().getPackageName() + "/cache") ||
|
||||||
filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath()) ||
|
filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath()) ||
|
||||||
filePath.equals("/data/data/" + ctx.getPackageName())) {
|
filePath.equals("/data/data/" + ctx.getActivity().getPackageName())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -791,7 +794,7 @@ public class FileUtils extends Plugin {
|
|||||||
throw new FileNotFoundException("File: " + filePath + " does not exist.");
|
throw new FileNotFoundException("File: " + filePath + " does not exist.");
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONObject metadata = new JSONObject();
|
JSONObject metadata = new JSONObject();
|
||||||
metadata.put("size", file.length());
|
metadata.put("size", file.length());
|
||||||
metadata.put("type", getMimeType(filePath));
|
metadata.put("type", getMimeType(filePath));
|
||||||
metadata.put("name", file.getName());
|
metadata.put("name", file.getName());
|
||||||
@ -816,16 +819,16 @@ public class FileUtils extends Plugin {
|
|||||||
fs.put("name", "temporary");
|
fs.put("name", "temporary");
|
||||||
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
||||||
fp = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
|
fp = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
|
||||||
"/Android/data/" + ctx.getPackageName() + "/cache/");
|
"/Android/data/" + ctx.getActivity().getPackageName() + "/cache/");
|
||||||
// Create the cache dir if it doesn't exist.
|
// Create the cache dir if it doesn't exist.
|
||||||
fp.mkdirs();
|
fp.mkdirs();
|
||||||
fs.put("root", getEntry(Environment.getExternalStorageDirectory().getAbsolutePath() +
|
fs.put("root", getEntry(Environment.getExternalStorageDirectory().getAbsolutePath() +
|
||||||
"/Android/data/" + ctx.getPackageName() + "/cache/"));
|
"/Android/data/" + ctx.getActivity().getPackageName() + "/cache/"));
|
||||||
} else {
|
} else {
|
||||||
fp = new File("/data/data/" + ctx.getPackageName() + "/cache/");
|
fp = new File("/data/data/" + ctx.getActivity().getPackageName() + "/cache/");
|
||||||
// Create the cache dir if it doesn't exist.
|
// Create the cache dir if it doesn't exist.
|
||||||
fp.mkdirs();
|
fp.mkdirs();
|
||||||
fs.put("root", getEntry("/data/data/" + ctx.getPackageName() + "/cache/"));
|
fs.put("root", getEntry("/data/data/" + ctx.getActivity().getPackageName() + "/cache/"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == PERSISTENT) {
|
else if (type == PERSISTENT) {
|
||||||
@ -833,7 +836,7 @@ public class FileUtils extends Plugin {
|
|||||||
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
||||||
fs.put("root", getEntry(Environment.getExternalStorageDirectory()));
|
fs.put("root", getEntry(Environment.getExternalStorageDirectory()));
|
||||||
} else {
|
} else {
|
||||||
fs.put("root", getEntry("/data/data/" + ctx.getPackageName()));
|
fs.put("root", getEntry("/data/data/" + ctx.getActivity().getPackageName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -940,7 +943,7 @@ public class FileUtils extends Plugin {
|
|||||||
String contentType = null;
|
String contentType = null;
|
||||||
if (filename.startsWith("content:")) {
|
if (filename.startsWith("content:")) {
|
||||||
Uri fileUri = Uri.parse(filename);
|
Uri fileUri = Uri.parse(filename);
|
||||||
contentType = this.ctx.getContentResolver().getType(fileUri);
|
contentType = this.ctx.getActivity().getContentResolver().getType(fileUri);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
contentType = getMimeType(filename);
|
contentType = getMimeType(filename);
|
||||||
@ -959,7 +962,7 @@ public class FileUtils extends Plugin {
|
|||||||
*/
|
*/
|
||||||
public static String getMimeType(String filename) {
|
public static String getMimeType(String filename) {
|
||||||
MimeTypeMap map = MimeTypeMap.getSingleton();
|
MimeTypeMap map = MimeTypeMap.getSingleton();
|
||||||
return map.getMimeTypeFromExtension(map.getFileExtensionFromUrl(filename));
|
return map.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -980,7 +983,7 @@ public class FileUtils extends Plugin {
|
|||||||
append = true;
|
append = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte [] rawData = data.getBytes();
|
byte[] rawData = data.getBytes();
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(rawData);
|
ByteArrayInputStream in = new ByteArrayInputStream(rawData);
|
||||||
FileOutputStream out = new FileOutputStream(filename, append);
|
FileOutputStream out = new FileOutputStream(filename, append);
|
||||||
byte buff[] = new byte[rawData.length];
|
byte buff[] = new byte[rawData.length];
|
||||||
@ -1005,9 +1008,9 @@ public class FileUtils extends Plugin {
|
|||||||
RandomAccessFile raf = new RandomAccessFile(filename, "rw");
|
RandomAccessFile raf = new RandomAccessFile(filename, "rw");
|
||||||
|
|
||||||
if (raf.length() >= size) {
|
if (raf.length() >= size) {
|
||||||
FileChannel channel = raf.getChannel();
|
FileChannel channel = raf.getChannel();
|
||||||
channel.truncate(size);
|
channel.truncate(size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
return raf.length();
|
return raf.length();
|
||||||
@ -1023,7 +1026,7 @@ public class FileUtils extends Plugin {
|
|||||||
private InputStream getPathFromUri(String path) throws FileNotFoundException {
|
private InputStream getPathFromUri(String path) throws FileNotFoundException {
|
||||||
if (path.startsWith("content")) {
|
if (path.startsWith("content")) {
|
||||||
Uri uri = Uri.parse(path);
|
Uri uri = Uri.parse(path);
|
||||||
return ctx.getContentResolver().openInputStream(uri);
|
return ctx.getActivity().getContentResolver().openInputStream(uri);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
path = stripFileProtocol(path);
|
path = stripFileProtocol(path);
|
||||||
@ -1035,12 +1038,13 @@ public class FileUtils extends Plugin {
|
|||||||
* Queries the media store to find out what the file path is for the Uri we supply
|
* Queries the media store to find out what the file path is for the Uri we supply
|
||||||
*
|
*
|
||||||
* @param contentUri the Uri of the audio/image/video
|
* @param contentUri the Uri of the audio/image/video
|
||||||
* @param ctx the current applicaiton context
|
* @param ctx) the current applicaiton context
|
||||||
* @return the full path to the file
|
* @return the full path to the file
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
protected static String getRealPathFromURI(Uri contentUri, CordovaInterface ctx) {
|
protected static String getRealPathFromURI(Uri contentUri, CordovaInterface ctx) {
|
||||||
String[] proj = { _DATA };
|
String[] proj = { _DATA };
|
||||||
Cursor cursor = ctx.managedQuery(contentUri, proj, null, null, null);
|
Cursor cursor = ctx.getActivity().managedQuery(contentUri, proj, null, null, null);
|
||||||
int column_index = cursor.getColumnIndexOrThrow(_DATA);
|
int column_index = cursor.getColumnIndexOrThrow(_DATA);
|
||||||
cursor.moveToFirst();
|
cursor.moveToFirst();
|
||||||
return cursor.getString(column_index);
|
return cursor.getString(column_index);
|
||||||
|
@ -55,7 +55,7 @@ public class GeoBroker extends Plugin {
|
|||||||
*/
|
*/
|
||||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||||
if (this.locationManager == null) {
|
if (this.locationManager == null) {
|
||||||
this.locationManager = (LocationManager) this.ctx.getSystemService(Context.LOCATION_SERVICE);
|
this.locationManager = (LocationManager) this.ctx.getActivity().getSystemService(Context.LOCATION_SERVICE);
|
||||||
this.networkListener = new NetworkListener(this.locationManager, this);
|
this.networkListener = new NetworkListener(this.locationManager, this);
|
||||||
this.gpsListener = new GPSListener(this.locationManager, this);
|
this.gpsListener = new GPSListener(this.locationManager, this);
|
||||||
}
|
}
|
||||||
@ -141,46 +141,47 @@ public class GeoBroker extends Plugin {
|
|||||||
o.put("latitude", loc.getLatitude());
|
o.put("latitude", loc.getLatitude());
|
||||||
o.put("longitude", loc.getLongitude());
|
o.put("longitude", loc.getLongitude());
|
||||||
o.put("altitude", (loc.hasAltitude() ? loc.getAltitude() : null));
|
o.put("altitude", (loc.hasAltitude() ? loc.getAltitude() : null));
|
||||||
o.put("accuracy", loc.getAccuracy());
|
o.put("accuracy", loc.getAccuracy());
|
||||||
o.put("heading", (loc.hasBearing() ? (loc.hasSpeed() ? loc.getBearing() : null) : null));
|
o.put("heading", (loc.hasBearing() ? (loc.hasSpeed() ? loc.getBearing() : null) : null));
|
||||||
o.put("speed", loc.getSpeed());
|
o.put("speed", loc.getSpeed());
|
||||||
o.put("timestamp", loc.getTime());
|
o.put("timestamp", loc.getTime());
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
public void win(Location loc, String callbackId) {
|
|
||||||
PluginResult result = new PluginResult(PluginResult.Status.OK, this.returnLocationJSON(loc));
|
|
||||||
this.success(result, callbackId);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Location failed. Send error back to JavaScript.
|
|
||||||
*
|
|
||||||
* @param code The error code
|
|
||||||
* @param msg The error message
|
|
||||||
* @throws JSONException
|
|
||||||
*/
|
|
||||||
public void fail(int code, String msg, String callbackId) {
|
|
||||||
JSONObject obj = new JSONObject();
|
|
||||||
String backup = null;
|
|
||||||
try {
|
|
||||||
obj.put("code", code);
|
|
||||||
obj.put("message", msg);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
obj = null;
|
|
||||||
backup = "{'code':" + code + ",'message':'" + msg.replaceAll("'", "\'") + "'}";
|
|
||||||
}
|
|
||||||
PluginResult result;
|
|
||||||
if (obj != null) {
|
|
||||||
result = new PluginResult(PluginResult.Status.ERROR, obj);
|
|
||||||
} else {
|
|
||||||
result = new PluginResult(PluginResult.Status.ERROR, backup);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.error(result, callbackId);
|
public void win(Location loc, String callbackId) {
|
||||||
}
|
PluginResult result = new PluginResult(PluginResult.Status.OK, this.returnLocationJSON(loc));
|
||||||
|
this.success(result, callbackId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location failed. Send error back to JavaScript.
|
||||||
|
*
|
||||||
|
* @param code The error code
|
||||||
|
* @param msg The error message
|
||||||
|
* @throws JSONException
|
||||||
|
*/
|
||||||
|
public void fail(int code, String msg, String callbackId) {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
String backup = null;
|
||||||
|
try {
|
||||||
|
obj.put("code", code);
|
||||||
|
obj.put("message", msg);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
obj = null;
|
||||||
|
backup = "{'code':" + code + ",'message':'" + msg.replaceAll("'", "\'") + "'}";
|
||||||
|
}
|
||||||
|
PluginResult result;
|
||||||
|
if (obj != null) {
|
||||||
|
result = new PluginResult(PluginResult.Status.ERROR, obj);
|
||||||
|
} else {
|
||||||
|
result = new PluginResult(PluginResult.Status.ERROR, backup);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.error(result, callbackId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,16 @@ public class HttpHandler {
|
|||||||
HttpEntity entity = getHttpEntity(url);
|
HttpEntity entity = getHttpEntity(url);
|
||||||
try {
|
try {
|
||||||
writeToDisk(entity, file);
|
writeToDisk(entity, file);
|
||||||
} catch (Exception e) { e.printStackTrace(); return false; }
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
entity.consumeContent();
|
entity.consumeContent();
|
||||||
} catch (Exception e) { e.printStackTrace(); return false; }
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +52,7 @@ public class HttpHandler {
|
|||||||
* get the http entity at a given url
|
* get the http entity at a given url
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
HttpEntity entity=null;
|
HttpEntity entity = null;
|
||||||
try {
|
try {
|
||||||
DefaultHttpClient httpclient = new DefaultHttpClient();
|
DefaultHttpClient httpclient = new DefaultHttpClient();
|
||||||
HttpGet httpget = new HttpGet(url);
|
HttpGet httpget = new HttpGet(url);
|
||||||
@ -61,18 +67,18 @@ public class HttpHandler {
|
|||||||
* writes a HTTP entity to the specified filename and location on disk
|
* writes a HTTP entity to the specified filename and location on disk
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int i=0;
|
//int i = 0;
|
||||||
String FilePath="/sdcard/" + file;
|
String FilePath = "/sdcard/" + file;
|
||||||
InputStream in = entity.getContent();
|
InputStream in = entity.getContent();
|
||||||
byte buff[] = new byte[1024];
|
byte buff[] = new byte[1024];
|
||||||
FileOutputStream out=
|
FileOutputStream out =
|
||||||
new FileOutputStream(FilePath);
|
new FileOutputStream(FilePath);
|
||||||
do {
|
do {
|
||||||
int numread = in.read(buff);
|
int numread = in.read(buff);
|
||||||
if (numread <= 0)
|
if (numread <= 0)
|
||||||
break;
|
break;
|
||||||
out.write(buff, 0, numread);
|
out.write(buff, 0, numread);
|
||||||
i++;
|
//i++;
|
||||||
} while (true);
|
} while (true);
|
||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
|
@ -17,9 +17,11 @@
|
|||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
import org.apache.cordova.api.LOG;
|
import org.apache.cordova.api.LOG;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
//import android.view.View.MeasureSpec;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,7 +77,7 @@ public class LinearLayoutSoftKeyboardDetect extends LinearLayout {
|
|||||||
LOG.d(TAG, "Ignore this event");
|
LOG.d(TAG, "Ignore this event");
|
||||||
}
|
}
|
||||||
// Account for orientation change and ignore this event/Fire orientation change
|
// Account for orientation change and ignore this event/Fire orientation change
|
||||||
else if(screenHeight == width)
|
else if (screenHeight == width)
|
||||||
{
|
{
|
||||||
int tmp_var = screenHeight;
|
int tmp_var = screenHeight;
|
||||||
screenHeight = screenWidth;
|
screenHeight = screenWidth;
|
||||||
@ -85,14 +87,14 @@ public class LinearLayoutSoftKeyboardDetect extends LinearLayout {
|
|||||||
// If the height as gotten bigger then we will assume the soft keyboard has
|
// If the height as gotten bigger then we will assume the soft keyboard has
|
||||||
// gone away.
|
// gone away.
|
||||||
else if (height > oldHeight) {
|
else if (height > oldHeight) {
|
||||||
if(app != null)
|
if (app != null)
|
||||||
app.sendJavascript("cordova.fireDocumentEvent('hidekeyboard');");
|
app.appView.sendJavascript("cordova.fireDocumentEvent('hidekeyboard');");
|
||||||
}
|
}
|
||||||
// If the height as gotten smaller then we will assume the soft keyboard has
|
// If the height as gotten smaller then we will assume the soft keyboard has
|
||||||
// been displayed.
|
// been displayed.
|
||||||
else if (height < oldHeight) {
|
else if (height < oldHeight) {
|
||||||
if(app != null)
|
if (app != null)
|
||||||
app.sendJavascript("cordova.fireDocumentEvent('showkeyboard');");
|
app.appView.sendJavascript("cordova.fireDocumentEvent('showkeyboard');");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the old height for the next event
|
// Update the old height for the next event
|
||||||
|
@ -23,7 +23,6 @@ import org.apache.cordova.api.Plugin;
|
|||||||
import org.apache.cordova.api.PluginResult;
|
import org.apache.cordova.api.PluginResult;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -77,7 +76,7 @@ public class NetworkManager extends Plugin {
|
|||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
public NetworkManager() {
|
public NetworkManager() {
|
||||||
this.receiver = null;
|
this.receiver = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,20 +88,21 @@ public class NetworkManager extends Plugin {
|
|||||||
*/
|
*/
|
||||||
public void setContext(CordovaInterface ctx) {
|
public void setContext(CordovaInterface ctx) {
|
||||||
super.setContext(ctx);
|
super.setContext(ctx);
|
||||||
this.sockMan = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
|
this.sockMan = (ConnectivityManager) ctx.getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
this.connectionCallbackId = null;
|
this.connectionCallbackId = null;
|
||||||
|
|
||||||
// We need to listen to connectivity events to update navigator.connection
|
// We need to listen to connectivity events to update navigator.connection
|
||||||
IntentFilter intentFilter = new IntentFilter() ;
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||||
if (this.receiver == null) {
|
if (this.receiver == null) {
|
||||||
this.receiver = new BroadcastReceiver() {
|
this.receiver = new BroadcastReceiver() {
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
updateConnectionInfo((NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO));
|
updateConnectionInfo((NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ctx.registerReceiver(this.receiver, intentFilter);
|
ctx.getActivity().registerReceiver(this.receiver, intentFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -146,7 +146,7 @@ public class NetworkManager extends Plugin {
|
|||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
if (this.receiver != null) {
|
if (this.receiver != null) {
|
||||||
try {
|
try {
|
||||||
this.ctx.unregisterReceiver(this.receiver);
|
this.ctx.getActivity().unregisterReceiver(this.receiver);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(LOG_TAG, "Error unregistering network receiver: " + e.getMessage(), e);
|
Log.e(LOG_TAG, "Error unregistering network receiver: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
@ -157,7 +157,6 @@ public class NetworkManager extends Plugin {
|
|||||||
// LOCAL METHODS
|
// LOCAL METHODS
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the JavaScript side whenever the connection changes
|
* Updates the JavaScript side whenever the connection changes
|
||||||
*
|
*
|
||||||
@ -200,7 +199,7 @@ public class NetworkManager extends Plugin {
|
|||||||
this.success(result, this.connectionCallbackId);
|
this.success(result, this.connectionCallbackId);
|
||||||
|
|
||||||
// Send to all plugins
|
// Send to all plugins
|
||||||
this.ctx.postMessage("networkconnection", type);
|
webView.postMessage("networkconnection", type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -224,7 +223,7 @@ public class NetworkManager extends Plugin {
|
|||||||
return TYPE_2G;
|
return TYPE_2G;
|
||||||
}
|
}
|
||||||
else if (type.toLowerCase().startsWith(CDMA) ||
|
else if (type.toLowerCase().startsWith(CDMA) ||
|
||||||
type.toLowerCase().equals(UMTS) ||
|
type.toLowerCase().equals(UMTS) ||
|
||||||
type.toLowerCase().equals(ONEXRTT) ||
|
type.toLowerCase().equals(ONEXRTT) ||
|
||||||
type.toLowerCase().equals(EHRPD) ||
|
type.toLowerCase().equals(EHRPD) ||
|
||||||
type.toLowerCase().equals(HSUPA) ||
|
type.toLowerCase().equals(HSUPA) ||
|
||||||
|
@ -37,330 +37,330 @@ import android.os.Vibrator;
|
|||||||
*/
|
*/
|
||||||
public class Notification extends Plugin {
|
public class Notification extends Plugin {
|
||||||
|
|
||||||
public int confirmResult = -1;
|
public int confirmResult = -1;
|
||||||
public ProgressDialog spinnerDialog = null;
|
public ProgressDialog spinnerDialog = null;
|
||||||
public ProgressDialog progressDialog = null;
|
public ProgressDialog progressDialog = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
public Notification() {
|
public Notification() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the request and returns PluginResult.
|
* Executes the request and returns PluginResult.
|
||||||
*
|
*
|
||||||
* @param action The action to execute.
|
* @param action The action to execute.
|
||||||
* @param args JSONArry of arguments for the plugin.
|
* @param args JSONArry of arguments for the plugin.
|
||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
* @return A PluginResult object with a status and message.
|
* @return A PluginResult object with a status and message.
|
||||||
*/
|
*/
|
||||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||||
PluginResult.Status status = PluginResult.Status.OK;
|
PluginResult.Status status = PluginResult.Status.OK;
|
||||||
String result = "";
|
String result = "";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (action.equals("beep")) {
|
if (action.equals("beep")) {
|
||||||
this.beep(args.getLong(0));
|
this.beep(args.getLong(0));
|
||||||
}
|
}
|
||||||
else if (action.equals("vibrate")) {
|
else if (action.equals("vibrate")) {
|
||||||
this.vibrate(args.getLong(0));
|
this.vibrate(args.getLong(0));
|
||||||
}
|
}
|
||||||
else if (action.equals("alert")) {
|
else if (action.equals("alert")) {
|
||||||
this.alert(args.getString(0),args.getString(1),args.getString(2), callbackId);
|
this.alert(args.getString(0), args.getString(1), args.getString(2), callbackId);
|
||||||
PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
|
PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
|
||||||
r.setKeepCallback(true);
|
r.setKeepCallback(true);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
else if (action.equals("confirm")) {
|
else if (action.equals("confirm")) {
|
||||||
this.confirm(args.getString(0),args.getString(1),args.getString(2), callbackId);
|
this.confirm(args.getString(0), args.getString(1), args.getString(2), callbackId);
|
||||||
PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
|
PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
|
||||||
r.setKeepCallback(true);
|
r.setKeepCallback(true);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
else if (action.equals("activityStart")) {
|
else if (action.equals("activityStart")) {
|
||||||
this.activityStart(args.getString(0),args.getString(1));
|
this.activityStart(args.getString(0), args.getString(1));
|
||||||
}
|
}
|
||||||
else if (action.equals("activityStop")) {
|
else if (action.equals("activityStop")) {
|
||||||
this.activityStop();
|
this.activityStop();
|
||||||
}
|
}
|
||||||
else if (action.equals("progressStart")) {
|
else if (action.equals("progressStart")) {
|
||||||
this.progressStart(args.getString(0),args.getString(1));
|
this.progressStart(args.getString(0), args.getString(1));
|
||||||
}
|
}
|
||||||
else if (action.equals("progressValue")) {
|
else if (action.equals("progressValue")) {
|
||||||
this.progressValue(args.getInt(0));
|
this.progressValue(args.getInt(0));
|
||||||
}
|
}
|
||||||
else if (action.equals("progressStop")) {
|
else if (action.equals("progressStop")) {
|
||||||
this.progressStop();
|
this.progressStop();
|
||||||
}
|
}
|
||||||
return new PluginResult(status, result);
|
return new PluginResult(status, result);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies if action to be executed returns a value and should be run synchronously.
|
* Identifies if action to be executed returns a value and should be run synchronously.
|
||||||
*
|
*
|
||||||
* @param action The action to execute
|
* @param action The action to execute
|
||||||
* @return T=returns value
|
* @return T=returns value
|
||||||
*/
|
*/
|
||||||
public boolean isSynch(String action) {
|
public boolean isSynch(String action) {
|
||||||
if (action.equals("alert")) {
|
if (action.equals("alert")) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
else if (action.equals("confirm")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (action.equals("activityStart")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (action.equals("activityStop")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (action.equals("progressStart")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (action.equals("progressValue")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (action.equals("progressStop")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (action.equals("confirm")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (action.equals("activityStart")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (action.equals("activityStop")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (action.equals("progressStart")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (action.equals("progressValue")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (action.equals("progressStop")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
// LOCAL METHODS
|
// LOCAL METHODS
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Beep plays the default notification ringtone.
|
* Beep plays the default notification ringtone.
|
||||||
*
|
*
|
||||||
* @param count Number of times to play notification
|
* @param count Number of times to play notification
|
||||||
*/
|
*/
|
||||||
public void beep(long count) {
|
public void beep(long count) {
|
||||||
Uri ringtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
Uri ringtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
||||||
Ringtone notification = RingtoneManager.getRingtone(this.ctx.getContext(), ringtone);
|
Ringtone notification = RingtoneManager.getRingtone(this.ctx.getActivity().getBaseContext(), ringtone);
|
||||||
|
|
||||||
// If phone is not set to silent mode
|
// If phone is not set to silent mode
|
||||||
if (notification != null) {
|
if (notification != null) {
|
||||||
for (long i = 0; i < count; ++i) {
|
for (long i = 0; i < count; ++i) {
|
||||||
notification.play();
|
notification.play();
|
||||||
long timeout = 5000;
|
long timeout = 5000;
|
||||||
while (notification.isPlaying() && (timeout > 0)) {
|
while (notification.isPlaying() && (timeout > 0)) {
|
||||||
timeout = timeout - 100;
|
timeout = timeout - 100;
|
||||||
try {
|
try {
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vibrates the device for the specified amount of time.
|
* Vibrates the device for the specified amount of time.
|
||||||
*
|
*
|
||||||
* @param time Time to vibrate in ms.
|
* @param time Time to vibrate in ms.
|
||||||
*/
|
*/
|
||||||
public void vibrate(long time){
|
public void vibrate(long time) {
|
||||||
// Start the vibration, 0 defaults to half a second.
|
// Start the vibration, 0 defaults to half a second.
|
||||||
if (time == 0) {
|
if (time == 0) {
|
||||||
time = 500;
|
time = 500;
|
||||||
}
|
}
|
||||||
Vibrator vibrator = (Vibrator) this.ctx.getSystemService(Context.VIBRATOR_SERVICE);
|
Vibrator vibrator = (Vibrator) this.ctx.getActivity().getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
vibrator.vibrate(time);
|
vibrator.vibrate(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds and shows a native Android alert with given Strings
|
* Builds and shows a native Android alert with given Strings
|
||||||
* @param message The message the alert should display
|
* @param message The message the alert should display
|
||||||
* @param title The title of the alert
|
* @param title The title of the alert
|
||||||
* @param buttonLabel The label of the button
|
* @param buttonLabel The label of the button
|
||||||
* @param callbackId The callback id
|
* @param callbackId The callback id
|
||||||
*/
|
*/
|
||||||
public synchronized void alert(final String message, final String title, final String buttonLabel, final String callbackId) {
|
public synchronized void alert(final String message, final String title, final String buttonLabel, final String callbackId) {
|
||||||
|
|
||||||
final CordovaInterface ctx = this.ctx;
|
final CordovaInterface ctx = this.ctx;
|
||||||
final Notification notification = this;
|
final Notification notification = this;
|
||||||
|
|
||||||
Runnable runnable = new Runnable() {
|
Runnable runnable = new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
AlertDialog.Builder dlg = new AlertDialog.Builder(ctx.getContext());
|
AlertDialog.Builder dlg = new AlertDialog.Builder(ctx.getActivity());
|
||||||
dlg.setMessage(message);
|
dlg.setMessage(message);
|
||||||
dlg.setTitle(title);
|
dlg.setTitle(title);
|
||||||
dlg.setCancelable(false);
|
dlg.setCancelable(false);
|
||||||
dlg.setPositiveButton(buttonLabel,
|
dlg.setPositiveButton(buttonLabel,
|
||||||
new AlertDialog.OnClickListener() {
|
new AlertDialog.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
notification.success(new PluginResult(PluginResult.Status.OK, 0), callbackId);
|
notification.success(new PluginResult(PluginResult.Status.OK, 0), callbackId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dlg.create();
|
dlg.create();
|
||||||
dlg.show();
|
dlg.show();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
this.ctx.runOnUiThread(runnable);
|
this.ctx.getActivity().runOnUiThread(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds and shows a native Android confirm dialog with given title, message, buttons.
|
* Builds and shows a native Android confirm dialog with given title, message, buttons.
|
||||||
* This dialog only shows up to 3 buttons. Any labels after that will be ignored.
|
* This dialog only shows up to 3 buttons. Any labels after that will be ignored.
|
||||||
* The index of the button pressed will be returned to the JavaScript callback identified by callbackId.
|
* The index of the button pressed will be returned to the JavaScript callback identified by callbackId.
|
||||||
*
|
*
|
||||||
* @param message The message the dialog should display
|
* @param message The message the dialog should display
|
||||||
* @param title The title of the dialog
|
* @param title The title of the dialog
|
||||||
* @param buttonLabels A comma separated list of button labels (Up to 3 buttons)
|
* @param buttonLabels A comma separated list of button labels (Up to 3 buttons)
|
||||||
* @param callbackId The callback id
|
* @param callbackId The callback id
|
||||||
*/
|
*/
|
||||||
public synchronized void confirm(final String message, final String title, String buttonLabels, final String callbackId) {
|
public synchronized void confirm(final String message, final String title, String buttonLabels, final String callbackId) {
|
||||||
|
|
||||||
final CordovaInterface ctx = this.ctx;
|
final CordovaInterface ctx = this.ctx;
|
||||||
final Notification notification = this;
|
final Notification notification = this;
|
||||||
final String[] fButtons = buttonLabels.split(",");
|
final String[] fButtons = buttonLabels.split(",");
|
||||||
|
|
||||||
Runnable runnable = new Runnable() {
|
Runnable runnable = new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
AlertDialog.Builder dlg = new AlertDialog.Builder(ctx.getContext());
|
AlertDialog.Builder dlg = new AlertDialog.Builder(ctx.getActivity());
|
||||||
dlg.setMessage(message);
|
dlg.setMessage(message);
|
||||||
dlg.setTitle(title);
|
dlg.setTitle(title);
|
||||||
dlg.setCancelable(false);
|
dlg.setCancelable(false);
|
||||||
|
|
||||||
// First button
|
// First button
|
||||||
if (fButtons.length > 0) {
|
if (fButtons.length > 0) {
|
||||||
dlg.setNegativeButton(fButtons[0],
|
dlg.setNegativeButton(fButtons[0],
|
||||||
new AlertDialog.OnClickListener() {
|
new AlertDialog.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
notification.success(new PluginResult(PluginResult.Status.OK, 1), callbackId);
|
notification.success(new PluginResult(PluginResult.Status.OK, 1), callbackId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second button
|
||||||
|
if (fButtons.length > 1) {
|
||||||
|
dlg.setNeutralButton(fButtons[1],
|
||||||
|
new AlertDialog.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
dialog.dismiss();
|
||||||
|
notification.success(new PluginResult(PluginResult.Status.OK, 2), callbackId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Third button
|
||||||
|
if (fButtons.length > 2) {
|
||||||
|
dlg.setPositiveButton(fButtons[2],
|
||||||
|
new AlertDialog.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
dialog.dismiss();
|
||||||
|
notification.success(new PluginResult(PluginResult.Status.OK, 3), callbackId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
dlg.create();
|
||||||
|
dlg.show();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
this.ctx.getActivity().runOnUiThread(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the spinner.
|
||||||
|
*
|
||||||
|
* @param title Title of the dialog
|
||||||
|
* @param message The message of the dialog
|
||||||
|
*/
|
||||||
|
public synchronized void activityStart(final String title, final String message) {
|
||||||
|
if (this.spinnerDialog != null) {
|
||||||
|
this.spinnerDialog.dismiss();
|
||||||
|
this.spinnerDialog = null;
|
||||||
}
|
}
|
||||||
|
final Notification notification = this;
|
||||||
// Second button
|
final CordovaInterface ctx = this.ctx;
|
||||||
if (fButtons.length > 1) {
|
Runnable runnable = new Runnable() {
|
||||||
dlg.setNeutralButton(fButtons[1],
|
public void run() {
|
||||||
new AlertDialog.OnClickListener() {
|
notification.spinnerDialog = ProgressDialog.show(ctx.getActivity(), title, message, true, true,
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
new DialogInterface.OnCancelListener() {
|
||||||
dialog.dismiss();
|
public void onCancel(DialogInterface dialog) {
|
||||||
notification.success(new PluginResult(PluginResult.Status.OK, 2), callbackId);
|
notification.spinnerDialog = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
this.ctx.getActivity().runOnUiThread(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop spinner.
|
||||||
|
*/
|
||||||
|
public synchronized void activityStop() {
|
||||||
|
if (this.spinnerDialog != null) {
|
||||||
|
this.spinnerDialog.dismiss();
|
||||||
|
this.spinnerDialog = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Third button
|
/**
|
||||||
if (fButtons.length > 2) {
|
* Show the progress dialog.
|
||||||
dlg.setPositiveButton(fButtons[2],
|
*
|
||||||
new AlertDialog.OnClickListener() {
|
* @param title Title of the dialog
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
* @param message The message of the dialog
|
||||||
dialog.dismiss();
|
*/
|
||||||
notification.success(new PluginResult(PluginResult.Status.OK, 3), callbackId);
|
public synchronized void progressStart(final String title, final String message) {
|
||||||
}
|
if (this.progressDialog != null) {
|
||||||
}
|
this.progressDialog.dismiss();
|
||||||
);
|
this.progressDialog = null;
|
||||||
}
|
}
|
||||||
|
final Notification notification = this;
|
||||||
dlg.create();
|
final CordovaInterface ctx = this.ctx;
|
||||||
dlg.show();
|
Runnable runnable = new Runnable() {
|
||||||
};
|
public void run() {
|
||||||
};
|
notification.progressDialog = new ProgressDialog(ctx.getActivity());
|
||||||
this.ctx.runOnUiThread(runnable);
|
notification.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||||
}
|
notification.progressDialog.setTitle(title);
|
||||||
|
notification.progressDialog.setMessage(message);
|
||||||
/**
|
notification.progressDialog.setCancelable(true);
|
||||||
* Show the spinner.
|
notification.progressDialog.setMax(100);
|
||||||
*
|
notification.progressDialog.setProgress(0);
|
||||||
* @param title Title of the dialog
|
notification.progressDialog.setOnCancelListener(
|
||||||
* @param message The message of the dialog
|
new DialogInterface.OnCancelListener() {
|
||||||
*/
|
public void onCancel(DialogInterface dialog) {
|
||||||
public synchronized void activityStart(final String title, final String message) {
|
notification.progressDialog = null;
|
||||||
if (this.spinnerDialog != null) {
|
}
|
||||||
this.spinnerDialog.dismiss();
|
});
|
||||||
this.spinnerDialog = null;
|
notification.progressDialog.show();
|
||||||
}
|
|
||||||
final Notification notification = this;
|
|
||||||
final CordovaInterface ctx = this.ctx;
|
|
||||||
Runnable runnable = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
notification.spinnerDialog = ProgressDialog.show(ctx.getContext(), title , message, true, true,
|
|
||||||
new DialogInterface.OnCancelListener() {
|
|
||||||
public void onCancel(DialogInterface dialog) {
|
|
||||||
notification.spinnerDialog = null;
|
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
this.ctx.getActivity().runOnUiThread(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set value of progress bar.
|
||||||
|
*
|
||||||
|
* @param value 0-100
|
||||||
|
*/
|
||||||
|
public synchronized void progressValue(int value) {
|
||||||
|
if (this.progressDialog != null) {
|
||||||
|
this.progressDialog.setProgress(value);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
this.ctx.runOnUiThread(runnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop spinner.
|
|
||||||
*/
|
|
||||||
public synchronized void activityStop() {
|
|
||||||
if (this.spinnerDialog != null) {
|
|
||||||
this.spinnerDialog.dismiss();
|
|
||||||
this.spinnerDialog = null;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the progress dialog.
|
* Stop progress dialog.
|
||||||
*
|
*/
|
||||||
* @param title Title of the dialog
|
public synchronized void progressStop() {
|
||||||
* @param message The message of the dialog
|
if (this.progressDialog != null) {
|
||||||
*/
|
this.progressDialog.dismiss();
|
||||||
public synchronized void progressStart(final String title, final String message) {
|
this.progressDialog = null;
|
||||||
if (this.progressDialog != null) {
|
}
|
||||||
this.progressDialog.dismiss();
|
|
||||||
this.progressDialog = null;
|
|
||||||
}
|
}
|
||||||
final Notification notification = this;
|
|
||||||
final CordovaInterface ctx = this.ctx;
|
|
||||||
Runnable runnable = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
notification.progressDialog = new ProgressDialog(ctx.getContext());
|
|
||||||
notification.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
|
||||||
notification.progressDialog.setTitle(title);
|
|
||||||
notification.progressDialog.setMessage(message);
|
|
||||||
notification.progressDialog.setCancelable(true);
|
|
||||||
notification.progressDialog.setMax(100);
|
|
||||||
notification.progressDialog.setProgress(0);
|
|
||||||
notification.progressDialog.setOnCancelListener(
|
|
||||||
new DialogInterface.OnCancelListener() {
|
|
||||||
public void onCancel(DialogInterface dialog) {
|
|
||||||
notification.progressDialog = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
notification.progressDialog.show();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.ctx.runOnUiThread(runnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set value of progress bar.
|
|
||||||
*
|
|
||||||
* @param value 0-100
|
|
||||||
*/
|
|
||||||
public synchronized void progressValue(int value) {
|
|
||||||
if (this.progressDialog != null) {
|
|
||||||
this.progressDialog.setProgress(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop progress dialog.
|
|
||||||
*/
|
|
||||||
public synchronized void progressStop() {
|
|
||||||
if (this.progressDialog != null) {
|
|
||||||
this.progressDialog.dismiss();
|
|
||||||
this.progressDialog = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
or more contributor license agreements. See the NOTICE file
|
|
||||||
distributed with this work for additional information
|
|
||||||
regarding copyright ownership. The ASF licenses this file
|
|
||||||
to you under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance
|
|
||||||
with the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
|
||||||
software distributed under the License is distributed on an
|
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, either express or implied. See the License for the
|
|
||||||
specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
*/
|
|
||||||
package org.apache.cordova;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
import org.apache.cordova.PreferenceNode;
|
|
||||||
|
|
||||||
|
|
||||||
public class PreferenceSet {
|
|
||||||
private HashSet<PreferenceNode> innerSet;
|
|
||||||
|
|
||||||
public PreferenceSet() {
|
|
||||||
this.innerSet = new HashSet<PreferenceNode>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(PreferenceNode node) {
|
|
||||||
this.innerSet.add(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int size() {
|
|
||||||
return this.innerSet.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() {
|
|
||||||
this.innerSet.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String pref(String prefName) {
|
|
||||||
for (PreferenceNode n : innerSet)
|
|
||||||
if (prefName.equals(n.name))
|
|
||||||
return n.value;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean prefMatches(String prefName, String prefValue) {
|
|
||||||
String value = pref(prefName);
|
|
||||||
|
|
||||||
if (value == null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return value.equals(prefValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -31,7 +31,8 @@ public class SplashScreen extends Plugin {
|
|||||||
String result = "";
|
String result = "";
|
||||||
|
|
||||||
if (action.equals("hide")) {
|
if (action.equals("hide")) {
|
||||||
((DroidGap)this.ctx).removeSplashScreen();
|
//((DroidGap)this.ctx).removeSplashScreen();
|
||||||
|
this.webView.postMessage("splashscreen", "hide");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
status = PluginResult.Status.INVALID_ACTION;
|
status = PluginResult.Status.INVALID_ACTION;
|
||||||
|
@ -141,7 +141,7 @@ public class Storage extends Plugin {
|
|||||||
|
|
||||||
// If no database path, generate from application package
|
// If no database path, generate from application package
|
||||||
if (this.path == null) {
|
if (this.path == null) {
|
||||||
this.path = this.ctx.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
|
this.path = this.ctx.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dbName = this.path + File.pathSeparator + db + ".db";
|
this.dbName = this.path + File.pathSeparator + db + ".db";
|
||||||
|
@ -25,7 +25,6 @@ import org.apache.cordova.api.Plugin;
|
|||||||
import org.apache.cordova.api.PluginResult;
|
import org.apache.cordova.api.PluginResult;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
|
||||||
|
|
||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
@ -51,12 +50,12 @@ public class TempListener extends Plugin implements SensorEventListener {
|
|||||||
*/
|
*/
|
||||||
public void setContext(CordovaInterface ctx) {
|
public void setContext(CordovaInterface ctx) {
|
||||||
super.setContext(ctx);
|
super.setContext(ctx);
|
||||||
this.sensorManager = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE);
|
this.sensorManager = (SensorManager) ctx.getActivity().getSystemService(Context.SENSOR_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the request and returns PluginResult.
|
* Executes the request and returns PluginResult.
|
||||||
*
|
*
|
||||||
* @param action The action to execute.
|
* @param action The action to execute.
|
||||||
* @param args JSONArry of arguments for the plugin.
|
* @param args JSONArry of arguments for the plugin.
|
||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
@ -87,7 +86,8 @@ public class TempListener extends Plugin implements SensorEventListener {
|
|||||||
// LOCAL METHODS
|
// LOCAL METHODS
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_TEMPERATURE);
|
List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_TEMPERATURE);
|
||||||
if (list.size() > 0) {
|
if (list.size() > 0) {
|
||||||
this.mSensor = list.get(0);
|
this.mSensor = list.get(0);
|
||||||
|
@ -18,18 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova.api;
|
package org.apache.cordova.api;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import android.app.Activity;
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.content.res.AssetManager;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Cordova activity abstract class that is extended by DroidGap.
|
* The Cordova activity abstract class that is extended by DroidGap.
|
||||||
@ -38,107 +28,53 @@ import android.net.Uri;
|
|||||||
public interface CordovaInterface {
|
public interface CordovaInterface {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* Launch an activity for which you would like a result when it finished. When this activity exits,
|
||||||
* Add services to res/xml/plugins.xml instead.
|
|
||||||
*
|
|
||||||
* Add a class that implements a service.
|
|
||||||
*
|
|
||||||
* @param serviceType
|
|
||||||
* @param className
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
abstract public void addService(String serviceType, String className);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send JavaScript statement back to JavaScript.
|
|
||||||
*
|
|
||||||
* @param message
|
|
||||||
*/
|
|
||||||
abstract public void sendJavascript(String statement);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Launch an activity for which you would like a result when it finished. When this activity exits,
|
|
||||||
* your onActivityResult() method will be called.
|
* your onActivityResult() method will be called.
|
||||||
*
|
*
|
||||||
* @param command The command object
|
* @param command The command object
|
||||||
* @param intent The intent to start
|
* @param intent The intent to start
|
||||||
* @param requestCode The request code that is passed to callback to identify the activity
|
* @param requestCode The request code that is passed to callback to identify the activity
|
||||||
*/
|
*/
|
||||||
abstract public void startActivityForResult(IPlugin command, Intent intent, int requestCode);
|
abstract public void startActivityForResult(IPlugin command, Intent intent, int requestCode);
|
||||||
|
|
||||||
/**
|
|
||||||
* Launch an activity for which you would not like a result when it finished.
|
|
||||||
*
|
|
||||||
* @param intent The intent to start
|
|
||||||
*/
|
|
||||||
abstract public void startActivity(Intent intent);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the plugin to be called when a sub-activity exits.
|
* Set the plugin to be called when a sub-activity exits.
|
||||||
*
|
*
|
||||||
* @param plugin The plugin on which onActivityResult is to be called
|
* @param plugin The plugin on which onActivityResult is to be called
|
||||||
*/
|
*/
|
||||||
abstract public void setActivityResultCallback(IPlugin plugin);
|
abstract public void setActivityResultCallback(IPlugin plugin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the specified URL in the Cordova webview.
|
* Causes the Activity to override the back button behavior.
|
||||||
*
|
*
|
||||||
* @param url The URL to load.
|
* @param override
|
||||||
*/
|
*/
|
||||||
abstract public void loadUrl(String url);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a message to all plugins.
|
|
||||||
*
|
|
||||||
* @param id The message id
|
|
||||||
* @param data The message data
|
|
||||||
*/
|
|
||||||
abstract public void postMessage(String id, Object data);
|
|
||||||
|
|
||||||
|
|
||||||
public abstract Resources getResources();
|
|
||||||
|
|
||||||
public abstract String getPackageName();
|
|
||||||
|
|
||||||
public abstract Object getSystemService(String service);
|
|
||||||
|
|
||||||
public abstract Context getContext();
|
|
||||||
|
|
||||||
public abstract Context getBaseContext();
|
|
||||||
|
|
||||||
public abstract Intent registerReceiver(BroadcastReceiver receiver,
|
|
||||||
IntentFilter intentFilter);
|
|
||||||
|
|
||||||
public abstract ContentResolver getContentResolver();
|
|
||||||
|
|
||||||
public abstract void unregisterReceiver(BroadcastReceiver receiver);
|
|
||||||
|
|
||||||
public abstract Cursor managedQuery(Uri uri, String[] projection, String selection,
|
|
||||||
String[] selectionArgs, String sortOrder);
|
|
||||||
|
|
||||||
public abstract void runOnUiThread(Runnable runnable);
|
|
||||||
|
|
||||||
public abstract AssetManager getAssets();
|
|
||||||
|
|
||||||
public abstract void clearCache();
|
|
||||||
|
|
||||||
public abstract void clearHistory();
|
|
||||||
|
|
||||||
public abstract boolean backHistory();
|
|
||||||
|
|
||||||
//public abstract void addWhiteListEntry(String origin, boolean subdomains);
|
|
||||||
|
|
||||||
public abstract void bindBackButton(boolean override);
|
public abstract void bindBackButton(boolean override);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A hook required to check if the Back Button is bound.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public abstract boolean isBackButtonBound();
|
public abstract boolean isBackButtonBound();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Android activity.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public abstract Activity getActivity();
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public abstract void cancelLoadUrl();
|
public abstract void cancelLoadUrl();
|
||||||
|
|
||||||
public abstract void showWebPage(String url, boolean openExternal,
|
/**
|
||||||
boolean clearHistory, HashMap<String, Object> params);
|
* Called when a message is sent to plugin.
|
||||||
|
*
|
||||||
public abstract Context getApplicationContext();
|
* @param id The message id
|
||||||
|
* @param data The message data
|
||||||
public abstract boolean isUrlWhiteListed(String source);
|
* @return Object or null
|
||||||
|
*/
|
||||||
|
public Object onMessage(String id, Object data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova.api;
|
package org.apache.cordova.api;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
|
||||||
|
//import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.webkit.WebView;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin interface must be implemented by any plugin classes.
|
* Plugin interface must be implemented by any plugin classes.
|
||||||
@ -50,18 +52,18 @@ public interface IPlugin {
|
|||||||
/**
|
/**
|
||||||
* Sets the context of the Plugin. This can then be used to do things like
|
* Sets the context of the Plugin. This can then be used to do things like
|
||||||
* get file paths associated with the Activity.
|
* get file paths associated with the Activity.
|
||||||
*
|
*
|
||||||
* @param ctx The context of the main Activity.
|
* @param ctx The context of the main Activity.
|
||||||
*/
|
*/
|
||||||
void setContext(CordovaInterface ctx);
|
void setContext(CordovaInterface ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the main View of the application, this is the WebView within which
|
* Sets the main View of the application, this is the WebView within which
|
||||||
* a Cordova app runs.
|
* a Cordova app runs.
|
||||||
*
|
*
|
||||||
* @param webView The Cordova WebView
|
* @param webView The Cordova WebView
|
||||||
*/
|
*/
|
||||||
void setView(WebView webView);
|
void setView(CordovaWebView webView);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the system is about to start resuming a previous activity.
|
* Called when the system is about to start resuming a previous activity.
|
||||||
@ -92,8 +94,9 @@ public interface IPlugin {
|
|||||||
*
|
*
|
||||||
* @param id The message id
|
* @param id The message id
|
||||||
* @param data The message data
|
* @param data The message data
|
||||||
|
* @return Object to stop propagation or null
|
||||||
*/
|
*/
|
||||||
public void onMessage(String id, Object data);
|
public Object onMessage(String id, Object data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when an activity you launched exits, giving you the requestCode you started it with,
|
* Called when an activity you launched exits, giving you the requestCode you started it with,
|
||||||
|
@ -18,11 +18,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova.api;
|
package org.apache.cordova.api;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.webkit.WebView;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin interface must be implemented by any plugin classes.
|
* Plugin interface must be implemented by any plugin classes.
|
||||||
@ -32,12 +31,12 @@ import android.webkit.WebView;
|
|||||||
public abstract class Plugin implements IPlugin {
|
public abstract class Plugin implements IPlugin {
|
||||||
|
|
||||||
public String id;
|
public String id;
|
||||||
public WebView webView; // WebView object
|
public CordovaWebView webView; // WebView object
|
||||||
public CordovaInterface ctx; // CordovaActivity object
|
public CordovaInterface ctx; // CordovaActivity object
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the request and returns PluginResult.
|
* Executes the request and returns PluginResult.
|
||||||
*
|
*
|
||||||
* @param action The action to execute.
|
* @param action The action to execute.
|
||||||
* @param args JSONArry of arguments for the plugin.
|
* @param args JSONArry of arguments for the plugin.
|
||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
@ -66,18 +65,18 @@ public abstract class Plugin implements IPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the main View of the application, this is the WebView within which
|
* Sets the main View of the application, this is the WebView within which
|
||||||
* a Cordova app runs.
|
* a Cordova app runs.
|
||||||
*
|
*
|
||||||
* @param webView The Cordova WebView
|
* @param webView The Cordova WebView
|
||||||
*/
|
*/
|
||||||
public void setView(WebView webView) {
|
public void setView(CordovaWebView webView) {
|
||||||
this.webView = webView;
|
this.webView = webView;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
* @param multitasking Flag indicating if multitasking is turned on for app
|
||||||
*/
|
*/
|
||||||
public void onPause(boolean multitasking) {
|
public void onPause(boolean multitasking) {
|
||||||
@ -108,8 +107,10 @@ public abstract class Plugin implements IPlugin {
|
|||||||
*
|
*
|
||||||
* @param id The message id
|
* @param id The message id
|
||||||
* @param data The message data
|
* @param data The message data
|
||||||
|
* @return Object to stop propagation or null
|
||||||
*/
|
*/
|
||||||
public void onMessage(String id, Object data) {
|
public Object onMessage(String id, Object data) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,7 +142,7 @@ public abstract class Plugin implements IPlugin {
|
|||||||
* @param statement
|
* @param statement
|
||||||
*/
|
*/
|
||||||
public void sendJavascript(String statement) {
|
public void sendJavascript(String statement) {
|
||||||
this.ctx.sendJavascript(statement);
|
this.webView.sendJavascript(statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -155,7 +156,7 @@ public abstract class Plugin implements IPlugin {
|
|||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
*/
|
*/
|
||||||
public void success(PluginResult pluginResult, String callbackId) {
|
public void success(PluginResult pluginResult, String callbackId) {
|
||||||
this.ctx.sendJavascript(pluginResult.toSuccessCallbackString(callbackId));
|
this.webView.sendJavascript(pluginResult.toSuccessCallbackString(callbackId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,7 +166,7 @@ public abstract class Plugin implements IPlugin {
|
|||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
*/
|
*/
|
||||||
public void success(JSONObject message, String callbackId) {
|
public void success(JSONObject message, String callbackId) {
|
||||||
this.ctx.sendJavascript(new PluginResult(PluginResult.Status.OK, message).toSuccessCallbackString(callbackId));
|
this.webView.sendJavascript(new PluginResult(PluginResult.Status.OK, message).toSuccessCallbackString(callbackId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -175,7 +176,7 @@ public abstract class Plugin implements IPlugin {
|
|||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
*/
|
*/
|
||||||
public void success(String message, String callbackId) {
|
public void success(String message, String callbackId) {
|
||||||
this.ctx.sendJavascript(new PluginResult(PluginResult.Status.OK, message).toSuccessCallbackString(callbackId));
|
this.webView.sendJavascript(new PluginResult(PluginResult.Status.OK, message).toSuccessCallbackString(callbackId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,7 +186,7 @@ public abstract class Plugin implements IPlugin {
|
|||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
*/
|
*/
|
||||||
public void error(PluginResult pluginResult, String callbackId) {
|
public void error(PluginResult pluginResult, String callbackId) {
|
||||||
this.ctx.sendJavascript(pluginResult.toErrorCallbackString(callbackId));
|
this.webView.sendJavascript(pluginResult.toErrorCallbackString(callbackId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -195,7 +196,7 @@ public abstract class Plugin implements IPlugin {
|
|||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
*/
|
*/
|
||||||
public void error(JSONObject message, String callbackId) {
|
public void error(JSONObject message, String callbackId) {
|
||||||
this.ctx.sendJavascript(new PluginResult(PluginResult.Status.ERROR, message).toErrorCallbackString(callbackId));
|
this.webView.sendJavascript(new PluginResult(PluginResult.Status.ERROR, message).toErrorCallbackString(callbackId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -205,6 +206,6 @@ public abstract class Plugin implements IPlugin {
|
|||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
*/
|
*/
|
||||||
public void error(String message, String callbackId) {
|
public void error(String message, String callbackId) {
|
||||||
this.ctx.sendJavascript(new PluginResult(PluginResult.Status.ERROR, message).toErrorCallbackString(callbackId));
|
this.webView.sendJavascript(new PluginResult(PluginResult.Status.ERROR, message).toErrorCallbackString(callbackId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova.api;
|
package org.apache.cordova.api;
|
||||||
|
|
||||||
import android.webkit.WebView;
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
|
||||||
|
//import android.content.Context;
|
||||||
|
//import android.webkit.WebView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents a service entry object.
|
* This class represents a service entry object.
|
||||||
@ -66,12 +69,12 @@ public class PluginEntry {
|
|||||||
*
|
*
|
||||||
* @return The plugin object
|
* @return The plugin object
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
public IPlugin createPlugin(CordovaWebView webView, CordovaInterface ctx) {
|
||||||
public IPlugin createPlugin(WebView webView, CordovaInterface ctx) {
|
|
||||||
if (this.plugin != null) {
|
if (this.plugin != null) {
|
||||||
return this.plugin;
|
return this.plugin;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
Class c = getClassByName(this.pluginClass);
|
Class c = getClassByName(this.pluginClass);
|
||||||
if (isCordovaPlugin(c)) {
|
if (isCordovaPlugin(c)) {
|
||||||
this.plugin = (IPlugin) c.newInstance();
|
this.plugin = (IPlugin) c.newInstance();
|
||||||
@ -93,7 +96,7 @@ public class PluginEntry {
|
|||||||
* @return
|
* @return
|
||||||
* @throws ClassNotFoundException
|
* @throws ClassNotFoundException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("rawtypes")
|
||||||
private Class getClassByName(final String clazz) throws ClassNotFoundException {
|
private Class getClassByName(final String clazz) throws ClassNotFoundException {
|
||||||
Class c = null;
|
Class c = null;
|
||||||
if (clazz != null) {
|
if (clazz != null) {
|
||||||
@ -109,7 +112,7 @@ public class PluginEntry {
|
|||||||
* @param c The class to check the interfaces of.
|
* @param c The class to check the interfaces of.
|
||||||
* @return Boolean indicating if the class implements org.apache.cordova.api.Plugin
|
* @return Boolean indicating if the class implements org.apache.cordova.api.Plugin
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("rawtypes")
|
||||||
private boolean isCordovaPlugin(Class c) {
|
private boolean isCordovaPlugin(Class c) {
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
return org.apache.cordova.api.Plugin.class.isAssignableFrom(c) || org.apache.cordova.api.IPlugin.class.isAssignableFrom(c);
|
return org.apache.cordova.api.Plugin.class.isAssignableFrom(c) || org.apache.cordova.api.IPlugin.class.isAssignableFrom(c);
|
||||||
|
@ -23,13 +23,13 @@ import java.util.HashMap;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.XmlResourceParser;
|
import android.content.res.XmlResourceParser;
|
||||||
import android.webkit.WebView;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PluginManager is exposed to JavaScript in the Cordova WebView.
|
* PluginManager is exposed to JavaScript in the Cordova WebView.
|
||||||
@ -44,7 +44,7 @@ public class PluginManager {
|
|||||||
private final HashMap<String, PluginEntry> entries = new HashMap<String, PluginEntry>();
|
private final HashMap<String, PluginEntry> entries = new HashMap<String, PluginEntry>();
|
||||||
|
|
||||||
private final CordovaInterface ctx;
|
private final CordovaInterface ctx;
|
||||||
private final WebView app;
|
private final CordovaWebView app;
|
||||||
|
|
||||||
// Flag to track first time through
|
// Flag to track first time through
|
||||||
private boolean firstRun;
|
private boolean firstRun;
|
||||||
@ -59,7 +59,7 @@ public class PluginManager {
|
|||||||
* @param app
|
* @param app
|
||||||
* @param ctx
|
* @param ctx
|
||||||
*/
|
*/
|
||||||
public PluginManager(WebView app, CordovaInterface ctx) {
|
public PluginManager(CordovaWebView app, CordovaInterface ctx) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.firstRun = true;
|
this.firstRun = true;
|
||||||
@ -72,9 +72,9 @@ public class PluginManager {
|
|||||||
LOG.d(TAG, "init()");
|
LOG.d(TAG, "init()");
|
||||||
|
|
||||||
// If first time, then load plugins from plugins.xml file
|
// If first time, then load plugins from plugins.xml file
|
||||||
if (firstRun) {
|
if (this.firstRun) {
|
||||||
this.loadPlugins();
|
this.loadPlugins();
|
||||||
firstRun = false;
|
this.firstRun = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop plugins on current HTML page and discard plugin objects
|
// Stop plugins on current HTML page and discard plugin objects
|
||||||
@ -92,11 +92,11 @@ public class PluginManager {
|
|||||||
* Load plugins from res/xml/plugins.xml
|
* Load plugins from res/xml/plugins.xml
|
||||||
*/
|
*/
|
||||||
public void loadPlugins() {
|
public void loadPlugins() {
|
||||||
int id = ctx.getResources().getIdentifier("plugins", "xml", ctx.getPackageName());
|
int id = this.ctx.getActivity().getResources().getIdentifier("plugins", "xml", this.ctx.getActivity().getPackageName());
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
pluginConfigurationMissing();
|
this.pluginConfigurationMissing();
|
||||||
}
|
}
|
||||||
XmlResourceParser xml = ctx.getResources().getXml(id);
|
XmlResourceParser xml = this.ctx.getActivity().getResources().getXml(id);
|
||||||
int eventType = -1;
|
int eventType = -1;
|
||||||
String service = "", pluginClass = "";
|
String service = "", pluginClass = "";
|
||||||
boolean onload = false;
|
boolean onload = false;
|
||||||
@ -167,14 +167,13 @@ public class PluginManager {
|
|||||||
*
|
*
|
||||||
* @return JSON encoded string with a response message and status.
|
* @return JSON encoded string with a response message and status.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public String exec(final String service, final String action, final String callbackId, final String jsonArgs, final boolean async) {
|
public String exec(final String service, final String action, final String callbackId, final String jsonArgs, final boolean async) {
|
||||||
PluginResult cr = null;
|
PluginResult cr = null;
|
||||||
boolean runAsync = async;
|
boolean runAsync = async;
|
||||||
try {
|
try {
|
||||||
final JSONArray args = new JSONArray(jsonArgs);
|
final JSONArray args = new JSONArray(jsonArgs);
|
||||||
final IPlugin plugin = this.getPlugin(service);
|
final IPlugin plugin = this.getPlugin(service);
|
||||||
final CordovaInterface ctx = this.ctx;
|
//final CordovaInterface ctx = this.ctx;
|
||||||
if (plugin != null) {
|
if (plugin != null) {
|
||||||
runAsync = async && !plugin.isSynch(action);
|
runAsync = async && !plugin.isSynch(action);
|
||||||
if (runAsync) {
|
if (runAsync) {
|
||||||
@ -192,16 +191,16 @@ public class PluginManager {
|
|||||||
|
|
||||||
// Check the success (OK, NO_RESULT & !KEEP_CALLBACK)
|
// Check the success (OK, NO_RESULT & !KEEP_CALLBACK)
|
||||||
else if ((status == PluginResult.Status.OK.ordinal()) || (status == PluginResult.Status.NO_RESULT.ordinal())) {
|
else if ((status == PluginResult.Status.OK.ordinal()) || (status == PluginResult.Status.NO_RESULT.ordinal())) {
|
||||||
ctx.sendJavascript(cr.toSuccessCallbackString(callbackId));
|
app.sendJavascript(cr.toSuccessCallbackString(callbackId));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If error
|
// If error
|
||||||
else {
|
else {
|
||||||
ctx.sendJavascript(cr.toErrorCallbackString(callbackId));
|
app.sendJavascript(cr.toErrorCallbackString(callbackId));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
PluginResult cr = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
|
PluginResult cr = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
|
||||||
ctx.sendJavascript(cr.toErrorCallbackString(callbackId));
|
app.sendJavascript(cr.toErrorCallbackString(callbackId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -226,7 +225,7 @@ public class PluginManager {
|
|||||||
if (cr == null) {
|
if (cr == null) {
|
||||||
cr = new PluginResult(PluginResult.Status.CLASS_NOT_FOUND_EXCEPTION);
|
cr = new PluginResult(PluginResult.Status.CLASS_NOT_FOUND_EXCEPTION);
|
||||||
}
|
}
|
||||||
ctx.sendJavascript(cr.toErrorCallbackString(callbackId));
|
app.sendJavascript(cr.toErrorCallbackString(callbackId));
|
||||||
}
|
}
|
||||||
return (cr != null ? cr.getJSONString() : "{ status: 0, message: 'all good' }");
|
return (cr != null ? cr.getJSONString() : "{ status: 0, message: 'all good' }");
|
||||||
}
|
}
|
||||||
@ -240,7 +239,7 @@ public class PluginManager {
|
|||||||
* @return IPlugin or null
|
* @return IPlugin or null
|
||||||
*/
|
*/
|
||||||
private IPlugin getPlugin(String service) {
|
private IPlugin getPlugin(String service) {
|
||||||
PluginEntry entry = entries.get(service);
|
PluginEntry entry = this.entries.get(service);
|
||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -315,13 +314,22 @@ public class PluginManager {
|
|||||||
*
|
*
|
||||||
* @param id The message id
|
* @param id The message id
|
||||||
* @param data The message data
|
* @param data The message data
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
public void postMessage(String id, Object data) {
|
public Object postMessage(String id, Object data) {
|
||||||
|
Object obj = this.ctx.onMessage(id, data);
|
||||||
|
if (obj != null) {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
for (PluginEntry entry : this.entries.values()) {
|
for (PluginEntry entry : this.entries.values()) {
|
||||||
if (entry.plugin != null) {
|
if (entry.plugin != null) {
|
||||||
entry.plugin.onMessage(id, data);
|
obj = entry.plugin.onMessage(id, data);
|
||||||
|
if (obj != null) {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,12 +25,13 @@ public class PluginResult {
|
|||||||
private final int status;
|
private final int status;
|
||||||
private final String message;
|
private final String message;
|
||||||
private boolean keepCallback = false;
|
private boolean keepCallback = false;
|
||||||
|
|
||||||
|
|
||||||
public PluginResult(Status status) {
|
public PluginResult(Status status) {
|
||||||
this.status = status.ordinal();
|
this.status = status.ordinal();
|
||||||
this.message = "'" + PluginResult.StatusMessages[this.status] + "'";
|
this.message = "'" + PluginResult.StatusMessages[this.status] + "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginResult(Status status, String message) {
|
public PluginResult(Status status, String message) {
|
||||||
this.status = status.ordinal();
|
this.status = status.ordinal();
|
||||||
this.message = JSONObject.quote(message);
|
this.message = JSONObject.quote(message);
|
||||||
@ -60,11 +61,11 @@ public class PluginResult {
|
|||||||
this.status = status.ordinal();
|
this.status = status.ordinal();
|
||||||
this.message = ""+b;
|
this.message = ""+b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKeepCallback(boolean b) {
|
public void setKeepCallback(boolean b) {
|
||||||
this.keepCallback = b;
|
this.keepCallback = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStatus() {
|
public int getStatus() {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -72,23 +73,23 @@ public class PluginResult {
|
|||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getKeepCallback() {
|
public boolean getKeepCallback() {
|
||||||
return this.keepCallback;
|
return this.keepCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getJSONString() {
|
public String getJSONString() {
|
||||||
return "{\"status\":" + this.status + ",\"message\":" + this.message + ",\"keepCallback\":" + this.keepCallback + "}";
|
return "{\"status\":" + this.status + ",\"message\":" + this.message + ",\"keepCallback\":" + this.keepCallback + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toSuccessCallbackString(String callbackId) {
|
public String toSuccessCallbackString(String callbackId) {
|
||||||
return "cordova.callbackSuccess('"+callbackId+"',"+this.getJSONString()+");";
|
return "cordova.callbackSuccess('"+callbackId+"',"+this.getJSONString()+");";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toErrorCallbackString(String callbackId) {
|
public String toErrorCallbackString(String callbackId) {
|
||||||
return "cordova.callbackError('"+callbackId+"', " + this.getJSONString()+ ");";
|
return "cordova.callbackError('"+callbackId+"', " + this.getJSONString()+ ");";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] StatusMessages = new String[] {
|
public static String[] StatusMessages = new String[] {
|
||||||
"No result",
|
"No result",
|
||||||
"OK",
|
"OK",
|
||||||
@ -101,7 +102,7 @@ public class PluginResult {
|
|||||||
"JSON error",
|
"JSON error",
|
||||||
"Error"
|
"Error"
|
||||||
};
|
};
|
||||||
|
|
||||||
public enum Status {
|
public enum Status {
|
||||||
NO_RESULT,
|
NO_RESULT,
|
||||||
OK,
|
OK,
|
||||||
|
29
guides/Cordova Upgrade Guide.md
Normal file
29
guides/Cordova Upgrade Guide.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Cordova Upgrade Guide #
|
||||||
|
|
||||||
|
This document is for people who need to upgrade their Cordova versions from an older version to a current version of Cordova.
|
||||||
|
|
||||||
|
- To upgrade to 1.8.0, please go from 1.7.0
|
||||||
|
- To upgrade from 1.7.0, please go from 1.6.0
|
||||||
|
|
||||||
|
## Upgrade to 1.8.0 from 1.7.0 ##
|
||||||
|
|
||||||
|
1. Remove cordova-1.7.0.jar from the libs directory in your project
|
||||||
|
2. Add cordova-1.8.0.jar to the libs directory in your project
|
||||||
|
3. If you are using Eclipse, please refresh your eclipse project and do a clean
|
||||||
|
4. Copy the new cordova-1.7.0.js into your project
|
||||||
|
5. Update your HTML to sue the new cordova-1.7.0.js file
|
||||||
|
6. Update the res/xml/plugins.xml to be the same as the one found in framework/res/xml/plugins.xml
|
||||||
|
|
||||||
|
|
||||||
|
## Upgrade to 1.7.0 from 1.6.0 ##
|
||||||
|
|
||||||
|
1. Remove cordova-1.6.0.jar from the libs directory in your project
|
||||||
|
2. Add cordova-1.6.0.jar to the libs directory in your project
|
||||||
|
3. If you are using Eclipse, please refresh your eclipse project and do a clean
|
||||||
|
4. Copy the new cordova-1.6.0.js into your project
|
||||||
|
5. Update your HTML to sue the new cordova-1.6.0.js file
|
||||||
|
6. Update the res/xml/plugins.xml to be the same as the one found in framework/res/xml/plugins.xml
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
53
guides/CordovaWebView Guide.md
Normal file
53
guides/CordovaWebView Guide.md
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# How to use Cordova as a component #
|
||||||
|
|
||||||
|
Beginning in Cordova 1.8, with the assistance of the CordovaActivity, you can use Cordova as a component in your Android applications. This component is known in Android
|
||||||
|
as the CordovaWebView, and new Cordova-based applications from 1.8 and greater will be using the CordovaWebView as its main view, whether the legacy DroidGap approach is
|
||||||
|
used or not.
|
||||||
|
|
||||||
|
|
||||||
|
The pre-requisites are the same as the pre-requisites for Android application development. It is assumed that you are familiar with Android Development. If not, please
|
||||||
|
look at the Getting Started guide to developing an Cordova Application and start there before continuing with this approach. Since this is not the main method that people use
|
||||||
|
to run applications, the instructions are currently manual. In the future, we may try to further automate the project generation.
|
||||||
|
|
||||||
|
## Pre-requisites ##
|
||||||
|
|
||||||
|
1. **Cordova 1.8** or greater downloaded
|
||||||
|
2. Android SDK updated with 15
|
||||||
|
|
||||||
|
## Guide to using CordovaWebView in an Android Project ##
|
||||||
|
|
||||||
|
1. Use bin/create to fetch the commons-codec-1.6.jar
|
||||||
|
2. Go into framework and run ant jar to build the cordova jar (currently cordova-1.8.jar at the time of writing)
|
||||||
|
3. Copy the cordova jar into your Android project libs directory
|
||||||
|
4. Edit your main.xml to look similar the following. The layout_height, layout_width and ID can be modified to suit your application:
|
||||||
|
|
||||||
|
` <org.apache.cordova.CordovaWebView$
|
||||||
|
android:id="@+id/tutorialView"$
|
||||||
|
android:layout_width="match_parent"$
|
||||||
|
android:layout_height="match_parent" />$
|
||||||
|
`
|
||||||
|
|
||||||
|
5. Modify your activity so that it implements the CordovaInterface. It is recommended that you implement the methods that are included. You may wish to copy the methods from framework/src/org/apache/cordova/DroidGap.java, or you may wish to implement your own methods. Below is a fragment of code from a basic application that uses the interface:
|
||||||
|
|
||||||
|
`
|
||||||
|
public class CordovaViewTestActivity extends Activity implements CordovaInterface {$
|
||||||
|
CordovaWebView phoneGap;$
|
||||||
|
$
|
||||||
|
/** Called when the activity is first created. */$
|
||||||
|
@Override$
|
||||||
|
public void onCreate(Bundle savedInstanceState) {$
|
||||||
|
super.onCreate(savedInstanceState);$
|
||||||
|
setContentView(R.layout.main);$
|
||||||
|
$
|
||||||
|
phoneGap = (CordovaWebView) findViewById(R.id.phoneGapView);$
|
||||||
|
$
|
||||||
|
phoneGap.loadUrl("file:///android_asset/www/index.html");$
|
||||||
|
}$
|
||||||
|
`
|
||||||
|
|
||||||
|
6. Copy the HTML and Javascript used to the assets directory of your Android project
|
||||||
|
7. Copy cordova.xml and plugins.xml from framework/res/xml to the framework/res/xml in your project
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
0
test/.classpath
Executable file → Normal file
0
test/.classpath
Executable file → Normal file
2
test/.project
Executable file → Normal file
2
test/.project
Executable file → Normal file
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<projectDescription>
|
<projectDescription>
|
||||||
<name>CordovaTest</name>
|
<name>PhoneGapViewTestActivity</name>
|
||||||
<comment></comment>
|
<comment></comment>
|
||||||
<projects>
|
<projects>
|
||||||
</projects>
|
</projects>
|
||||||
|
@ -20,20 +20,20 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan"
|
||||||
package="org.apache.cordova.test" android:versionName="1.1" android:versionCode="5">
|
package="org.apache.cordova.test" android:versionName="1.1" android:versionCode="5">
|
||||||
<supports-screens
|
<supports-screens
|
||||||
android:largeScreens="true"
|
android:largeScreens="true"
|
||||||
android:normalScreens="true"
|
android:normalScreens="true"
|
||||||
android:smallScreens="true"
|
android:smallScreens="true"
|
||||||
android:xlargeScreens="true"
|
android:xlargeScreens="true"
|
||||||
android:resizeable="true"
|
android:resizeable="true"
|
||||||
android:anyDensity="true"
|
android:anyDensity="true"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
|
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_SMS" />
|
<uses-permission android:name="android.permission.RECEIVE_SMS" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="android.permission.RECORD_VIDEO"/>
|
<uses-permission android:name="android.permission.RECORD_VIDEO"/>
|
||||||
@ -44,21 +44,66 @@
|
|||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||||
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
|
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
|
||||||
|
|
||||||
|
<uses-sdk android:minSdkVersion="7" />
|
||||||
|
|
||||||
<uses-feature android:name="android.hardware.camera" />
|
<instrumentation
|
||||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
android:name="android.test.InstrumentationTestRunner"
|
||||||
|
android:targetPackage="org.apache.cordova.test" />
|
||||||
|
|
||||||
<application android:icon="@drawable/icon" android:label="@string/app_name"
|
<application
|
||||||
android:debuggable="true">
|
android:icon="@drawable/icon"
|
||||||
<activity android:name="tests" android:label="@string/app_name"
|
android:label="@string/app_name" >
|
||||||
android:configChanges="orientation|keyboardHidden">
|
<uses-library android:name="android.test.runner" />
|
||||||
<intent-filter>
|
<activity
|
||||||
<action android:name="android.intent.action.MAIN" />
|
android:windowSoftInputMode="adjustPan"
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
android:label="@string/app_name"
|
||||||
</intent-filter>
|
android:configChanges="orientation|keyboardHidden"
|
||||||
|
android:name=".CordovaWebViewTestActivity" >
|
||||||
|
<intent-filter >
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity android:name="tests" android:label="@string/app_name"
|
||||||
|
android:configChanges="orientation|keyboardHidden">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.SAMPLE_CODE" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:windowSoftInputMode="adjustPan"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:configChanges="orientation|keyboardHidden"
|
||||||
|
android:name=".JailActivity" >
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.SAMPLE_CODE" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:windowSoftInputMode="adjustPan"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:configChanges="orientation|keyboardHidden"
|
||||||
|
android:name=".CordovaDriverAction" >
|
||||||
|
<intent-filter >
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.SAMPLE_CODE" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:windowSoftInputMode="adjustPan"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:configChanges="orientation|keyboardHidden"
|
||||||
|
android:name=".CordovaActivity" >
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.SAMPLE_CODE" />
|
||||||
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="splashscreen" android:label="@string/app_name"
|
<activity android:name="splashscreen" android:label="@string/app_name"
|
||||||
android:configChanges="orientation|keyboardHidden">
|
android:configChanges="orientation|keyboardHidden">
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="timeout" android:label="@string/app_name"
|
<activity android:name="timeout" android:label="@string/app_name"
|
||||||
android:configChanges="orientation|keyboardHidden">
|
android:configChanges="orientation|keyboardHidden">
|
||||||
@ -99,7 +144,14 @@
|
|||||||
<activity android:name="xhr" android:label="@string/app_name"
|
<activity android:name="xhr" android:label="@string/app_name"
|
||||||
android:configChanges="orientation|keyboardHidden">
|
android:configChanges="orientation|keyboardHidden">
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity android:name="basicauth" android:label="@string/app_name"
|
||||||
|
android:configChanges="orientation|keyboardHidden">
|
||||||
|
</activity>
|
||||||
|
<activity android:name="fullscreen" android:label="@string/app_name"
|
||||||
|
android:configChanges="orientation|keyboardHidden">
|
||||||
|
</activity>
|
||||||
|
<activity android:name="backgroundcolor" android:label="@string/app_name"
|
||||||
|
android:configChanges="orientation|keyboardHidden">
|
||||||
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="5" />
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -1,23 +1,30 @@
|
|||||||
## Android Native Tests ##
|
# Android Native Tests #
|
||||||
|
|
||||||
These tests are designed to verify Android native features and other Android specific features.
|
These tests are designed to verify Android native features and other Android specific features.
|
||||||
|
|
||||||
|
## Initial Setup ##
|
||||||
|
|
||||||
Before running the tests, they need to be set up.
|
Before running the tests, they need to be set up.
|
||||||
|
|
||||||
1. Copy the version of cordova-x.y.z.js into assets/www directory
|
0. Copy cordova-x.y.z.jar into libs directory
|
||||||
2. Edit assets/www/cordova.js to reference the correct version
|
|
||||||
3. Copy cordova-x.y.z.jar into libs directory
|
|
||||||
|
|
||||||
To run from command line:
|
To run from command line:
|
||||||
|
|
||||||
4. Build by entering "ant debug install"
|
0. Build by entering `ant debug install`
|
||||||
5. Run tests by clicking on "CordovaTest" icon on device
|
0. Run tests by clicking on "CordovaTest" icon on device
|
||||||
|
|
||||||
To run from Eclipse:
|
To run from Eclipse:
|
||||||
|
|
||||||
4. Import Android project into Eclipse
|
0. Import Android project into Eclipse
|
||||||
5. Ensure Project properties "Java Build Path" includes the lib/cordova-x.y.z.jar
|
0. Ensure Project properties "Java Build Path" includes the lib/cordova-x.y.z.jar
|
||||||
6. Create run configuration if not already created
|
0. Create run configuration if not already created
|
||||||
7. Run tests
|
0. Run tests
|
||||||
|
|
||||||
|
## Automatic Runs ##
|
||||||
|
|
||||||
|
Once you have installed the test, you can launch and run the tests
|
||||||
|
automatically with the below command:
|
||||||
|
|
||||||
|
adb shell am instrument -w org.apache.cordova.test/android.test.InstrumentationTestRunner
|
||||||
|
|
||||||
|
(Optionally, you can also run in Eclipse)
|
||||||
|
41
test/assets/www/backgroundcolor/index.html
Executable file
41
test/assets/www/backgroundcolor/index.html
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
<!--
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=320; user-scalable=no" />
|
||||||
|
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||||
|
<title>Cordova Tests</title>
|
||||||
|
<link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title">
|
||||||
|
<script type="text/javascript" charset="utf-8" src="../cordova.js"></script>
|
||||||
|
<script type="text/javascript" charset="utf-8" src="../main.js"></script>
|
||||||
|
</head>
|
||||||
|
<body onload="init();" id="stage" class="theme">
|
||||||
|
<h1>Background Color Test</h1>
|
||||||
|
<div id="info">
|
||||||
|
<h4>Platform: <span id="platform"> </span>, Version: <span id="version"> </span></h4>
|
||||||
|
<h4>UUID: <span id="uuid"> </span>, Name: <span id="name"> </span></h4>
|
||||||
|
<h4>Width: <span id="width"> </span>, Height: <span id="height">
|
||||||
|
</span>, Color Depth: <span id="colorDepth"></span></h4>
|
||||||
|
</div>
|
||||||
|
<div id="info">
|
||||||
|
Before this page was show, you should have seen the background flash green.</br>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
42
test/assets/www/basicauth/index.html
Executable file
42
test/assets/www/basicauth/index.html
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
<!--
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=320; user-scalable=no" />
|
||||||
|
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||||
|
<title>Cordova Tests</title>
|
||||||
|
<link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title">
|
||||||
|
<script type="text/javascript" charset="utf-8" src="../cordova.js"></script>
|
||||||
|
<script type="text/javascript" charset="utf-8" src="../main.js"></script>
|
||||||
|
</head>
|
||||||
|
<body onload="init();" id="stage" class="theme">
|
||||||
|
<h1>Basic Auth</h1>
|
||||||
|
<div id="info">
|
||||||
|
<h4>Platform: <span id="platform"> </span>, Version: <span id="version"> </span></h4>
|
||||||
|
<h4>UUID: <span id="uuid"> </span>, Name: <span id="name"> </span></h4>
|
||||||
|
<h4>Width: <span id="width"> </span>, Height: <span id="height">
|
||||||
|
</span>, Color Depth: <span id="colorDepth"></span></h4>
|
||||||
|
</div>
|
||||||
|
<div id="info">
|
||||||
|
Loading link below should be successful and show page indicating username=test & password=test. <br>
|
||||||
|
</div>
|
||||||
|
<a href="http://browserspy.dk/password-ok.php" class="btn large">Test password</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
4985
test/assets/www/cordova-1.6.0.js
vendored
4985
test/assets/www/cordova-1.6.0.js
vendored
File diff suppressed because it is too large
Load Diff
42
test/assets/www/fullscreen/index.html
Executable file
42
test/assets/www/fullscreen/index.html
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
<!--
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=320; user-scalable=no" />
|
||||||
|
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||||
|
<title>Cordova Tests</title>
|
||||||
|
<link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title">
|
||||||
|
<script type="text/javascript" charset="utf-8" src="../cordova.js"></script>
|
||||||
|
<script type="text/javascript" charset="utf-8" src="../main.js"></script>
|
||||||
|
</head>
|
||||||
|
<body onload="init();" id="stage" class="theme">
|
||||||
|
<h1>Full Screen Test</h1>
|
||||||
|
<div id="info">
|
||||||
|
<h4>Platform: <span id="platform"> </span>, Version: <span id="version"> </span></h4>
|
||||||
|
<h4>UUID: <span id="uuid"> </span>, Name: <span id="name"> </span></h4>
|
||||||
|
<h4>Width: <span id="width"> </span>, Height: <span id="height">
|
||||||
|
</span>, Color Depth: <span id="colorDepth"></span></h4>
|
||||||
|
</div>
|
||||||
|
<div id="info">
|
||||||
|
The app should take over the entire screen. <br>
|
||||||
|
The top Android status bar should not be shown.
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,20 +1,20 @@
|
|||||||
<!--
|
<!--
|
||||||
Licensed to the Apache Software Foundation (ASF) under one$
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
or more contributor license agreements. See the NOTICE file$
|
or more contributor license agreements. See the NOTICE file
|
||||||
distributed with this work for additional information$
|
distributed with this work for additional information
|
||||||
regarding copyright ownership. The ASF licenses this file$
|
regarding copyright ownership. The ASF licenses this file
|
||||||
to you under the Apache License, Version 2.0 (the$
|
to you under the Apache License, Version 2.0 (the
|
||||||
"License"); you may not use this file except in compliance$
|
"License"); you may not use this file except in compliance
|
||||||
with the License. You may obtain a copy of the License at$
|
with the License. You may obtain a copy of the License at
|
||||||
$
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0$
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
$
|
|
||||||
Unless required by applicable law or agreed to in writing,$
|
Unless required by applicable law or agreed to in writing,
|
||||||
software distributed under the License is distributed on an$
|
software distributed under the License is distributed on an
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY$
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
KIND, either express or implied. See the License for the$
|
KIND, either express or implied. See the License for the
|
||||||
specific language governing permissions and limitations$
|
specific language governing permissions and limitations
|
||||||
under the License.$
|
under the License.
|
||||||
-->
|
-->
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<html>
|
<html>
|
||||||
@ -49,7 +49,10 @@ $
|
|||||||
</div>
|
</div>
|
||||||
<button class="btn large" onclick="startActivity('org.apache.cordova.test.jqmtabbackbutton');">Backbutton jQM tab</button>
|
<button class="btn large" onclick="startActivity('org.apache.cordova.test.jqmtabbackbutton');">Backbutton jQM tab</button>
|
||||||
<button class="btn large" onclick="startActivity('org.apache.cordova.test.backbuttonmultipage');">Backbutton with multiple pages</button>
|
<button class="btn large" onclick="startActivity('org.apache.cordova.test.backbuttonmultipage');">Backbutton with multiple pages</button>
|
||||||
|
<button class="btn large" onclick="startActivity('org.apache.cordova.test.backgroundcolor');">Background Color</button>
|
||||||
|
<button class="btn large" onclick="startActivity('org.apache.cordova.test.basicauth');">Basic Authentication</button>
|
||||||
<button class="btn large" onclick="startActivity('org.apache.cordova.test.errorurl');">Error URL</button>
|
<button class="btn large" onclick="startActivity('org.apache.cordova.test.errorurl');">Error URL</button>
|
||||||
|
<button class="btn large" onclick="startActivity('org.apache.cordova.test.fullscreen');">Full Screen</button>
|
||||||
<button class="btn large" onclick="startActivity('org.apache.cordova.test.htmlnotfound');">HTML not found</button>
|
<button class="btn large" onclick="startActivity('org.apache.cordova.test.htmlnotfound');">HTML not found</button>
|
||||||
<button class="btn large" onclick="startActivity('org.apache.cordova.test.iframe');">IFrame</button>
|
<button class="btn large" onclick="startActivity('org.apache.cordova.test.iframe');">IFrame</button>
|
||||||
<button class="btn large" onclick="startActivity('org.apache.cordova.test.lifecycle');">Lifecycle</button>
|
<button class="btn large" onclick="startActivity('org.apache.cordova.test.lifecycle');">Lifecycle</button>
|
||||||
|
40
test/proguard.cfg
Normal file
40
test/proguard.cfg
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
-optimizationpasses 5
|
||||||
|
-dontusemixedcaseclassnames
|
||||||
|
-dontskipnonpubliclibraryclasses
|
||||||
|
-dontpreverify
|
||||||
|
-verbose
|
||||||
|
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||||
|
|
||||||
|
-keep public class * extends android.app.Activity
|
||||||
|
-keep public class * extends android.app.Application
|
||||||
|
-keep public class * extends android.app.Service
|
||||||
|
-keep public class * extends android.content.BroadcastReceiver
|
||||||
|
-keep public class * extends android.content.ContentProvider
|
||||||
|
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||||
|
-keep public class * extends android.preference.Preference
|
||||||
|
-keep public class com.android.vending.licensing.ILicensingService
|
||||||
|
|
||||||
|
-keepclasseswithmembernames class * {
|
||||||
|
native <methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclasseswithmembers class * {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclasseswithmembers class * {
|
||||||
|
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclassmembers class * extends android.app.Activity {
|
||||||
|
public void *(android.view.View);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclassmembers enum * {
|
||||||
|
public static **[] values();
|
||||||
|
public static ** valueOf(java.lang.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep class * implements android.os.Parcelable {
|
||||||
|
public static final android.os.Parcelable$Creator *;
|
||||||
|
}
|
2
test/project.properties
Executable file → Normal file
2
test/project.properties
Executable file → Normal file
@ -8,4 +8,4 @@
|
|||||||
# project structure.
|
# project structure.
|
||||||
|
|
||||||
# Project target.
|
# Project target.
|
||||||
target=Google Inc.:Google APIs:14
|
target=Google Inc.:Google APIs:15
|
||||||
|
16
test/res/layout/main.xml
Executable file → Normal file
16
test/res/layout/main.xml
Executable file → Normal file
@ -18,14 +18,14 @@
|
|||||||
under the License.
|
under the License.
|
||||||
-->
|
-->
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
>
|
android:orientation="vertical" >
|
||||||
<TextView
|
|
||||||
android:layout_width="fill_parent"
|
<org.apache.cordova.CordovaWebView
|
||||||
android:layout_height="wrap_content"
|
android:id="@+id/phoneGapView"
|
||||||
android:text="Hello World, tests"
|
android:layout_width="fill_parent"
|
||||||
/>
|
android:layout_height="fill_parent" />
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
2
test/res/values/strings.xml
Executable file → Normal file
2
test/res/values/strings.xml
Executable file → Normal file
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">CordovaTests</string>
|
<string name="app_name">CordovaTests</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -18,19 +18,19 @@
|
|||||||
under the License.
|
under the License.
|
||||||
-->
|
-->
|
||||||
<cordova>
|
<cordova>
|
||||||
<!--
|
<!--
|
||||||
access elements control the Android whitelist.
|
access elements control the Android whitelist.
|
||||||
Domains are assumed blocked unless set otherwise
|
Domains are assumed blocked unless set otherwise
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<access origin="http://127.0.0.1*"/> <!-- allow local pages -->
|
<access origin="http://127.0.0.1*"/> <!-- allow local pages -->
|
||||||
|
|
||||||
<!-- <access origin="https://example.com" /> allow any secure requests to example.com -->
|
<!-- <access origin="https://example.com" /> allow any secure requests to example.com -->
|
||||||
<!-- <access origin="https://example.com" subdomains="true" /> such as above, but including subdomains, such as www -->
|
<!-- <access origin="https://example.com" subdomains="true" /> such as above, but including subdomains, such as www -->
|
||||||
<!-- <access origin=".*"/> Allow all domains, suggested development use only -->
|
<!-- <access origin=".*"/> Allow all domains, suggested development use only -->
|
||||||
|
|
||||||
<log level="DEBUG"/>
|
<log level="DEBUG"/>
|
||||||
<preference name="classicRender" value="true" />
|
<preference name="useBrowserHistory" value="true" />
|
||||||
</cordova>
|
</cordova>
|
||||||
|
|
||||||
|
|
||||||
|
0
test/res/xml/plugins.xml
Executable file → Normal file
0
test/res/xml/plugins.xml
Executable file → Normal file
@ -69,9 +69,9 @@ public class ActivityPlugin extends Plugin {
|
|||||||
|
|
||||||
public void startActivity(String className) {
|
public void startActivity(String className) {
|
||||||
try {
|
try {
|
||||||
Intent intent = new Intent().setClass(this.ctx.getContext(), Class.forName(className));
|
Intent intent = new Intent().setClass(this.ctx.getActivity(), Class.forName(className));
|
||||||
LOG.d(TAG, "Starting activity %s", className);
|
LOG.d(TAG, "Starting activity %s", className);
|
||||||
this.ctx.startActivity(intent);
|
this.ctx.getActivity().startActivity(intent);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
LOG.e(TAG, "Error starting activity %s", className);
|
LOG.e(TAG, "Error starting activity %s", className);
|
||||||
|
@ -16,19 +16,18 @@
|
|||||||
specific language governing permissions and limitations
|
specific language governing permissions and limitations
|
||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.cordova;
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
// represents the <preference> element from the W3C config.xml spec
|
import org.apache.cordova.DroidGap;
|
||||||
// see http://www.w3.org/TR/widgets/#the-preference-element-and-its-attributes
|
|
||||||
public class PreferenceNode {
|
|
||||||
public String name;
|
|
||||||
public String value;
|
|
||||||
public boolean readonly;
|
|
||||||
|
|
||||||
// constructor
|
import android.app.Activity;
|
||||||
public PreferenceNode(String name, String value, boolean readonly) {
|
import android.os.Bundle;
|
||||||
this.name = name;
|
|
||||||
this.value = value;
|
public class CordovaActivity extends DroidGap {
|
||||||
this.readonly = readonly;
|
/** Called when the activity is first created. */
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
super.loadUrl("file:///android_asset/www/index.html");
|
||||||
}
|
}
|
||||||
}
|
}
|
68
test/src/org/apache/cordova/test/CordovaActivityTest.java
Normal file
68
test/src/org/apache/cordova/test/CordovaActivityTest.java
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import com.phonegap.api.PluginManager;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
public class CordovaActivityTest extends ActivityInstrumentationTestCase2<CordovaActivity> {
|
||||||
|
|
||||||
|
private CordovaActivity testActivity;
|
||||||
|
private FrameLayout containerView;
|
||||||
|
private LinearLayout innerContainer;
|
||||||
|
private CordovaWebView testView;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public CordovaActivityTest()
|
||||||
|
{
|
||||||
|
super("org.apache.cordova.test",CordovaActivity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
testActivity = this.getActivity();
|
||||||
|
containerView = (FrameLayout) testActivity.findViewById(android.R.id.content);
|
||||||
|
innerContainer = (LinearLayout) containerView.getChildAt(0);
|
||||||
|
testView = (CordovaWebView) innerContainer.getChildAt(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPreconditions(){
|
||||||
|
assertNotNull(innerContainer);
|
||||||
|
assertNotNull(testView);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testForCordovaView() {
|
||||||
|
String className = testView.getClass().getSimpleName();
|
||||||
|
assertTrue(className.equals("CordovaWebView"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testForLinearLayout() {
|
||||||
|
String className = innerContainer.getClass().getSimpleName();
|
||||||
|
assertTrue(className.equals("LinearLayoutSoftKeyboardDetect"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
109
test/src/org/apache/cordova/test/CordovaTest.java
Normal file
109
test/src/org/apache/cordova/test/CordovaTest.java
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import com.phonegap.api.PluginManager;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
public class CordovaTest extends
|
||||||
|
ActivityInstrumentationTestCase2<CordovaWebViewTestActivity> {
|
||||||
|
|
||||||
|
private static final long TIMEOUT = 1000;
|
||||||
|
private CordovaWebViewTestActivity testActivity;
|
||||||
|
private View testView;
|
||||||
|
private String rString;
|
||||||
|
|
||||||
|
public CordovaTest() {
|
||||||
|
super("com.phonegap.test.activities", CordovaWebViewTestActivity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
testActivity = this.getActivity();
|
||||||
|
testView = testActivity.findViewById(R.id.phoneGapView);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPreconditions() {
|
||||||
|
assertNotNull(testView);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testForCordovaView() {
|
||||||
|
String className = testView.getClass().getSimpleName();
|
||||||
|
assertTrue(className.equals("CordovaWebView"));
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
public void testForPluginManager() {
|
||||||
|
CordovaWebView v = (CordovaWebView) testView;
|
||||||
|
PluginManager p = v.getPluginManager();
|
||||||
|
assertNotNull(p);
|
||||||
|
String className = p.getClass().getSimpleName();
|
||||||
|
assertTrue(className.equals("PluginManager"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBackButton() {
|
||||||
|
CordovaWebView v = (CordovaWebView) testView;
|
||||||
|
assertFalse(v.checkBackKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLoadUrl() {
|
||||||
|
CordovaWebView v = (CordovaWebView) testView;
|
||||||
|
v.loadUrlIntoView("file:///android_asset/www/index.html");
|
||||||
|
sleep();
|
||||||
|
String url = v.getUrl();
|
||||||
|
boolean result = url.equals("file:///android_asset/www/index.html");
|
||||||
|
assertTrue(result);
|
||||||
|
int visible = v.getVisibility();
|
||||||
|
assertTrue(visible == View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBackHistoryFalse() {
|
||||||
|
CordovaWebView v = (CordovaWebView) testView;
|
||||||
|
// Move back in the history
|
||||||
|
boolean test = v.backHistory();
|
||||||
|
assertFalse(test);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure that we can go back
|
||||||
|
public void testBackHistoryTrue() {
|
||||||
|
this.testLoadUrl();
|
||||||
|
CordovaWebView v = (CordovaWebView) testView;
|
||||||
|
v.loadUrlIntoView("file:///android_asset/www/compass/index.html");
|
||||||
|
sleep();
|
||||||
|
String url = v.getUrl();
|
||||||
|
assertTrue(url.equals("file:///android_asset/www/compass/index.html"));
|
||||||
|
// Move back in the history
|
||||||
|
boolean test = v.backHistory();
|
||||||
|
assertTrue(test);
|
||||||
|
sleep();
|
||||||
|
url = v.getUrl();
|
||||||
|
assertTrue(url.equals("file:///android_asset/www/index.html"));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
private void sleep() {
|
||||||
|
try {
|
||||||
|
Thread.sleep(TIMEOUT);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
fail("Unexpected Timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
|
import org.apache.cordova.api.IPlugin;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
public class CordovaWebViewTestActivity extends Activity implements CordovaInterface {
|
||||||
|
|
||||||
|
CordovaWebView phoneGap;
|
||||||
|
|
||||||
|
/** Called when the activity is first created. */
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setContentView(R.layout.main);
|
||||||
|
|
||||||
|
phoneGap = (CordovaWebView) findViewById(R.id.phoneGapView);
|
||||||
|
|
||||||
|
phoneGap.loadUrl("file:///android_asset/www/index.html");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDestroy()
|
||||||
|
{
|
||||||
|
super.onDestroy();
|
||||||
|
if (phoneGap.pluginManager != null) {
|
||||||
|
phoneGap.pluginManager.onDestroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startActivityForResult(IPlugin command, Intent intent, int requestCode) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setActivityResultCallback(IPlugin plugin) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bindBackButton(boolean override) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBackButtonBound() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Activity getActivity() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelLoadUrl() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object onMessage(String id, Object data) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
54
test/src/org/apache/cordova/test/ErrorUrlTest.java
Normal file
54
test/src/org/apache/cordova/test/ErrorUrlTest.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
public class ErrorUrlTest extends ActivityInstrumentationTestCase2<errorurl> {
|
||||||
|
|
||||||
|
private int TIMEOUT = 1000;
|
||||||
|
errorurl testActivity;
|
||||||
|
private FrameLayout containerView;
|
||||||
|
private LinearLayout innerContainer;
|
||||||
|
private CordovaWebView testView;
|
||||||
|
|
||||||
|
public ErrorUrlTest() {
|
||||||
|
super("org.apache.cordova.test",errorurl.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
testActivity = this.getActivity();
|
||||||
|
containerView = (FrameLayout) testActivity.findViewById(android.R.id.content);
|
||||||
|
innerContainer = (LinearLayout) containerView.getChildAt(0);
|
||||||
|
testView = (CordovaWebView) innerContainer.getChildAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPreconditions(){
|
||||||
|
assertNotNull(innerContainer);
|
||||||
|
assertNotNull(testView);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUrl()
|
||||||
|
{
|
||||||
|
sleep();
|
||||||
|
String good_url = "file:///android_asset/www/htmlnotfound/error.html";
|
||||||
|
String url = testView.getUrl();
|
||||||
|
assertNotNull(url);
|
||||||
|
assertTrue(url.equals(good_url));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void sleep() {
|
||||||
|
try {
|
||||||
|
Thread.sleep(TIMEOUT);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
fail("Unexpected Timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
67
test/src/org/apache/cordova/test/GapClientTest.java
Normal file
67
test/src/org/apache/cordova/test/GapClientTest.java
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import org.apache.cordova.CordovaChromeClient;
|
||||||
|
import org.apache.cordova.api.PluginManager;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
public class GapClientTest extends ActivityInstrumentationTestCase2<CordovaWebViewTestActivity> {
|
||||||
|
|
||||||
|
private CordovaWebViewTestActivity testActivity;
|
||||||
|
private FrameLayout containerView;
|
||||||
|
private LinearLayout innerContainer;
|
||||||
|
private View testView;
|
||||||
|
private String rString;
|
||||||
|
private CordovaChromeClient appCode;
|
||||||
|
|
||||||
|
public GapClientTest() {
|
||||||
|
super("com.phonegap.test.activities",CordovaWebViewTestActivity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setUp() throws Exception{
|
||||||
|
super.setUp();
|
||||||
|
testActivity = this.getActivity();
|
||||||
|
containerView = (FrameLayout) testActivity.findViewById(android.R.id.content);
|
||||||
|
innerContainer = (LinearLayout) containerView.getChildAt(0);
|
||||||
|
testView = innerContainer.getChildAt(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPreconditions(){
|
||||||
|
assertNotNull(innerContainer);
|
||||||
|
assertNotNull(testView);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testForCordovaView() {
|
||||||
|
String className = testView.getClass().getSimpleName();
|
||||||
|
assertTrue(className.equals("CordovaWebView"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
52
test/src/org/apache/cordova/test/HtmlNotFoundTest.java
Normal file
52
test/src/org/apache/cordova/test/HtmlNotFoundTest.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
public class HtmlNotFoundTest extends ActivityInstrumentationTestCase2<htmlnotfound> {
|
||||||
|
|
||||||
|
private int TIMEOUT = 1000;
|
||||||
|
private htmlnotfound testActivity;
|
||||||
|
private FrameLayout containerView;
|
||||||
|
private LinearLayout innerContainer;
|
||||||
|
private CordovaWebView testView;
|
||||||
|
|
||||||
|
public HtmlNotFoundTest() {
|
||||||
|
super("org.apache.cordova.test",htmlnotfound.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
testActivity = this.getActivity();
|
||||||
|
containerView = (FrameLayout) testActivity.findViewById(android.R.id.content);
|
||||||
|
innerContainer = (LinearLayout) containerView.getChildAt(0);
|
||||||
|
testView = (CordovaWebView) innerContainer.getChildAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPreconditions(){
|
||||||
|
assertNotNull(innerContainer);
|
||||||
|
assertNotNull(testView);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUrl()
|
||||||
|
{
|
||||||
|
sleep();
|
||||||
|
String good_url = "file:///android_asset/www/htmlnotfound/error.html";
|
||||||
|
String url = testView.getUrl();
|
||||||
|
assertNotNull(url);
|
||||||
|
assertFalse(url.equals(good_url));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sleep() {
|
||||||
|
try {
|
||||||
|
Thread.sleep(TIMEOUT);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
fail("Unexpected Timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
test/src/org/apache/cordova/test/IFrameTest.java
Normal file
11
test/src/org/apache/cordova/test/IFrameTest.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
|
||||||
|
public class IFrameTest extends ActivityInstrumentationTestCase2<iframe> {
|
||||||
|
|
||||||
|
public IFrameTest() {
|
||||||
|
super("org.apache.cordova.test",iframe.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
test/src/org/apache/cordova/test/JQMTabTest.java
Normal file
12
test/src/org/apache/cordova/test/JQMTabTest.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
|
||||||
|
public class JQMTabTest extends ActivityInstrumentationTestCase2<jqmtabbackbutton> {
|
||||||
|
|
||||||
|
public JQMTabTest(Class<jqmtabbackbutton> activityClass) {
|
||||||
|
super(activityClass);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
test/src/org/apache/cordova/test/LifecycleTest.java
Normal file
11
test/src/org/apache/cordova/test/LifecycleTest.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
|
||||||
|
public class LifecycleTest extends ActivityInstrumentationTestCase2<lifecycle> {
|
||||||
|
|
||||||
|
public LifecycleTest()
|
||||||
|
{
|
||||||
|
super("org.apache.cordova.test",lifecycle.class);
|
||||||
|
}
|
||||||
|
}
|
50
test/src/org/apache/cordova/test/LoadTimeoutTest.java
Normal file
50
test/src/org/apache/cordova/test/LoadTimeoutTest.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
public class LoadTimeoutTest extends ActivityInstrumentationTestCase2<loading> {
|
||||||
|
private loading testActivity;
|
||||||
|
private FrameLayout containerView;
|
||||||
|
private LinearLayout innerContainer;
|
||||||
|
private CordovaWebView testView;
|
||||||
|
private long TIMEOUT = 1000;
|
||||||
|
|
||||||
|
public LoadTimeoutTest()
|
||||||
|
{
|
||||||
|
super("org.apache.cordova.test",loading.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
testActivity = this.getActivity();
|
||||||
|
containerView = (FrameLayout) testActivity.findViewById(android.R.id.content);
|
||||||
|
innerContainer = (LinearLayout) containerView.getChildAt(0);
|
||||||
|
testView = (CordovaWebView) innerContainer.getChildAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPreconditions(){
|
||||||
|
assertNotNull(innerContainer);
|
||||||
|
assertNotNull(testView);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUrl()
|
||||||
|
{
|
||||||
|
sleep();
|
||||||
|
String good_url = "http://www.google.com";
|
||||||
|
String url = testView.getUrl();
|
||||||
|
assertNotNull(url);
|
||||||
|
assertFalse(url.equals(good_url));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sleep() {
|
||||||
|
try {
|
||||||
|
Thread.sleep(TIMEOUT );
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
fail("Unexpected Timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
test/src/org/apache/cordova/test/PluginManagerTest.java
Normal file
69
test/src/org/apache/cordova/test/PluginManagerTest.java
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import com.phonegap.api.PluginManager;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
public class PluginManagerTest extends ActivityInstrumentationTestCase2<CordovaWebViewTestActivity> {
|
||||||
|
|
||||||
|
private CordovaWebViewTestActivity testActivity;
|
||||||
|
private FrameLayout containerView;
|
||||||
|
private LinearLayout innerContainer;
|
||||||
|
private View testView;
|
||||||
|
private String rString;
|
||||||
|
private PluginManager pMan;
|
||||||
|
|
||||||
|
public PluginManagerTest() {
|
||||||
|
super("com.phonegap.test.activities",CordovaWebViewTestActivity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setUp() throws Exception{
|
||||||
|
super.setUp();
|
||||||
|
testActivity = this.getActivity();
|
||||||
|
containerView = (FrameLayout) testActivity.findViewById(android.R.id.content);
|
||||||
|
innerContainer = (LinearLayout) containerView.getChildAt(0);
|
||||||
|
testView = innerContainer.getChildAt(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPreconditions(){
|
||||||
|
assertNotNull(innerContainer);
|
||||||
|
assertNotNull(testView);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testForPluginManager() {
|
||||||
|
/*
|
||||||
|
CordovaWebView v = (CordovaWebView) testView;
|
||||||
|
pMan = v.getPluginManager();
|
||||||
|
assertNotNull(pMan);
|
||||||
|
String className = pMan.getClass().getSimpleName();
|
||||||
|
assertTrue(className.equals("PluginManager"));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
27
test/src/org/apache/cordova/test/SplashscreenTest.java
Normal file
27
test/src/org/apache/cordova/test/SplashscreenTest.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
public class SplashscreenTest extends ActivityInstrumentationTestCase2<splashscreen> {
|
||||||
|
|
||||||
|
private splashscreen testActivity;
|
||||||
|
private Dialog containerView;
|
||||||
|
|
||||||
|
public SplashscreenTest()
|
||||||
|
{
|
||||||
|
super("org.apache.cordova.test",splashscreen.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
testActivity = this.getActivity();
|
||||||
|
//containerView = (FrameLayout) testActivity.findViewById(android.R.id.content);
|
||||||
|
//containerView = (Dialog) testActivity.findViewById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
test/src/org/apache/cordova/test/UserWebViewTest.java
Normal file
11
test/src/org/apache/cordova/test/UserWebViewTest.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
|
||||||
|
public class UserWebViewTest extends ActivityInstrumentationTestCase2<userwebview> {
|
||||||
|
|
||||||
|
public UserWebViewTest ()
|
||||||
|
{
|
||||||
|
super(userwebview.class);
|
||||||
|
}
|
||||||
|
}
|
12
test/src/org/apache/cordova/test/WhitelistTest.java
Normal file
12
test/src/org/apache/cordova/test/WhitelistTest.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
|
||||||
|
public class WhitelistTest extends ActivityInstrumentationTestCase2<whitelist> {
|
||||||
|
|
||||||
|
public WhitelistTest()
|
||||||
|
{
|
||||||
|
super(whitelist.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
test/src/org/apache/cordova/test/XhrTest.java
Normal file
11
test/src/org/apache/cordova/test/XhrTest.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
|
||||||
|
public class XhrTest extends ActivityInstrumentationTestCase2<xhr> {
|
||||||
|
|
||||||
|
public XhrTest()
|
||||||
|
{
|
||||||
|
super(xhr.class);
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,6 @@
|
|||||||
package org.apache.cordova.test;
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.webkit.WebView;
|
|
||||||
|
|
||||||
import org.apache.cordova.*;
|
import org.apache.cordova.*;
|
||||||
|
|
||||||
|
40
test/src/org/apache/cordova/test/backgroundcolor.java
Executable file
40
test/src/org/apache/cordova/test/backgroundcolor.java
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import org.apache.cordova.*;
|
||||||
|
|
||||||
|
public class backgroundcolor extends DroidGap {
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// Properties must be set before init() is called, since some are processed during init().
|
||||||
|
|
||||||
|
// backgroundColor can also be set in cordova.xml, but you must use the number equivalent of the color. For example, Color.RED is
|
||||||
|
// <preference name="backgroundColor" value="-65536" />
|
||||||
|
super.setIntegerProperty("backgroundColor", Color.GREEN);
|
||||||
|
|
||||||
|
super.init();
|
||||||
|
super.loadUrl("file:///android_asset/www/backgroundcolor/index.html");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
43
test/src/org/apache/cordova/test/basicauth.java
Executable file
43
test/src/org/apache/cordova/test/basicauth.java
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import org.apache.cordova.*;
|
||||||
|
|
||||||
|
public class basicauth extends DroidGap {
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
// LogCat: onReceivedHttpAuthRequest(browserspy.dk:80,BrowserSpy.dk - HTTP Password Test)
|
||||||
|
AuthenticationToken token = new AuthenticationToken();
|
||||||
|
token.setUserName("test");
|
||||||
|
token.setPassword("test");
|
||||||
|
super.setAuthenticationToken(token, "browserspy.dk:80", "BrowserSpy.dk - HTTP Password Test");
|
||||||
|
|
||||||
|
// Add web site to whitelist
|
||||||
|
super.appView.addWhiteListEntry("http://browserspy.dk*", true);
|
||||||
|
|
||||||
|
// Load test
|
||||||
|
super.loadUrl("file:///android_asset/www/basicauth/index.html");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -29,4 +29,6 @@ public class errorurl extends DroidGap {
|
|||||||
this.setStringProperty("errorUrl", "file:///android_asset/www/htmlnotfound/error.html");
|
this.setStringProperty("errorUrl", "file:///android_asset/www/htmlnotfound/error.html");
|
||||||
super.loadUrl("file:///android_asset/www/htmlnotfound/index.html");
|
super.loadUrl("file:///android_asset/www/htmlnotfound/index.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
39
test/src/org/apache/cordova/test/fullscreen.java
Executable file
39
test/src/org/apache/cordova/test/fullscreen.java
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.cordova.test;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import org.apache.cordova.*;
|
||||||
|
|
||||||
|
public class fullscreen extends DroidGap {
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// Properties must be set before init() is called, since some are processed during init().
|
||||||
|
|
||||||
|
// fullscreen can also be set in cordova.xml. For example,
|
||||||
|
// <preference name="fullscreen" value="true" />
|
||||||
|
super.setBooleanProperty("fullscreen", true);
|
||||||
|
|
||||||
|
super.init();
|
||||||
|
super.loadUrl("file:///android_asset/www/fullscreen/index.html");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -26,7 +26,7 @@ public class tests extends DroidGap {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
super.init();
|
super.init();
|
||||||
super.pluginManager.addService("Activity", "org.apache.cordova.test.ActivityPlugin");
|
//super.pluginManager.addService("Activity", "org.apache.cordova.test.ActivityPlugin");
|
||||||
super.loadUrl("file:///android_asset/www/index.html");
|
super.loadUrl("file:///android_asset/www/index.html");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ public class userwebview extends DroidGap {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
super.init(new WebView(this), new TestViewClient(this), new TestChromeClient(this));
|
super.init(new CordovaWebView(this), new TestViewClient(this), new TestChromeClient(this));
|
||||||
super.loadUrl("file:///android_asset/www/userwebview/index.html");
|
super.loadUrl("file:///android_asset/www/userwebview/index.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ public class whitelist extends DroidGap {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
super.init(new WebView(this), new TestViewClient(this), new CordovaChromeClient(this));
|
super.init(new CordovaWebView(this), new TestViewClient(this), new CordovaChromeClient(this));
|
||||||
super.loadUrl("file:///android_asset/www/whitelist/index.html");
|
super.loadUrl("file:///android_asset/www/whitelist/index.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user