Compare commits

..

76 Commits

Author SHA1 Message Date
macdonst
e5e7c3fad3 Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cordova-android 2012-06-29 15:55:34 -04:00
macdonst
2a8b9ab75e Tagging to 1.9.0 2012-06-29 15:55:03 -04:00
Fil Maj
c8f0ffb42f Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cordova-android 2012-06-29 09:37:59 -07:00
Fil Maj
b3e68b96cf Removing CordovaWebView Guide; its going into the docs 2012-06-29 09:37:31 -07:00
macdonst
ae7a550a09 Only load Exif information if necessary 2012-06-29 11:31:33 -04:00
Anis Kadri
e069bbb800 CB-937 fixing debug for windows 2012-06-28 17:11:21 -07:00
Anis Kadri
17ff6be6a9 CB-937 fixing debug 2012-06-28 17:08:32 -07:00
Anis Kadri
d42489c67a Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cordova-android 2012-06-28 16:47:18 -07:00
macdonst
e2047afa42 Wire rotation fix to correctOrientation parameter 2012-06-28 12:00:19 -04:00
macdonst
231b39d2dc Reset orientation exif information when photo is rotated
When a photo is taken in portrait mode we rotate it so it shows up properly in the webview. The Exif orientation must be reset to normal orientation (0) or the image will not display properly on desktops.
2012-06-28 12:00:19 -04:00
macdonst
dddce30368 Rotate image if taken in portrait mode 2012-06-28 12:00:19 -04:00
macdonst
e0e4ba2bd7 Fix double image problem on Samsung phones
On Samsung phones even if you tell the camera not to save to the photo gallery it still does. This small fix deletes the original file as it is not needed.
2012-06-28 12:00:19 -04:00
macdonst
e0eadb6b76 Using a better scaling algorithm to resize the image
Instead of reading the entire image into a bitmap then scaling we use the
inSampleSize option to get a close to the target width and height as possible
then we scale that smaller image.
2012-06-28 12:00:19 -04:00
macdonst
483e5dfbea Switch getPicture from Gallery to use file instead of content resolver 2012-06-28 12:00:18 -04:00
macdonst
8aa9d8213d Cache bust returned Image URI if saveToPhotoAlbum is false 2012-06-28 12:00:18 -04:00
macdonst
a74f71c935 Decode image from File instead of content resolver 2012-06-28 12:00:18 -04:00
macdonst
87b81e53f0 CB-978: FileTransfer.upload from a directory with a space fails 2012-06-28 11:57:06 -04:00
Joe Bowser
a2816e31c3 Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cordova-android 2012-06-28 08:00:59 -07:00
Joe Bowser
f78af9f27b Forgot to add it renderscript.opt.level to the project. This will fix ant issues 2012-06-28 08:00:35 -07:00
Anis Kadri
98138a0a60 log was actually doing nothing...fixing it 2012-06-27 17:55:35 -07:00
Anis Kadri
e639b6303e updating create script to work from distro and source 2012-06-27 17:54:57 -07:00
Anis Kadri
99fb3ebe00 creating project without source 2012-06-26 17:34:19 -07:00
Joe Bowser
5829840409 Re-adding getContext because yo dawg, I heard you like contexts in your contexts 2012-06-26 11:25:17 -07:00
Anis Kadri
4699ab5500 forgot to add +x on BOOM 2012-06-25 15:03:19 -07:00
Anis Kadri
69fc7f39b7 setting +x on script files 2012-06-25 14:59:35 -07:00
Anis Kadri
510a962a52 deleting old BOOM 2012-06-25 14:56:09 -07:00
Anis Kadri
570fc3cfb2 removing echoes 2012-06-25 14:46:10 -07:00
Joe Bowser
5d211f2fa6 Might as well keep isBackbuttonOverriden on the plugin 2012-06-22 10:38:42 -07:00
Joe Bowser
dcb127c14d Weird merge error didn't account for isBackButtonBound 2012-06-22 10:37:33 -07:00
Fil Maj
fba87de064 Removed some legacy button code that existed in droidgap + app plugins 2012-06-22 10:07:07 -07:00
Anis Kadri
576f8cba44 Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cordova-android 2012-06-21 21:15:59 -07:00
Anis Kadri
b9f9429542 windows build/debug/launch scripts 2012-06-21 21:15:53 -07:00
Joe Bowser
bf0df9f3c3 Since we moved binding of buttons into a view, let's remove it from the Interface 2012-06-21 15:21:56 -07:00
Joe Bowser
1d458f2782 After failed rebase, need to do merge in the branch to fix this 2012-06-21 14:49:19 -07:00
Fil Maj
5ca4b4a884 Refactored cleanup in camera code a bit. Removed overrides for Scanner functionality 2012-06-21 14:22:09 -07:00
Joe Bowser
5935052ead Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cordova-android 2012-06-21 14:04:48 -07:00
Fil Maj
f3f2ad9144 Merging in use of uri variable between Simon and my changes. 2012-06-21 14:03:59 -07:00
Fil Maj
9d1edc4554 Fixed the 0-byte files in gallery. Also fixed exif rewriter for saveToPhotoAlbum:false JPG files. Thanks for your help Simon! 2012-06-21 14:03:59 -07:00
Fil Maj
5143b8a492 added . in front of the temp files passed into camera app. presumably this hsould stop the gallery app from picking it up 2012-06-21 14:03:59 -07:00
Fil Maj
7c67f40fc4 Tacked on file extension to camera file 2012-06-21 14:03:58 -07:00
Fil Maj
167b600135 Removing images and saving images to jail if SaveToPhotoAlbum is set to true 2012-06-21 14:03:58 -07:00
Fil Maj
6c465e25d3 merge!!!!11one 2012-06-21 14:03:58 -07:00
Fil Maj
c183d06ed1 Added MediaScanner abilities to camera launcher plugin. Now images saved to SD card should show up in the android gallery app right away 2012-06-21 14:03:58 -07:00
Joe Bowser
574731b853 Adding updated JS 2012-06-21 14:03:58 -07:00
Fil Maj
94568a4ec8 Merging in use of uri variable between Simon and my changes. 2012-06-21 12:37:44 -07:00
Fil Maj
b22c0e5b6d Fixed the 0-byte files in gallery. Also fixed exif rewriter for saveToPhotoAlbum:false JPG files. Thanks for your help Simon! 2012-06-21 12:09:51 -07:00
Fil Maj
ab3347d25d added . in front of the temp files passed into camera app. presumably this hsould stop the gallery app from picking it up 2012-06-21 12:09:51 -07:00
Fil Maj
66872de8e5 Tacked on file extension to camera file 2012-06-21 12:09:50 -07:00
Fil Maj
f6d4402fdc Removing images and saving images to jail if SaveToPhotoAlbum is set to true 2012-06-21 12:09:50 -07:00
Fil Maj
9f66ccb5f3 merge!!!!11one 2012-06-21 12:09:50 -07:00
Fil Maj
b339330592 Added MediaScanner abilities to camera launcher plugin. Now images saved to SD card should show up in the android gallery app right away 2012-06-21 12:09:50 -07:00
Joe Bowser
56acd2953b Adding updated JS 2012-06-21 11:12:30 -07:00
Anis Kadri
6f8e13297e fixing create 2012-06-20 19:08:18 -07:00
Anis Kadri
e9a9144098 adding windows scripts 2012-06-20 19:07:41 -07:00
Joe Bowser
d1905dbee8 Fixing work-around to work for both ? and # 2012-06-20 14:16:02 -07:00
Joe Bowser
adc88f01b7 Attempt to test icecream_workaround from viafirma 2012-06-20 12:45:51 -07:00
macdonst
507554b8e8 Fixing merge error 2012-06-20 12:47:00 -04:00
macdonst
4795133daf CB-919: Camera Plugin returned with empty error message
Instead of guarding against a null cursor we detect if the device is using internal or external storage to save the photos and adjust our DB queries accordingly.
2012-06-20 12:43:37 -04:00
macdonst
c1c9075962 CB-919: Camera Plugin returned with empty error message
Guarding against null cursor.
2012-06-20 12:20:42 -04:00
macdonst
a691e9f744 CB-910: Camera out of memory error
Whenever possible do not load the image into a Bitmap as it takes too much memory and blows up the Java heap.
2012-06-20 11:00:13 -04:00
macdonst
8969eed506 Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cordova-android 2012-06-19 20:22:30 -04:00
Anis Kadri
be83095edf updating windows create.js and creating node test 2012-06-19 20:21:45 -04:00
macdonst
5c7783305a CB-883: SplashScreen without show() method, only hide() 2012-06-19 20:21:13 -04:00
Anis Kadri
d60806bfa6 Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cordova-android 2012-06-19 16:28:11 -07:00
Anis Kadri
32febcb892 updating windows create.js and creating node test 2012-06-19 16:28:00 -07:00
macdonst
6c594b6f5f Fixing merge error in FileUtils.notifyDelete 2012-06-19 11:29:00 -04:00
Joe Bowser
67d46432ed Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cordova-android 2012-06-18 16:01:19 -07:00
Joe Bowser
adf4166caa Incrementing version to 1.9.0rc1 and doing some variable cleanup 2012-06-18 16:00:42 -07:00
Anis Kadri
aa45670d87 Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-cordova-android 2012-06-15 18:38:56 -07:00
Anis Kadri
e6d801a594 adding appinfo 2012-06-15 18:38:46 -07:00
Anis Kadri
0aec2be4dd updating bash create script and node test 2012-06-15 18:36:06 -07:00
Anis Kadri
c86b618aaa adding bash helper scripts 2012-06-15 18:35:34 -07:00
Juan G. Hurtado
dffd2deb53 Merge branch 'icecream_workaround' of github.com:viafirma/incubator-cordova-android into icecream_workaround 2012-05-18 08:49:26 +02:00
Juan G. Hurtado
8ff48b371e Fix imports for changes in 45680a5
Commit 45680a5 had errors importing packages. This commit fix them.
2012-05-18 08:48:08 +02:00
Juan G. Hurtado
6de66b87cb Add Android 4.0 workaround for links with params
Android 4.0.x has a known bug [1] while accessing local files with
params:

file://file.html?param=2

This commit adds a workaround for this problem by removing the params
part of the local URI before accessing the file.

[1] http://code.google.com/p/android/issues/detail?id=17535
2012-05-18 08:48:07 +02:00
Juan G. Hurtado
45680a562e Add Android 4.0 workaround for links with params
Android 4.0.x has a known bug [1] while accessing local files with
params:

file://file.html?param=2

This commit adds a workaround for this problem by removing the params
part of the local URI before accessing the file.

[1] http://code.google.com/p/android/issues/detail?id=17535
2012-05-16 08:42:50 +02:00
52 changed files with 1241 additions and 593 deletions

View File

@@ -1 +1 @@
1.9.0rc1
1.9.0

View File

@@ -1,21 +0,0 @@
#! /bin/sh
# 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.
#
#
./bin/create
cd ./example && ./cordova/debug && ./cordova/log

View File

@@ -46,11 +46,16 @@ fi
# cleanup after exit and/or on error
function on_exit {
echo "Cleaning up ..."
# [ -f $BUILD_PATH/framework/libs/commons-codec-1.6.jar ] && rm $BUILD_PATH/framework/libs/commons-codec-1.6.jar
# [ -d $BUILD_PATH/framework/libs ] && rmdir $BUILD_PATH/framework/libs
[ -f $BUILD_PATH/framework/assets/www/cordova-$VERSION.js ] && rm $BUILD_PATH/framework/assets/www/cordova-$VERSION.js
[ -f $BUILD_PATH/framework/cordova-$VERSION.jar ] && rm $BUILD_PATH/framework/cordova-$VERSION.jar
if [ -f $BUILD_PATH/framework/assets/www/cordova-$VERSION.js ]
then
rm $BUILD_PATH/framework/assets/www/cordova-$VERSION.js
fi
if [ -f $BUILD_PATH/framework/cordova-$VERSION.jar ]
then
rm $BUILD_PATH/framework/cordova-$VERSION.jar
fi
}
function on_error {
@@ -69,43 +74,47 @@ MANIFEST_PATH=$PROJECT_PATH/AndroidManifest.xml
TARGET=$($ANDROID_BIN list targets | grep id: | tail -1 | cut -f 2 -d ' ' )
# if this a distribution release no need to build a jar
if [ ! -e $BUILD_PATH/cordova-$VERSION.jar ] && [ -d $BUILD_PATH/framework ]
then
# update the cordova-android framework for the desired target
$ANDROID_BIN update project --target $TARGET --path $BUILD_PATH/framework &> /dev/null
$ANDROID_BIN update project --target $TARGET --path $BUILD_PATH/framework &> /dev/null
if [ ! -e $BUILD_PATH/framework/libs/commons-codec-1.6.jar ]; then
# Use curl to get the jar (TODO: Support Apache Mirrors)
echo "Downloading common-codecs-1.6 ..."
curl -OL http://mirror.symnds.com/software/Apache//commons/codec/binaries/commons-codec-1.6-bin.zip &> /dev/null
unzip commons-codec-1.6-bin.zip &> /dev/null
mkdir -p $BUILD_PATH/framework/libs
cp commons-codec-1.6/commons-codec-1.6.jar $BUILD_PATH/framework/libs
# cleanup yo
rm commons-codec-1.6-bin.zip && rm -rf commons-codec-1.6
fi
if [ ! -e $BUILD_PATH/framework/libs/commons-codec-1.6.jar ]; then
# Use curl to get the jar (TODO: Support Apache Mirrors)
curl -OL http://mirror.symnds.com/software/Apache//commons/codec/binaries/commons-codec-1.6-bin.zip &> /dev/null
unzip commons-codec-1.6-bin.zip &> /dev/null
mkdir -p $BUILD_PATH/framework/libs
cp commons-codec-1.6/commons-codec-1.6.jar $BUILD_PATH/framework/libs
# cleanup yo
rm commons-codec-1.6-bin.zip && rm -rf commons-codec-1.6
fi
# compile cordova.js and cordova.jar
echo "Building cordova-$VERSION.jar and cordova-$VERSION.js ..."
(cd $BUILD_PATH/framework && ant jar &> /dev/null )
(cd $BUILD_PATH/framework && ant jar &> /dev/null )
fi
# create new android project
echo "Creating a new cordova android project ..."
$ANDROID_BIN create project --target $TARGET --path $PROJECT_PATH --package $PACKAGE --activity $ACTIVITY &> /dev/null
# copy project template
echo "Copying assets and resources ..."
cp -r $BUILD_PATH/bin/templates/project/assets $PROJECT_PATH
cp -r $BUILD_PATH/bin/templates/project/res $PROJECT_PATH
# copy cordova.js, cordova.jar and res/xml
echo "Setting up config and plugins list ..."
cp -r $BUILD_PATH/framework/res/xml $PROJECT_PATH/res
echo "Adding cordova-$VERSION.js and cordova-$VERSION.jar ..."
cp $BUILD_PATH/framework/assets/www/cordova-$VERSION.js $PROJECT_PATH/assets/www/cordova-$VERSION.js
cp $BUILD_PATH/framework/cordova-$VERSION.jar $PROJECT_PATH/libs/cordova-$VERSION.jar
if [ -d $BUILD_PATH/framework ]
then
cp -r $BUILD_PATH/framework/res/xml $PROJECT_PATH/res
cp $BUILD_PATH/framework/assets/www/cordova-$VERSION.js $PROJECT_PATH/assets/www/cordova-$VERSION.js
cp $BUILD_PATH/framework/cordova-$VERSION.jar $PROJECT_PATH/libs/cordova-$VERSION.jar
else
cp -r $BUILD_PATH/xml $PROJECT_PATH/res/xml
cp $BUILD_PATH/cordova-$VERSION.js $PROJECT_PATH/assets/www/cordova-$VERSION.js
cp $BUILD_PATH/cordova-$VERSION.jar $PROJECT_PATH/libs/cordova-$VERSION.jar
fi
# interpolate the activity name and package
echo "Updating Activity and AndroidManifest ..."
cp $BUILD_PATH/bin/templates/project/Activity.java $ACTIVITY_PATH
sed -i '' -e "s/__ACTIVITY__/${ACTIVITY}/g" $ACTIVITY_PATH
sed -i '' -e "s/__ID__/${PACKAGE}/g" $ACTIVITY_PATH
@@ -113,3 +122,13 @@ sed -i '' -e "s/__ID__/${PACKAGE}/g" $ACTIVITY_PATH
cp $BUILD_PATH/bin/templates/project/AndroidManifest.xml $MANIFEST_PATH
sed -i '' -e "s/__ACTIVITY__/${ACTIVITY}/g" $MANIFEST_PATH
sed -i '' -e "s/__PACKAGE__/${PACKAGE}/g" $MANIFEST_PATH
# creating cordova folder and copying emulate/debug/log/launch scripts
mkdir $PROJECT_PATH/cordova
cp $BUILD_PATH/bin/templates/cordova/appinfo.jar $PROJECT_PATH/cordova/appinfo.jar
cp $BUILD_PATH/bin/templates/cordova/cordova $PROJECT_PATH/cordova/cordova
cp $BUILD_PATH/bin/templates/cordova/debug $PROJECT_PATH/cordova/debug
cp $BUILD_PATH/bin/templates/cordova/clean $PROJECT_PATH/cordova/clean
cp $BUILD_PATH/bin/templates/cordova/log $PROJECT_PATH/cordova/log
cp $BUILD_PATH/bin/templates/cordova/emulate $PROJECT_PATH/cordova/emulate
cp $BUILD_PATH/bin/templates/cordova/BOOM $PROJECT_PATH/cordova/BOOM

View File

@@ -33,6 +33,10 @@ function read(filename) {
f.Close();
return s;
}
function setTarget() {
var targets = shell.Exec('android.bat list targets').StdOut.ReadAll().match(/id:\s\d+/g);
return targets[targets.length - 1].replace(/id: /, ""); // TODO: give users the option to set their target
}
function write(filename, contents) {
var fso=WScript.CreateObject("Scripting.FileSystemObject");
var f=fso.OpenTextFile(filename, 2, true);
@@ -42,12 +46,11 @@ function write(filename, contents) {
function replaceInFile(filename, regexp, replacement) {
write(filename, read(filename).replace(regexp, replacement));
}
function exec(s, output) {
var o=shell.Exec(s);
while (o.Status == 0) {
WScript.Sleep(100);
function exec(command) {
var oShell=shell.Exec(command);
while (oShell.Status == 0) {
WScript.sleep(100);
}
//WScript.Echo("Command exited with code " + o.Status);
}
function cleanup() {
@@ -125,32 +128,55 @@ if(fso.FolderExists(PROJECT_PATH)) {
var PACKAGE_AS_PATH=PACKAGE.replace(/\./g, '\\');
var ACTIVITY_PATH=PROJECT_PATH+'\\src\\'+PACKAGE_AS_PATH+'\\'+ACTIVITY+'.java';
var MANIFEST_PATH=PROJECT_PATH+'\\AndroidManifest.xml';
var TARGET=shell.Exec('android.bat list targets').StdOut.ReadAll().match(/id:\s([0-9]).*/)[1];
var TARGET=setTarget();
var VERSION=read(ROOT+'\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
// create the project
exec('android.bat create project --target '+TARGET+' --path '+PROJECT_PATH+' --package '+PACKAGE+' --activity '+ACTIVITY);
// update the cordova framework project to a target that exists on this machine
exec('android.bat update project --target '+TARGET+' --path '+ROOT+'\\framework');
// pull down commons codec if necessary
downloadCommonsCodec();
exec('ant.bat -f '+ ROOT +'\\framework\\build.xml jar');
// build from source. distro should have these files
if (!fso.FileExists(ROOT+'\\cordova-'+VERSION+'.jar') &&
!fso.FileExists(ROOT+'\\cordova-'+VERSION+'.js')) {
// update the cordova framework project to a target that exists on this machine
exec('android.bat update project --target '+TARGET+' --path '+ROOT+'\\framework');
// pull down commons codec if necessary
downloadCommonsCodec();
exec('ant.bat -f '+ ROOT +'\\framework\\build.xml jar');
}
// copy in the project template
exec('cmd /c xcopy '+ ROOT + '\\bin\\templates\\project\\* '+PROJECT_PATH+' /S /Y');
exec('%comspec% /c xcopy '+ ROOT + '\\bin\\templates\\project\\res '+PROJECT_PATH+'\\res\\ /E /Y');
exec('%comspec% /c xcopy '+ ROOT + '\\bin\\templates\\project\\assets '+PROJECT_PATH+'\\assets\\ /E /Y');
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\project\\AndroidManifest.xml ' + PROJECT_PATH + '\\AndroidManifest.xml /Y');
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\project\\Activity.java '+ ACTIVITY_PATH +' /Y');
// copy in cordova.js
exec('cmd /c copy '+ROOT+'\\framework\\assets\\www\\cordova-'+VERSION+'.js '+PROJECT_PATH+'\\assets\\www\\cordova-'+VERSION+'.js /Y');
// check if we have the source or the distro files
if(fso.FolderExists(ROOT + '\\framework')) {
exec('%comspec% /c copy '+ROOT+'\\framework\\assets\\www\\cordova-'+VERSION+'.js '+PROJECT_PATH+'\\assets\\www\\cordova-'+VERSION+'.js /Y');
exec('%comspec% /c copy '+ROOT+'\\framework\\cordova-'+VERSION+'.jar '+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar /Y');
fso.CreateFolder(PROJECT_PATH + '\\res\\xml');
exec('%comspec% /c copy '+ROOT+'\\framework\\res\\xml\\cordova.xml ' + PROJECT_PATH + '\\res\\xml\\cordova.xml /Y');
exec('%comspec% /c copy '+ROOT+'\\framework\\res\\xml\\plugins.xml ' + PROJECT_PATH + '\\res\\xml\\plugins.xml /Y');
} else {
// copy in cordova.js
exec('%comspec% /c copy '+ROOT+'\\cordova-'+VERSION+'.js '+PROJECT_PATH+'\\assets\\www\\cordova-'+VERSION+'.js /Y');
// copy in cordova.jar
exec('%comspec% /c copy '+ROOT+'\\cordova-'+VERSION+'.jar '+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar /Y');
// copy in xml
fso.CreateFolder(PROJECT_PATH + '\\res\\xml');
exec('%comspec% /c copy '+ROOT+'\\xml\\cordova.xml ' + PROJECT_PATH + '\\res\\xml\\cordova.xml /Y');
exec('%comspec% /c copy '+ROOT+'\\xml\\plugins.xml ' + PROJECT_PATH + '\\res\\xml\\plugins.xml /Y');
}
// copy in cordova.jar
exec('cmd /c copy '+ROOT+'\\framework\\cordova-'+VERSION+'.jar '+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar /Y');
// copy in xml
exec('cmd /c copy '+ROOT+'\\framework\\res\\xml\\cordova.xml ' + PROJECT_PATH + '\\res\\xml\\cordova.xml /Y');
exec('cmd /c copy '+ROOT+'\\framework\\res\\xml\\plugins.xml ' + PROJECT_PATH + '\\res\\xml\\plugins.xml /Y');
// copy cordova scripts
fso.CreateFolder(PROJECT_PATH + '\\cordova');
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\appinfo.jar ' + PROJECT_PATH + '\\cordova\\appinfo.jar /Y');
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\cordova.js ' + PROJECT_PATH + '\\cordova\\cordova.js /Y');
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\cordova.bat ' + PROJECT_PATH + '\\cordova\\cordova.bat /Y');
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\clean.bat ' + PROJECT_PATH + '\\cordova\\clean.bat /Y');
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\debug.bat ' + PROJECT_PATH + '\\cordova\\debug.bat /Y');
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\log.bat ' + PROJECT_PATH + '\\cordova\\log.bat /Y');
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\emulate.bat ' + PROJECT_PATH + '\\cordova\\emulate.bat /Y');
exec('%comspec% /c copy '+ROOT+'\\bin\\templates\\cordova\\BOOM.bat ' + PROJECT_PATH + '\\cordova\\BOOM.bat /Y');
// interpolate the activity name and package
replaceInFile(ACTIVITY_PATH, /__ACTIVITY__/, ACTIVITY);

View File

@@ -0,0 +1,44 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import java.io.IOException;
public class ApplicationInfo {
private static void parseAndroidManifest(String path) {
// System.out.println(path);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document dom;
try {
DocumentBuilder db = dbf.newDocumentBuilder();
dom = db.parse(path);
// getting package information
Element manifest = dom.getDocumentElement();
String pakkage = manifest.getAttribute("package");
// getting activity name
String activity = ((Element)dom.getElementsByTagName("activity").item(0)).getAttribute("android:name");
System.out.println(String.format("%s/.%s", pakkage, activity.replace(".", "")));
} catch(ParserConfigurationException pce) {
pce.printStackTrace();
} catch(SAXException se) {
se.printStackTrace();
} catch(IOException ioe) {
ioe.printStackTrace();
}
}
public static void main(String[] args) {
String path;
if(args.length > 0) {
path = args[0];
} else {
path = System.getProperty("user.dir") + "/../AndroidManifest.xml";
}
parseAndroidManifest(path);
}
}

7
bin/templates/cordova/BOOM Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
set -e
CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd )
bash $CORDOVA_PATH/cordova BOOM

View File

@@ -0,0 +1 @@
%~dp0\cordova.bat BOOM

Binary file not shown.

7
bin/templates/cordova/clean Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
set -e
CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd )
bash $CORDOVA_PATH/cordova clean

View File

@@ -0,0 +1 @@
%~dp0\cordova.bat clean

85
bin/templates/cordova/cordova Executable file
View File

@@ -0,0 +1,85 @@
#!/bin/bash
set -e
PROJECT_PATH=$( cd "$( dirname "$0" )/.." && pwd )
function check_devices {
local devices=`adb devices | awk '/List of devices attached/ { while(getline > 0) { print }}'`
if [ -z "$devices" ] ; then
echo "1"
else
echo "0"
fi
}
function emulate {
declare -a avd_list=($(android list avd | grep "Name:" | cut -f 2 -d ":" | xargs))
# we need to start adb-server
adb start-server 1>/dev/null
# Do not launch an emulator if there is already one running or if a device is attached
if [ $(check_devices) == 0 ] ; then
echo "Device attached or emulator already running"
return
fi
local avd_id="1000" #FIXME: hopefully user does not have 1000 AVDs
# User has no AVDs
if [ ${#avd_list[@]} == 0 ]
then
echo "You don't have any Android Virtual Devices. Please create at least one AVD."
echo "android"
fi
# User has only one AVD
if [ ${#avd_list[@]} == 1 ]
then
emulator -cpu-delay 0 -no-boot-anim -cache /tmp/cache -avd ${avd_list[0]} 1> /dev/null 2>&1 &
# User has more than 1 AVD
elif [ ${#avd_list[@]} -gt 1 ]
then
while [ -z ${avd_list[$avd_id]} ]
do
echo "Choose from one of the following Android Virtual Devices [0 to $((${#avd_list[@]}-1))]:"
for(( i = 0 ; i < ${#avd_list[@]} ; i++ ))
do
echo "$i) ${avd_list[$i]}"
done
echo -n "> "
read avd_id
done
emulator -cpu-delay 0 -no-boot-anim -cache /tmp/cache -avd ${avd_list[$avd_id]} 1> /dev/null 2>&1 &
fi
}
function clean {
ant clean
}
# has to be used independently and not in conjuction with other commands
function log {
adb logcat
}
function debug {
if [ $(check_devices) == 0 ] ; then
ant debug install
else
ant debug
echo "##################################################################"
echo "# Plug in your device or launch an emulator with cordova/emulate #"
echo "##################################################################"
fi
}
function launch {
local launch_str=$(java -jar $PROJECT_PATH/cordova/appinfo.jar $PROJECT_PATH/AndroidManifest.xml)
adb shell am start -n $launch_str
}
function BOOM {
clean && debug && launch
}
# TODO parse arguments
(cd $PROJECT_PATH && $1)

View File

@@ -0,0 +1,15 @@
@ECHO OFF
IF NOT DEFINED JAVA_HOME GOTO MISSING
FOR %%X in (java.exe ant.bat android.bat) do (
SET FOUND=%%~$PATH:X
IF NOT DEFINED FOUND GOTO MISSING
)
cscript %~dp0\cordova.js %*
GOTO END
:MISSING
ECHO Missing one of the following:
ECHO JDK: http://java.oracle.com
ECHO Android SDK: http://developer.android.com
ECHO Apache ant: http://ant.apache.org
EXIT /B 1
:END

104
bin/templates/cordova/cordova.js vendored Normal file
View File

@@ -0,0 +1,104 @@
var ROOT = WScript.ScriptFullName.split('\\cordova\\cordova.js').join(''),
shell=WScript.CreateObject("WScript.Shell");
function exec(command) {
var oExec=shell.Exec(command);
var output = new String();
while(oExec.Status == 0) {
if(!oExec.StdOut.AtEndOfStream) {
var line = oExec.StdOut.ReadLine();
// XXX: Change to verbose mode
// WScript.StdOut.WriteLine(line);
output += line;
}
WScript.sleep(100);
}
return output;
}
function emulator_running() {
var local_devices = shell.Exec("%comspec% /c adb devices").StdOut.ReadAll();
if(local_devices.match(/emulator/)) {
return true;
}
return false;
}
function emulate() {
// don't run emulator if a device is plugged in or if emulator is already running
if(emulator_running()) {
WScript.Echo("Device or Emulator already running!");
return;
}
var oExec = shell.Exec("%comspec% /c android.bat list avd");
var avd_list = [];
var avd_id = -10;
while(!oExec.StdOut.AtEndOfStream) {
var output = oExec.StdOut.ReadLine();
if(output.match(/Name: (.)*/)) {
avd_list.push(output.replace(/ *Name:\s/, ""));
}
}
// user has no AVDs
if(avd_list.length == 0) {
WScript.Echo("You don't have any Android Virtual Devices. Please create at least one AVD.");
WScript.Echo("android");
WScript.Quit(1);
}
// user has only one AVD so we launch that one
if(avd_list.length == 1) {
shell.Run("emulator -cpu-delay 0 -no-boot-anim -cache %Temp%\cache -avd "+avd_list[0]);
}
// user has more than one avd so we ask them to choose
if(avd_list.length > 1) {
while(!avd_list[avd_id]) {
WScript.Echo("Choose from one of the following Android Virtual Devices [0 to "+(avd_list.length - 1)+"]:")
for(i = 0, j = avd_list.length ; i < j ; i++) {
WScript.Echo((i)+") "+avd_list[i]);
}
WScript.StdOut.Write("> ");
avd_id = new Number(WScript.StdIn.ReadLine());
}
shell.Run("emulator -cpu-delay 0 -no-boot-anim -cache %Temp%\\cache -avd "+avd_list[avd_id], 0, false);
}
}
function clean() {
exec("%comspec% /c ant.bat clean -f "+ROOT+"\\build.xml 2>&1");
}
function debug() {
if(emulator_running()) {
exec("%comspec% /c ant.bat debug install -f "+ROOT+"\\build.xml 2>&1");
} else {
exec("%comspec% /c ant.bat debug -f "+ROOT+"\\build.xml 2>&1");
WScript.Echo("##################################################################");
WScript.Echo("# Plug in your device or launch an emulator with cordova/emulate #");
WScript.Echo("##################################################################");
}
}
function log() {
shell.Run("%comspec% /c adb logcat");
}
function launch() {
var launch_str=exec("%comspec% /c java -jar "+ROOT+"\\cordova\\appinfo.jar "+ROOT+"\\AndroidManifest.xml");
//WScript.Echo(launch_str);
exec("%comspec% /c adb shell am start -n "+launch_str+" 2>&1");
}
function BOOM() {
clean();
debug();
launch();
}
var args = WScript.Arguments;
if(args.count() != 1) {
WScript.StdErr.Write("An error has occured!\n");
WScript.Quit(1);
}
eval(args(0)+"()");

7
bin/templates/cordova/debug Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
set -e
CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd )
bash $CORDOVA_PATH/cordova debug

View File

@@ -0,0 +1 @@
%~dp0\cordova.bat debug

7
bin/templates/cordova/emulate Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
set -e
CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd )
bash $CORDOVA_PATH/cordova emulate

View File

@@ -0,0 +1 @@
%~dp0\cordova.bat emulate

7
bin/templates/cordova/log Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
set -e
PROJECT_PATH=$( cd "$( dirname "$0" )/.." && pwd )
bash $PROJECT_PATH/cordova/cordova log

View File

@@ -0,0 +1 @@
%~dp0\cordova.bat log

View File

@@ -23,7 +23,7 @@
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>PhoneGap</title>
<link rel="stylesheet" href="master.css" type="text/css" media="screen" title="no title">
<script type="text/javascript" charset="utf-8" src="cordova-1.8.0.js"></script>
<script type="text/javascript" charset="utf-8" src="cordova-1.9.0.js"></script>
<script type="text/javascript" charset="utf-8" src="main.js"></script>
</head>

View File

@@ -80,6 +80,41 @@ create_project.on('exit', function(code) {
path.exists(util.format('%s/assets/www/cordova-%s.js', project_path, version), function(exists) {
assert(exists, 'cordova.js did not get added');
});
// make sure cordova master script was added
path.exists(util.format('%s/cordova/cordova', project_path), function(exists) {
assert(exists, 'cordova script did not get added');
});
// make sure debug script was added
path.exists(util.format('%s/cordova/debug', project_path), function(exists) {
assert(exists, 'debug script did not get added');
});
// make sure BOOM script was added
path.exists(util.format('%s/cordova/BOOM', project_path), function(exists) {
assert(exists, 'BOOM script did not get added');
});
// make sure log script was added
path.exists(util.format('%s/cordova/log', project_path), function(exists) {
assert(exists, 'log script did not get added');
});
// make sure clean script was added
path.exists(util.format('%s/cordova/clean', project_path), function(exists) {
assert(exists, 'clean script did not get added');
});
// make sure emulate script was added
path.exists(util.format('%s/cordova/emulate', project_path), function(exists) {
assert(exists, 'emulate script did not get added');
});
// make sure appinfo.jar script was added
path.exists(util.format('%s/cordova/appinfo.jar', project_path), function(exists) {
assert(exists, 'appinfo.jar script did not get added');
});
// check that project compiles && creates a cordovaExample-debug.apk
var compile_project = spawn('ant', ['debug'], {cwd: project_path});

View File

@@ -0,0 +1,143 @@
var build_path = __dirname + '/../..'
project_path = process.env.Temp + '\\example',
package_name = 'org.apache.cordova.example',
package_as_path = 'org/apache/cordova/example',
project_name = 'cordovaExample';
var path = require('path'),
fs = require('fs'),
util = require('util'),
assert = require('assert'),
exec = require('child_process').exec,
spawn = require('child_process').spawn;
var version = fs.readFileSync(build_path + '/VERSION').toString().replace('\r\n', '');
assert(version !== undefined);
assert(version !== '');
process.on('uncaughtException', function (err) {
console.log('Caught exception: ' + err);
exec('rd /s /q ' + project_path);
});
var create_project = spawn('cscript',
[build_path + '/bin/create.js',
project_path,
package_name,
project_name]
);
create_project.stderr.on('data', function (data) {
console.log('ps stderr: ' + data);
});
create_project.stderr.on('data', function(data) {
console.log(data.toString());
});
create_project.stdout.on('data', function(data) {
console.log(data.toString());
});
create_project.on('exit', function(code) {
assert.equal(code, 0, 'Project did not get created');
// make sure the project was created
path.exists(project_path, function(exists) {
assert(exists, 'Project path does not exist');
});
// make sure the build directory was cleaned up
// path.exists(build_path + '/framework/libs', function(exists) {
// assert(!exists, 'libs directory did not get cleaned up');
// });
path.exists(build_path + util.format('/framework/assets/cordova-%s.js', version), function(exists) {
assert(!exists, 'javascript file did not get cleaned up');
});
path.exists(build_path + util.format('/framework/cordova-%s.jar', version), function(exists) {
assert(!exists, 'jar file did not get cleaned up');
});
// make sure AndroidManifest.xml was added
path.exists(util.format('%s/AndroidManifest.xml', project_path), function(exists) {
assert(exists, 'AndroidManifest.xml did not get created');
// TODO check that the activity name was properly substituted
});
// make sure main Activity was added
path.exists(util.format('%s/src/%s/%s.java', project_path, package_as_path, project_name), function(exists) {
assert(exists, 'Activity did not get created');
// TODO check that package name and activity name were substitued properly
});
// make sure plugins.xml was added
path.exists(util.format('%s/res/xml/plugins.xml', project_path), function(exists) {
assert(exists, 'plugins.xml did not get created');
});
// make sure cordova.xml was added
path.exists(util.format('%s/res/xml/cordova.xml', project_path), function(exists) {
assert(exists, 'plugins.xml did not get created');
});
// make sure cordova.jar was added
path.exists(util.format('%s/libs/cordova-%s.jar', project_path, version), function(exists) {
assert(exists, 'cordova.jar did not get added');
});
// make sure cordova.js was added
path.exists(util.format('%s/assets/www/cordova-%s.js', project_path, version), function(exists) {
assert(exists, 'cordova.js did not get added');
});
// make sure cordova master script was added
path.exists(util.format('%s/cordova/cordova.bat', project_path), function(exists) {
assert(exists, 'cordova script did not get added');
});
// make sure debug script was added
path.exists(util.format('%s/cordova/debug.bat', project_path), function(exists) {
assert(exists, 'debug script did not get added');
});
// make sure BOOM script was added
path.exists(util.format('%s/cordova/BOOM.bat', project_path), function(exists) {
assert(exists, 'BOOM script did not get added');
});
// make sure log script was added
path.exists(util.format('%s/cordova/log.bat', project_path), function(exists) {
assert(exists, 'log script did not get added');
});
// make sure clean script was added
path.exists(util.format('%s/cordova/clean.bat', project_path), function(exists) {
assert(exists, 'clean script did not get added');
});
// make sure emulate script was added
path.exists(util.format('%s/cordova/emulate.bat', project_path), function(exists) {
assert(exists, 'emulate script did not get added');
});
// make sure appinfo.jar script was added
path.exists(util.format('%s/cordova/appinfo.jar', project_path), function(exists) {
assert(exists, 'appinfo.jar script did not get added');
});
// check that project compiles && creates a cordovaExample-debug.apk
// XXX: !@##!@# WINDOWS
exec('ant debug -f ' + project_path + "\\build.xml", function(error, stdout, stderr) {
assert(error == null, "Cordova Android Project does not compile");
path.exists(util.format('%s/bin/%s-debug.apk', project_path, project_name),
function(exists) {
assert(exists, 'Package did not get created');
// if project compiles properly just AXE it
exec('rd /s /q ' + project_path);
});
});
});

View File

@@ -1,6 +1,6 @@
// commit 347de1a785b7ecbe86c2189343ab2549a9297f9b
// commit 5647225e12e18e15aefc33b151430d9a3804d9ea
// File generated at :: Fri Jun 08 2012 16:17:50 GMT-0700 (PDT)
// File generated at :: Fri Jun 29 2012 12:32:24 GMT-0400 (EDT)
/*
Licensed to the Apache Software Foundation (ASF) under one
@@ -190,7 +190,9 @@ var cordova = {
fireDocumentEvent: function(type, data) {
var evt = createEvent(type, data);
if (typeof documentEventHandlers[type] != 'undefined') {
documentEventHandlers[type].fire(evt);
setTimeout(function() {
documentEventHandlers[type].fire(evt);
}, 0);
} else {
document.dispatchEvent(evt);
}
@@ -198,7 +200,9 @@ var cordova = {
fireWindowEvent: function(type, data) {
var evt = createEvent(type,data);
if (typeof windowEventHandlers[type] != 'undefined') {
windowEventHandlers[type].fire(evt);
setTimeout(function() {
windowEventHandlers[type].fire(evt);
}, 0);
} else {
window.dispatchEvent(evt);
}
@@ -953,8 +957,7 @@ module.exports = function(success, fail, service, action, args) {
// If a result was returned
if (r.length > 0) {
var v;
eval("v="+r+";");
var v = JSON.parse(r);
// If status is OK, then return value back to caller
if (v.status === cordova.callbackStatus.OK) {
@@ -1067,28 +1070,6 @@ module.exports = {
cordova.addDocumentEventHandler('menubutton');
cordova.addDocumentEventHandler('searchbutton');
function bindButtonChannel(buttonName) {
// generic button bind used for volumeup/volumedown buttons
return cordova.addDocumentEventHandler(buttonName + 'button', {
onSubscribe:function() {
// If we just attached the first handler, let native know we need to override the button.
if (this.numHandlers === 1) {
exec(null, null, "App", "overrideButton", [buttonName, true]);
}
},
onUnsubscribe:function() {
// If we just detached the last handler, let native know we no longer override the volumeup button.
if (this.numHandlers === 0) {
exec(null, null, "App", "overrideButton", [buttonName, false]);
}
}
});
}
// Inject a listener for the volume buttons on the document.
var volumeUpButtonChannel = bindButtonChannel('volumeup');
var volumeDownButtonChannel = bindButtonChannel('volumedown');
// Figure out if we need to shim-in localStorage and WebSQL
// support from the native side.
var storage = require('cordova/plugin/android/storage');
@@ -1308,7 +1289,7 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) {
cameraExport.cleanup = function(successCallback, errorCallback) {
exec(successCallback, errorCallback, "Camera", "cleanup", []);
}
};
module.exports = cameraExport;
});
@@ -2628,7 +2609,8 @@ module.exports = FileSystem;
// file: lib/common/plugin/FileTransfer.js
define("cordova/plugin/FileTransfer", function(require, exports, module) {
var exec = require('cordova/exec');
var exec = require('cordova/exec'),
FileTransferError = require('cordova/plugin/FileTransferError');
/**
* FileTransfer uploads a file to a remote server.
@@ -2647,6 +2629,8 @@ var FileTransfer = function() {};
* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
*/
FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
// sanity parameter checking
if (!filePath || !server) throw new Error("FileTransfer.upload requires filePath and server URL parameters at the minimum.");
// check for options
var fileKey = null;
var fileName = null;
@@ -2668,7 +2652,12 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
}
}
exec(successCallback, errorCallback, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode]);
var fail = function(e) {
var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
errorCallback(error);
};
exec(successCallback, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode]);
};
/**
@@ -2679,6 +2668,8 @@ FileTransfer.prototype.upload = function(filePath, server, successCallback, erro
* @param errorCallback {Function} Callback to be invoked upon error
*/
FileTransfer.prototype.download = function(source, target, successCallback, errorCallback) {
// sanity parameter checking
if (!source || !target) throw new Error("FileTransfer.download requires source URI and target URI parameters at the minimum.");
var win = function(result) {
var entry = null;
if (result.isDirectory) {
@@ -2693,6 +2684,12 @@ FileTransfer.prototype.download = function(source, target, successCallback, erro
entry.fullPath = result.fullPath;
successCallback(entry);
};
var fail = function(e) {
var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
errorCallback(error);
};
exec(win, errorCallback, 'FileTransfer', 'download', [source, target]);
};
@@ -2706,8 +2703,11 @@ define("cordova/plugin/FileTransferError", function(require, exports, module) {
* FileTransferError
* @constructor
*/
var FileTransferError = function(code) {
var FileTransferError = function(code, source, target, status) {
this.code = code || null;
this.source = source || null;
this.target = target || null;
this.http_status = status || null;
};
FileTransferError.FILE_NOT_FOUND_ERR = 1;
@@ -2715,6 +2715,7 @@ FileTransferError.INVALID_URL_ERR = 2;
FileTransferError.CONNECTION_ERR = 3;
module.exports = FileTransferError;
});
// file: lib/common/plugin/FileUploadOptions.js
@@ -3665,21 +3666,6 @@ module.exports = {
exec(null, null, "App", "overrideBackbutton", [override]);
},
/**
* Override the default behavior of the Android volume button.
* If overridden, when the volume button is pressed, the "volume[up|down]button" JavaScript event will be fired.
*
* Note: The user should not have to call this method. Instead, when the user
* registers for the "volume[up|down]button" event, this is automatically done.
*
* @param button volumeup, volumedown
* @param override T=override, F=cancel override
*/
overrideButton:function(button, override) {
exec(null, null, "App", "overrideButton", [button, override]);
},
/**
* Exit and terminate the application.
*/
@@ -5509,6 +5495,9 @@ define("cordova/plugin/splashscreen", function(require, exports, module) {
var exec = require('cordova/exec');
var splashscreen = {
show:function() {
exec(null, null, "SplashScreen", "show", []);
},
hide:function() {
exec(null, null, "SplashScreen", "hide", []);
}

View File

@@ -19,7 +19,7 @@
<html>
<head>
<title></title>
<script src="cordova-1.8.0.js"></script>
<script src="cordova-1.9.0.js"></script>
</head>
<body>

View File

@@ -12,3 +12,4 @@ split.density=false
# Project target.
target=Google Inc.:Google APIs:15
apk-configurations=
renderscript.opt.level=O0

View File

@@ -68,12 +68,12 @@ public class AccelListener extends Plugin implements SensorEventListener {
* Sets the context of the Command. This can then be used to do things like
* get file paths associated with the Activity.
*
* @param ctx The context of the main Activity.
* @param cordova The context of the main Activity.
*/
public void setContext(CordovaInterface ctx) {
super.setContext(ctx);
this.sensorManager = (SensorManager) ctx.getActivity().getSystemService(Context.SENSOR_SERVICE);
public void setContext(CordovaInterface cordova) {
super.setContext(cordova);
this.sensorManager = (SensorManager) cordova.getActivity().getSystemService(Context.SENSOR_SERVICE);
}
/**

View File

@@ -49,7 +49,7 @@ public class App extends Plugin {
this.clearCache();
}
else if (action.equals("show")) { // TODO @bc - Not in master branch. When should this be called?
ctx.getActivity().runOnUiThread(new Runnable() {
cordova.getActivity().runOnUiThread(new Runnable() {
public void run() {
webView.postMessage("spinner", "stop");
}
@@ -73,10 +73,6 @@ public class App extends Plugin {
else if (action.equals("overrideBackbutton")) {
this.overrideBackbutton(args.getBoolean(0));
}
else if (action.equals("isBackbuttonOverridden")) {
boolean b = this.isBackbuttonOverridden();
return new PluginResult(status, b);
}
else if (action.equals("exitApp")) {
this.exitApp();
}
@@ -162,7 +158,7 @@ public class App extends Plugin {
*/
@Deprecated
public void cancelLoadUrl() {
this.ctx.cancelLoadUrl();
this.cordova.cancelLoadUrl();
}
/**
@@ -202,13 +198,14 @@ public class App extends Plugin {
LOG.i("DroidGap", "WARNING: Volume Button Default Behaviour will be overridden. The volume event will be fired!");
webView.bindButton(button, override);
}
/**
* Return whether the Android back button is overridden by the user.
*
* @return boolean
*/
public boolean isBackbuttonOverridden() {
return this.ctx.isBackButtonBound();
return webView.isBackButtonBound();
}
/**

View File

@@ -305,7 +305,7 @@ public class AudioHandler extends Plugin {
*/
@SuppressWarnings("deprecation")
public void setAudioOutputDevice(int output) {
AudioManager audiMgr = (AudioManager) this.ctx.getActivity().getSystemService(Context.AUDIO_SERVICE);
AudioManager audiMgr = (AudioManager) this.cordova.getActivity().getSystemService(Context.AUDIO_SERVICE);
if (output == 2) {
audiMgr.setRouting(AudioManager.MODE_NORMAL, AudioManager.ROUTE_SPEAKER, AudioManager.ROUTE_ALL);
}
@@ -324,7 +324,7 @@ public class AudioHandler extends Plugin {
*/
@SuppressWarnings("deprecation")
public int getAudioOutputDevice() {
AudioManager audiMgr = (AudioManager) this.ctx.getActivity().getSystemService(Context.AUDIO_SERVICE);
AudioManager audiMgr = (AudioManager) this.cordova.getActivity().getSystemService(Context.AUDIO_SERVICE);
if (audiMgr.getRouting(AudioManager.MODE_NORMAL) == AudioManager.ROUTE_EARPIECE) {
return 1;
}

View File

@@ -88,7 +88,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
this.tempFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tmprecording.mp3";
} else {
this.tempFile = "/data/data/" + handler.ctx.getActivity().getPackageName() + "/cache/tmprecording.mp3";
this.tempFile = "/data/data/" + handler.cordova.getActivity().getPackageName() + "/cache/tmprecording.mp3";
}
}
@@ -160,7 +160,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
f.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + file));
} else {
f.renameTo(new File("/data/data/" + handler.ctx.getActivity().getPackageName() + "/cache/" + file));
f.renameTo(new File("/data/data/" + handler.cordova.getActivity().getPackageName() + "/cache/" + file));
}
}
@@ -220,7 +220,7 @@ public class AudioPlayer implements OnCompletionListener, OnPreparedListener, On
else {
if (file.startsWith("/android_asset/")) {
String f = file.substring(15);
android.content.res.AssetFileDescriptor fd = this.handler.ctx.getActivity().getAssets().openFd(f);
android.content.res.AssetFileDescriptor fd = this.handler.cordova.getActivity().getAssets().openFd(f);
this.mPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
}
else {

View File

@@ -73,7 +73,7 @@ public class BatteryListener extends Plugin {
updateBatteryInfo(intent);
}
};
ctx.getActivity().registerReceiver(this.receiver, intentFilter);
cordova.getActivity().registerReceiver(this.receiver, intentFilter);
}
// Don't return any result now, since status results will be sent when events come in from broadcast receiver
@@ -105,7 +105,7 @@ public class BatteryListener extends Plugin {
private void removeBatteryListener() {
if (this.receiver != null) {
try {
this.ctx.getActivity().unregisterReceiver(this.receiver);
this.cordova.getActivity().unregisterReceiver(this.receiver);
this.receiver = null;
} catch (Exception e) {
Log.e(LOG_TAG, "Error unregistering battery receiver: " + e.getMessage(), e);

View File

@@ -20,6 +20,7 @@ package org.apache.cordova;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -39,17 +40,22 @@ import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Bitmap.CompressFormat;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
/**
* This class launches the camera view, allows the user to take a picture, closes the camera view,
* and returns the captured image. When the camera view is closed, the screen displayed before
* the camera view was shown is redisplayed.
*/
public class CameraLauncher extends Plugin {
public class CameraLauncher extends Plugin implements MediaScannerConnectionClient {
private static final int DATA_URL = 0; // Return base64 encoded string
private static final int FILE_URI = 1; // Return file uri (content://media/external/images/media/2 for Android)
@@ -76,10 +82,15 @@ public class CameraLauncher extends Plugin {
private Uri imageUri; // Uri of captured image
private int encodingType; // Type of encoding to use
private int mediaType; // What type of media to retrieve
private boolean saveToPhotoAlbum; // Should the picture be saved to the device's photo album
private boolean correctOrientation; // Should the pictures orientation be corrected
private boolean allowEdit; // Should we allow the user to crop the image
public String callbackId;
private int numPics;
private MediaScannerConnection conn; // Used to update gallery app with newly-written files
//This should never be null!
//private CordovaInterface cordova;
@@ -114,6 +125,7 @@ public class CameraLauncher extends Plugin {
if (action.equals("takePicture")) {
int srcType = CAMERA;
int destType = FILE_URI;
this.saveToPhotoAlbum = false;
this.targetHeight = 0;
this.targetWidth = 0;
this.encodingType = JPEG;
@@ -127,6 +139,9 @@ public class CameraLauncher extends Plugin {
this.targetHeight = args.getInt(4);
this.encodingType = args.getInt(5);
this.mediaType = args.getInt(6);
this.allowEdit = args.getBoolean(7);
this.correctOrientation = args.getBoolean(8);
this.saveToPhotoAlbum = args.getBoolean(9);
if (srcType == CAMERA) {
this.takePicture(destType, encodingType);
@@ -165,19 +180,18 @@ public class CameraLauncher extends Plugin {
*/
public void takePicture(int returnType, int encodingType) {
// Save the number of images currently on disk for later
this.numPics = queryImgDB().getCount();
this.numPics = queryImgDB(whichContentStore()).getCount();
// Display camera
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
// Specify file so that large image is captured and returned
// TODO: What if there isn't any external storage?
File photo = createCaptureFile(encodingType);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
this.imageUri = Uri.fromFile(photo);
if (this.ctx != null) {
this.ctx.startActivityForResult((Plugin) this, intent, (CAMERA + 1) * 16 + returnType + 1);
if (this.cordova != null) {
this.cordova.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");
@@ -192,9 +206,9 @@ public class CameraLauncher extends Plugin {
private File createCaptureFile(int encodingType) {
File photo = null;
if (encodingType == JPEG) {
photo = new File(DirectoryManager.getTempDirectoryPath(this.ctx.getActivity()), "Pic.jpg");
photo = new File(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()), ".Pic.jpg");
} else if (encodingType == PNG) {
photo = new File(DirectoryManager.getTempDirectoryPath(this.ctx.getActivity()), "Pic.png");
photo = new File(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()), ".Pic.png");
} else {
throw new IllegalArgumentException("Invalid Encoding Type: " + encodingType);
}
@@ -228,58 +242,12 @@ public class CameraLauncher extends Plugin {
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
if (this.ctx != null) {
this.ctx.startActivityForResult((Plugin) this, Intent.createChooser(intent,
if (this.cordova != null) {
this.cordova.startActivityForResult((Plugin) this, Intent.createChooser(intent,
new String(title)), (srcType + 1) * 16 + returnType + 1);
}
}
/**
* Scales the bitmap according to the requested size.
*
* @param bitmap The bitmap to scale.
* @return Bitmap A new Bitmap object of the same bitmap after scaling.
*/
public Bitmap scaleBitmap(Bitmap bitmap) {
int newWidth = this.targetWidth;
int newHeight = this.targetHeight;
int origWidth = bitmap.getWidth();
int origHeight = bitmap.getHeight();
// If no new width or height were specified return the original bitmap
if (newWidth <= 0 && newHeight <= 0) {
return bitmap;
}
// Only the width was specified
else if (newWidth > 0 && newHeight <= 0) {
newHeight = (newWidth * origHeight) / origWidth;
}
// only the height was specified
else if (newWidth <= 0 && newHeight > 0) {
newWidth = (newHeight * origWidth) / origHeight;
}
// If the user specified both a positive width and height
// (potentially different aspect ratio) then the width or height is
// scaled so that the image fits while maintaining aspect ratio.
// Alternatively, the specified width and height could have been
// kept and Bitmap.SCALE_TO_FIT specified when scaling, but this
// would result in whitespace in the new image.
else {
double newRatio = newWidth / (double) newHeight;
double origRatio = origWidth / (double) origHeight;
if (origRatio > newRatio) {
newHeight = (newWidth * origHeight) / origWidth;
} else if (origRatio < newRatio) {
newWidth = (newHeight * origWidth) / origHeight;
}
}
Bitmap retval = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
bitmap.recycle();
return retval;
}
/**
* Called when the camera view exits.
*
@@ -295,78 +263,93 @@ public class CameraLauncher extends Plugin {
int destType = (requestCode % 16) - 1;
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(this.ctx.getActivity()) + "/Pic.jpg");
exif.readExifData();
}
} catch (IOException e) {
e.printStackTrace();
}
// If CAMERA
if (srcType == CAMERA) {
// 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.cordova.getActivity()) + "/.Pic.jpg");
exif.readExifData();
rotate = exif.getOrientation();
}
} catch (IOException e) {
e.printStackTrace();
}
// If image available
if (resultCode == Activity.RESULT_OK) {
try {
// Read in bitmap of captured image
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media.getBitmap(this.ctx.getActivity().getContentResolver(), imageUri);
} catch (FileNotFoundException e) {
Uri uri = intent.getData();
android.content.ContentResolver resolver = this.ctx.getActivity().getContentResolver();
bitmap = android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
}
bitmap = scaleBitmap(bitmap);
Bitmap bitmap = null;
// If sending base64 image back
if (destType == DATA_URL) {
bitmap = getScaledBitmap(FileUtils.stripFileProtocol(imageUri.toString()));
if (rotate != 0 && this.correctOrientation) {
bitmap = getRotatedBitmap(rotate, bitmap, exif);
}
this.processPicture(bitmap);
checkForDuplicateImage(DATA_URL);
}
// If sending filename back
else if (destType == FILE_URI) {
// Create entry in media store for image
// (Don't use insertImage() because it uses default compression setting of 50 - no way to change it)
ContentValues values = new ContentValues();
values.put(android.provider.MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
Uri uri = null;
try {
uri = this.ctx.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} catch (UnsupportedOperationException e) {
LOG.d(LOG_TAG, "Can't write to external media storage.");
try {
uri = this.ctx.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
} catch (UnsupportedOperationException ex) {
LOG.d(LOG_TAG, "Can't write to internal media storage.");
this.failPicture("Error capturing image - no media storage found.");
return;
Uri uri;
if (!this.saveToPhotoAlbum) {
uri = Uri.fromFile(new File("/data/data/" + this.cordova.getActivity().getPackageName() + "/", (new File(FileUtils.stripFileProtocol(this.imageUri.toString()))).getName()));
} else {
uri = getUriFromMediaStore();
}
if (uri == null) {
this.failPicture("Error capturing image - no media storage found.");
}
// If all this is true we shouldn't compress the image.
if (this.targetHeight == -1 && this.targetWidth == -1 && this.mQuality == 100 && rotate == 0) {
writeUncompressedImage(uri);
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
} else {
bitmap = getScaledBitmap(FileUtils.stripFileProtocol(imageUri.toString()));
if (rotate != 0 && this.correctOrientation) {
bitmap = getRotatedBitmap(rotate, bitmap, exif);
}
// Add compressed version of captured image to returned media store Uri
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
os.close();
// Restore exif data to file
if (this.encodingType == JPEG) {
String exifPath;
if (this.saveToPhotoAlbum) {
exifPath = FileUtils.getRealPathFromURI(uri, this.cordova);
} else {
exifPath = uri.getPath();
}
exif.createOutFile(exifPath);
exif.writeExifData();
}
}
// Add compressed version of captured image to returned media store Uri
OutputStream os = this.ctx.getActivity().getContentResolver().openOutputStream(uri);
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
os.close();
// Restore exif data to file
if (this.encodingType == JPEG) {
exif.createOutFile(FileUtils.getRealPathFromURI(uri, this.ctx));
exif.writeExifData();
}
// Send Uri back to JavaScript for viewing image
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
if (saveToPhotoAlbum) {
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
} else {
// If you don't want to save the file to the photo album you need to append a timestamp
// to the returned URI to do some cache busting.
this.success(new PluginResult(PluginResult.Status.OK, uri.toString() + "?" + System.currentTimeMillis()), this.callbackId);
}
}
bitmap.recycle();
bitmap = null;
System.gc();
checkForDuplicateImage(FILE_URI);
this.cleanup(FILE_URI, this.imageUri, bitmap);
bitmap = null;
} catch (IOException e) {
e.printStackTrace();
this.failPicture("Error capturing image.");
@@ -388,41 +371,35 @@ public class CameraLauncher extends Plugin {
else if ((srcType == PHOTOLIBRARY) || (srcType == SAVEDPHOTOALBUM)) {
if (resultCode == Activity.RESULT_OK) {
Uri uri = intent.getData();
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
if (this.mediaType != PICTURE) {
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
}
else {
// Get the path to the image. Makes loading so much easier.
String imagePath = FileUtils.getRealPathFromURI(uri, this.cordova);
Bitmap bitmap = getScaledBitmap(imagePath);
// If sending base64 image back
if (destType == DATA_URL) {
try {
Bitmap bitmap = android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
String[] cols = { MediaStore.Images.Media.ORIENTATION };
Cursor cursor = this.ctx.getActivity().getContentResolver().query(intent.getData(),
cols,
null, null, null);
if (cursor != null) {
cursor.moveToPosition(0);
rotate = cursor.getInt(0);
cursor.close();
}
if (rotate != 0) {
Matrix matrix = new Matrix();
matrix.setRotate(rotate);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
bitmap = scaleBitmap(bitmap);
this.processPicture(bitmap);
bitmap.recycle();
bitmap = null;
System.gc();
} catch (FileNotFoundException e) {
e.printStackTrace();
this.failPicture("Error retrieving image.");
String[] cols = { MediaStore.Images.Media.ORIENTATION };
Cursor cursor = this.cordova.getActivity().getContentResolver().query(intent.getData(),
cols,
null, null, null);
if (cursor != null) {
cursor.moveToPosition(0);
rotate = cursor.getInt(0);
cursor.close();
}
if (rotate != 0) {
Matrix matrix = new Matrix();
matrix.setRotate(rotate);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
this.processPicture(bitmap);
}
// If sending filename back
@@ -430,27 +407,32 @@ public class CameraLauncher extends Plugin {
// Do we need to scale the returned file
if (this.targetHeight > 0 && this.targetWidth > 0) {
try {
Bitmap bitmap = android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
bitmap = scaleBitmap(bitmap);
// Create an ExifHelper to save the exif data that is lost during compression
String resizePath = DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()) + "/resize.jpg";
ExifHelper exif = new ExifHelper();
try {
if (this.encodingType == JPEG) {
exif.createInFile(resizePath);
exif.readExifData();
rotate = exif.getOrientation();
}
} catch (IOException e) {
e.printStackTrace();
}
String fileName = DirectoryManager.getTempDirectoryPath(this.ctx.getActivity()) + "/resize.jpg";
OutputStream os = new FileOutputStream(fileName);
OutputStream os = new FileOutputStream(resizePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, this.mQuality, os);
os.close();
// Restore exif data to file
if (this.encodingType == JPEG) {
exif.createOutFile(FileUtils.getRealPathFromURI(uri, this.ctx));
exif.createOutFile(FileUtils.getRealPathFromURI(uri, this.cordova));
exif.writeExifData();
}
bitmap.recycle();
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.
this.success(new PluginResult(PluginResult.Status.OK, ("file://" + fileName + "?" + System.currentTimeMillis())), this.callbackId);
System.gc();
this.success(new PluginResult(PluginResult.Status.OK, ("file://" + resizePath + "?" + System.currentTimeMillis())), this.callbackId);
} catch (Exception e) {
e.printStackTrace();
this.failPicture("Error retrieving image.");
@@ -460,6 +442,9 @@ public class CameraLauncher extends Plugin {
this.success(new PluginResult(PluginResult.Status.OK, uri.toString()), this.callbackId);
}
}
bitmap.recycle();
bitmap = null;
System.gc();
}
}
else if (resultCode == Activity.RESULT_CANCELED) {
@@ -471,20 +456,140 @@ public class CameraLauncher extends Plugin {
}
}
/**
* Figure out if the bitmap should be rotated. For instance if the picture was taken in
* portrait mode
*
* @param rotate
* @param bitmap
* @return rotated bitmap
*/
private Bitmap getRotatedBitmap(int rotate, Bitmap bitmap, ExifHelper exif) {
Matrix matrix = new Matrix();
if (rotate == 180) {
matrix.setRotate(rotate);
} else {
matrix.setRotate(rotate, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
}
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
exif.resetOrientation();
return bitmap;
}
/**
* In the special case where the default width, height and quality are unchanged
* we just write the file out to disk saving the expensive Bitmap.compress function.
*
* @param uri
* @throws FileNotFoundException
* @throws IOException
*/
private void writeUncompressedImage(Uri uri) throws FileNotFoundException,
IOException {
FileInputStream fis = new FileInputStream(FileUtils.stripFileProtocol(imageUri.toString()));
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
byte[] buffer = new byte[4096];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
os.flush();
os.close();
fis.close();
}
/**
* Create entry in media store for image
*
* @return uri
*/
private Uri getUriFromMediaStore() {
ContentValues values = new ContentValues();
values.put(android.provider.MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
Uri uri;
try {
uri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} catch (UnsupportedOperationException e) {
LOG.d(LOG_TAG, "Can't write to external media storage.");
try {
uri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
} catch (UnsupportedOperationException ex) {
LOG.d(LOG_TAG, "Can't write to internal media storage.");
return null;
}
}
return uri;
}
/**
* Return a scaled bitmap based on the target width and height
*
* @param imagePath
* @return
*/
private Bitmap getScaledBitmap(String imagePath) {
// If no new width or height were specified return the original bitmap
if (this.targetWidth <= 0 && this.targetHeight <= 0) {
return BitmapFactory.decodeFile(imagePath);
}
Bitmap unscaledBitmap = decodeFile(imagePath,
this.targetWidth, this.targetHeight);
return Bitmap.createScaledBitmap(unscaledBitmap, this.targetWidth, this.targetHeight, true);
}
public static Bitmap decodeFile(String pathName, int dstWidth, int dstHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth, dstHeight);
return BitmapFactory.decodeFile(pathName, options);
}
public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)dstWidth / (float)dstHeight;
if (srcAspect > dstAspect) {
return srcWidth / dstWidth;
} else {
return srcHeight / dstHeight;
}
}
/**
* Creates a cursor that can be used to determine how many images we have.
*
* @return a cursor
*/
private Cursor queryImgDB() {
return this.ctx.getActivity().getContentResolver().query(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
private Cursor queryImgDB(Uri contentStore) {
return this.cordova.getActivity().getContentResolver().query(
contentStore,
new String[] { MediaStore.Images.Media._ID },
null,
null,
null);
}
/**
* Cleans up after picture taking. Checking for duplicates and that kind of stuff.
*/
private void cleanup(int imageType, Uri oldImage, Bitmap bitmap) {
if (bitmap != null) {
bitmap.recycle();
}
// Clean up initial camera-written image file.
(new File(FileUtils.stripFileProtocol(oldImage.toString()))).delete();
checkForDuplicateImage(imageType);
// Scan for the gallery to update pic refs in gallery
this.scanForGallery();
System.gc();
}
/**
* Used to find out if we are in a situation where the Camera Intent adds to images
* to the content store. If we are using a FILE_URI and the number of images in the DB
@@ -494,10 +599,11 @@ public class CameraLauncher extends Plugin {
*/
private void checkForDuplicateImage(int type) {
int diff = 1;
Cursor cursor = queryImgDB();
Uri contentStore = whichContentStore();
Cursor cursor = queryImgDB(contentStore);
int currentNumOfImages = cursor.getCount();
if (type == FILE_URI) {
if (type == FILE_URI && this.saveToPhotoAlbum) {
diff = 2;
}
@@ -505,8 +611,20 @@ public class CameraLauncher extends Plugin {
if ((currentNumOfImages - numPics) == diff) {
cursor.moveToLast();
int id = Integer.valueOf(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media._ID))) - 1;
Uri uri = Uri.parse(MediaStore.Images.Media.EXTERNAL_CONTENT_URI + "/" + id);
this.ctx.getActivity().getContentResolver().delete(uri, null, null);
Uri uri = Uri.parse(contentStore + "/" + id);
this.cordova.getActivity().getContentResolver().delete(uri, null, null);
}
}
/**
* Determine if we are storing the images in internal or external storage
* @return Uri
*/
private Uri whichContentStore() {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
return android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else {
return android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI;
}
}
@@ -541,4 +659,24 @@ public class CameraLauncher extends Plugin {
public void failPicture(String err) {
this.error(new PluginResult(PluginResult.Status.ERROR, err), this.callbackId);
}
private void scanForGallery() {
if(this.conn!=null) this.conn.disconnect();
this.conn = new MediaScannerConnection(this.ctx.getActivity().getApplicationContext(), this);
conn.connect();
}
public void onMediaScannerConnected() {
try{
this.conn.scanFile(this.imageUri.toString(), "image/*");
} catch (java.lang.IllegalStateException e){
e.printStackTrace();
LOG.d(LOG_TAG, "Can;t scan file in MediaScanner aftering taking picture");
}
}
public void onScanCompleted(String path, Uri uri) {
this.conn.disconnect();
}
}

View File

@@ -19,6 +19,7 @@
package org.apache.cordova;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -32,10 +33,12 @@ import org.json.JSONObject;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.graphics.Bitmap;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
public class Capture extends Plugin {
@@ -61,6 +64,7 @@ public class Capture extends Plugin {
private double duration; // optional duration parameter for video recording
private JSONArray results; // The array of results to be returned to the user
private Uri imageUri; // Uri of captured image
private int numPics; // Number of pictures before capture activity
//private CordovaInterface cordova;
@@ -195,21 +199,24 @@ public class Capture extends Plugin {
private void captureAudio() {
Intent intent = new Intent(android.provider.MediaStore.Audio.Media.RECORD_SOUND_ACTION);
this.ctx.startActivityForResult((Plugin) this, intent, CAPTURE_AUDIO);
this.cordova.startActivityForResult((Plugin) this, intent, CAPTURE_AUDIO);
}
/**
* Sets up an intent to capture images. Result handled by onActivityResult()
*/
private void captureImage() {
// Save the number of images currently on disk for later
this.numPics = queryImgDB(whichContentStore()).getCount();
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
// Specify file so that large image is captured and returned
File photo = new File(DirectoryManager.getTempDirectoryPath(this.ctx.getActivity()), "Capture.jpg");
File photo = new File(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()), "Capture.jpg");
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
this.imageUri = Uri.fromFile(photo);
this.ctx.startActivityForResult((Plugin) this, intent, CAPTURE_IMAGE);
this.cordova.startActivityForResult((Plugin) this, intent, CAPTURE_IMAGE);
}
/**
@@ -220,7 +227,7 @@ public class Capture extends Plugin {
// Introduced in API 8
//intent.putExtra(android.provider.MediaStore.EXTRA_DURATION_LIMIT, duration);
this.ctx.startActivityForResult((Plugin) this, intent, CAPTURE_VIDEO);
this.cordova.startActivityForResult((Plugin) this, intent, CAPTURE_VIDEO);
}
/**
@@ -256,48 +263,39 @@ public class Capture extends Plugin {
// It crashes in the emulator and on my phone with a null pointer exception
// To work around it I had to grab the code from CameraLauncher.java
try {
// Create an ExifHelper to save the exif data that is lost during compression
ExifHelper exif = new ExifHelper();
exif.createInFile(DirectoryManager.getTempDirectoryPath(this.ctx.getActivity()) + "/Capture.jpg");
exif.readExifData();
// Read in bitmap of captured image
Bitmap bitmap = android.provider.MediaStore.Images.Media.getBitmap(this.ctx.getActivity().getContentResolver(), imageUri);
// Create entry in media store for image
// (Don't use insertImage() because it uses default compression setting of 50 - no way to change it)
ContentValues values = new ContentValues();
values.put(android.provider.MediaStore.Images.Media.MIME_TYPE, IMAGE_JPEG);
Uri uri = null;
try {
uri = this.ctx.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
uri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} catch (UnsupportedOperationException e) {
LOG.d(LOG_TAG, "Can't write to external media storage.");
try {
uri = this.ctx.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
uri = this.cordova.getActivity().getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
} catch (UnsupportedOperationException ex) {
LOG.d(LOG_TAG, "Can't write to internal media storage.");
this.fail(createErrorObject(CAPTURE_INTERNAL_ERR, "Error capturing image - no media storage found."));
return;
}
}
// Add compressed version of captured image to returned media store Uri
OutputStream os = this.ctx.getActivity().getContentResolver().openOutputStream(uri);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
FileInputStream fis = new FileInputStream(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()) + "/Capture.jpg");
OutputStream os = this.cordova.getActivity().getContentResolver().openOutputStream(uri);
byte[] buffer = new byte[4096];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
os.flush();
os.close();
bitmap.recycle();
bitmap = null;
System.gc();
// Restore exif data to file
exif.createOutFile(FileUtils.getRealPathFromURI(uri, this.ctx));
exif.writeExifData();
fis.close();
// Add image to results
results.put(createMediaFile(uri));
checkForDuplicateImage();
if (results.length() >= limit) {
// Send Uri back to JavaScript for viewing image
this.success(new PluginResult(PluginResult.Status.OK, results), this.callbackId);
@@ -356,7 +354,7 @@ public class Capture extends Plugin {
* @throws IOException
*/
private JSONObject createMediaFile(Uri data) {
File fp = new File(FileUtils.getRealPathFromURI(data, this.ctx));
File fp = new File(FileUtils.getRealPathFromURI(data, this.cordova));
JSONObject obj = new JSONObject();
try {
@@ -405,4 +403,49 @@ public class Capture extends Plugin {
public void fail(JSONObject err) {
this.error(new PluginResult(PluginResult.Status.ERROR, err), this.callbackId);
}
/**
* Creates a cursor that can be used to determine how many images we have.
*
* @return a cursor
*/
private Cursor queryImgDB(Uri contentStore) {
return this.cordova.getActivity().getContentResolver().query(
contentStore,
new String[] { MediaStore.Images.Media._ID },
null,
null,
null);
}
/**
* Used to find out if we are in a situation where the Camera Intent adds to images
* to the content store.
*/
private void checkForDuplicateImage() {
Uri contentStore = whichContentStore();
Cursor cursor = queryImgDB(contentStore);
int currentNumOfImages = cursor.getCount();
// delete the duplicate file if the difference is 2
if ((currentNumOfImages - numPics) == 2) {
cursor.moveToLast();
int id = Integer.valueOf(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media._ID))) - 1;
Uri uri = Uri.parse(contentStore + "/" + id);
this.cordova.getActivity().getContentResolver().delete(uri, null, null);
}
}
/**
* Determine if we are storing the images in internal or external storage
* @return Uri
*/
private Uri whichContentStore() {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
return android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else {
return android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI;
}
}
}

View File

@@ -67,11 +67,11 @@ public class CompassListener extends Plugin implements SensorEventListener {
* Sets the context of the Command. This can then be used to do things like
* get file paths associated with the Activity.
*
* @param ctx The context of the main Activity.
* @param cordova The context of the main Activity.
*/
public void setContext(CordovaInterface ctx) {
super.setContext(ctx);
this.sensorManager = (SensorManager) ctx.getActivity().getSystemService(Context.SENSOR_SERVICE);
public void setContext(CordovaInterface cordova) {
super.setContext(cordova);
this.sensorManager = (SensorManager) cordova.getActivity().getSystemService(Context.SENSOR_SERVICE);
}
/**

View File

@@ -69,7 +69,7 @@ public class ContactManager extends Plugin {
* older phones.
*/
if (this.contactAccessor == null) {
this.contactAccessor = new ContactAccessorSdk5(this.webView, this.ctx);
this.contactAccessor = new ContactAccessorSdk5(this.webView, this.cordova);
}
try {

View File

@@ -45,16 +45,16 @@ public class CordovaChromeClient extends WebChromeClient {
private String TAG = "CordovaLog";
private long MAX_QUOTA = 100 * 1024 * 1024;
private CordovaInterface ctx;
private CordovaInterface cordova;
private CordovaWebView appView;
/**
* Constructor.
*
* @param ctx
* @param cordova
*/
public CordovaChromeClient(CordovaInterface ctx) {
this.ctx = ctx;
public CordovaChromeClient(CordovaInterface cordova) {
this.cordova = cordova;
}
/**
@@ -64,7 +64,7 @@ public class CordovaChromeClient extends WebChromeClient {
* @param app
*/
public CordovaChromeClient(CordovaInterface ctx, CordovaWebView app) {
this.ctx = ctx;
this.cordova = ctx;
this.appView = app;
}
@@ -87,7 +87,7 @@ public class CordovaChromeClient extends WebChromeClient {
*/
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
AlertDialog.Builder dlg = new AlertDialog.Builder(this.ctx.getActivity());
AlertDialog.Builder dlg = new AlertDialog.Builder(this.cordova.getActivity());
dlg.setMessage(message);
dlg.setTitle("Alert");
//Don't let alerts break the back button
@@ -131,7 +131,7 @@ public class CordovaChromeClient extends WebChromeClient {
*/
@Override
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
AlertDialog.Builder dlg = new AlertDialog.Builder(this.ctx.getActivity());
AlertDialog.Builder dlg = new AlertDialog.Builder(this.cordova.getActivity());
dlg.setMessage(message);
dlg.setTitle("Confirm");
dlg.setCancelable(true);
@@ -243,9 +243,9 @@ public class CordovaChromeClient extends WebChromeClient {
// Show dialog
else {
final JsPromptResult res = result;
AlertDialog.Builder dlg = new AlertDialog.Builder(this.ctx.getActivity());
AlertDialog.Builder dlg = new AlertDialog.Builder(this.cordova.getActivity());
dlg.setMessage(message);
final EditText input = new EditText(this.ctx.getActivity());
final EditText input = new EditText(this.cordova.getActivity());
if (defaultValue != null) {
input.setText(defaultValue);
}

View File

@@ -54,18 +54,18 @@ public class CordovaWebView extends WebView {
private HashMap<String, Boolean> whiteListCache = new HashMap<String, Boolean>();
private ArrayList<Integer> keyDownCodes = new ArrayList<Integer>();
private ArrayList<Integer> keyUpCodes = new ArrayList<Integer>();
public PluginManager pluginManager;
public CallbackServer callbackServer;
/** Actvities and other important classes **/
private CordovaInterface mCtx;
private CordovaInterface cordova;
CordovaWebViewClient viewClient;
@SuppressWarnings("unused")
private CordovaChromeClient chromeClient;
//This is for the polyfil history
//This is for the polyfil history
private String url;
String baseUrl;
private Stack<String> urls = new Stack<String>();
@@ -83,14 +83,14 @@ public class CordovaWebView extends WebView {
/**
* Constructor.
*
*
* @param context
*/
public CordovaWebView(Context context) {
super(context);
if (CordovaInterface.class.isInstance(context))
{
this.mCtx = (CordovaInterface) context;
this.cordova = (CordovaInterface) context;
}
else
{
@@ -102,7 +102,7 @@ public class CordovaWebView extends WebView {
/**
* Constructor.
*
*
* @param context
* @param attrs
*/
@@ -110,45 +110,45 @@ public class CordovaWebView extends WebView {
super(context, attrs);
if (CordovaInterface.class.isInstance(context))
{
this.mCtx = (CordovaInterface) context;
this.cordova = (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.setWebChromeClient(new CordovaChromeClient(this.cordova, this));
this.setWebViewClient(new CordovaWebViewClient(this.cordova, 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;
this.cordova = (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.setWebChromeClient(new CordovaChromeClient(this.cordova, this));
this.setWebViewClient(new CordovaWebViewClient(this.cordova, this));
this.loadConfiguration();
this.setup();
}
/**
* Constructor.
*
*
* @param context
* @param attrs
* @param defStyle
@@ -158,14 +158,14 @@ public class CordovaWebView extends WebView {
super(context, attrs, defStyle, privateBrowsing);
if (CordovaInterface.class.isInstance(context))
{
this.mCtx = (CordovaInterface) context;
this.cordova = (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.setWebChromeClient(new CordovaChromeClient(this.cordova));
this.setWebViewClient(new CordovaWebViewClient(this.cordova));
this.loadConfiguration();
this.setup();
}
@@ -191,7 +191,7 @@ public class CordovaWebView extends WebView {
// Enable database
settings.setDatabaseEnabled(true);
String databasePath = this.mCtx.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
String databasePath = this.cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
settings.setDatabasePath(databasePath);
// Enable DOM storage
@@ -202,7 +202,7 @@ public class CordovaWebView extends WebView {
//Start up the plugin manager
try {
this.pluginManager = new PluginManager(this, this.mCtx);
this.pluginManager = new PluginManager(this, this.cordova);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -211,7 +211,7 @@ public class CordovaWebView extends WebView {
/**
* Set the WebViewClient.
*
*
* @param client
*/
public void setWebViewClient(CordovaWebViewClient client) {
@@ -221,7 +221,7 @@ public class CordovaWebView extends WebView {
/**
* Set the WebChromeClient.
*
*
* @param client
*/
public void setWebChromeClient(CordovaChromeClient client) {
@@ -231,7 +231,7 @@ public class CordovaWebView extends WebView {
/**
* Add entry to approved list of URLs (whitelist)
*
*
* @param origin URL regular expression to allow
* @param subdomains T=include all subdomains under origin
*/
@@ -269,7 +269,7 @@ public class CordovaWebView extends WebView {
/**
* Determine if URL is in approved list of URLs to load.
*
*
* @param url
* @return
*/
@@ -297,7 +297,7 @@ public class CordovaWebView extends WebView {
/**
* Load the url into the webview.
*
*
* @param url
*/
@Override
@@ -323,7 +323,7 @@ public class CordovaWebView extends WebView {
/**
* 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
*/
@@ -342,7 +342,7 @@ public class CordovaWebView extends WebView {
/**
* Load the url into the webview.
*
*
* @param url
*/
public void loadUrlIntoView(final String url) {
@@ -394,13 +394,13 @@ public class CordovaWebView extends WebView {
// If timeout, then stop loading and handle error
if (me.loadUrlTimeout == currentLoadUrlTimeout) {
me.mCtx.getActivity().runOnUiThread(loadError);
me.cordova.getActivity().runOnUiThread(loadError);
}
}
};
// Load url
this.mCtx.getActivity().runOnUiThread(new Runnable() {
this.cordova.getActivity().runOnUiThread(new Runnable() {
public void run() {
Thread thread = new Thread(timeoutCheck);
thread.start();
@@ -411,7 +411,7 @@ public class CordovaWebView extends WebView {
/**
* Load URL in webview.
*
*
* @param url
*/
private void loadUrlNow(String url) {
@@ -422,7 +422,7 @@ public class CordovaWebView extends WebView {
/**
* 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
*/
@@ -449,7 +449,7 @@ public class CordovaWebView extends WebView {
/**
* Send JavaScript statement back to JavaScript.
* (This is a convenience method)
*
*
* @param message
*/
public void sendJavascript(String statement) {
@@ -459,8 +459,8 @@ public class CordovaWebView extends WebView {
}
/**
* Send a message to all plugins.
*
* Send a message to all plugins.
*
* @param id The message id
* @param data The message data
*/
@@ -470,8 +470,8 @@ public class CordovaWebView extends WebView {
}
}
/**
* Returns the top url on the stack without removing it from
/**
* Returns the top url on the stack without removing it from
* the stack.
*/
public String peekAtUrlStack() {
@@ -483,7 +483,7 @@ public class CordovaWebView extends WebView {
/**
* Add a url to the stack
*
*
* @param url
*/
public void pushUrl(String url) {
@@ -492,7 +492,7 @@ public class CordovaWebView extends WebView {
/**
* 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() {
@@ -517,7 +517,7 @@ public class CordovaWebView extends WebView {
/**
* Return true if there is a history item.
*
*
* @return
*/
public boolean canGoBack() {
@@ -532,7 +532,7 @@ public class CordovaWebView extends WebView {
/**
* 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.
@@ -569,7 +569,7 @@ public class CordovaWebView extends WebView {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
mCtx.getActivity().startActivity(intent);
cordova.getActivity().startActivity(intent);
} catch (android.content.ActivityNotFoundException e) {
LOG.e(TAG, "Error loading url " + url, e);
}
@@ -581,7 +581,7 @@ public class CordovaWebView extends WebView {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
mCtx.getActivity().startActivity(intent);
cordova.getActivity().startActivity(intent);
} catch (android.content.ActivityNotFoundException e) {
LOG.e(TAG, "Error loading url " + url, e);
}
@@ -596,7 +596,7 @@ public class CordovaWebView extends WebView {
* <log level="DEBUG" />
*/
private void loadConfiguration() {
int id = getResources().getIdentifier("cordova", "xml", this.mCtx.getActivity().getPackageName());
int id = getResources().getIdentifier("cordova", "xml", this.cordova.getActivity().getPackageName());
if (id == 0) {
LOG.i("CordovaLog", "cordova.xml missing. Ignoring...");
return;
@@ -625,9 +625,10 @@ public class CordovaWebView extends WebView {
String value = xml.getAttributeValue(null, "value");
LOG.i("CordovaLog", "Found preference for %s=%s", name, value);
Log.d("CordovaLog", "Found preference for " + name + "=" + value);
// Save preferences in Intent
this.mCtx.getActivity().getIntent().putExtra(name, value);
this.cordova.getActivity().getIntent().putExtra(name, value);
}
}
try {
@@ -640,7 +641,7 @@ public class CordovaWebView extends WebView {
}
// Init preferences
if ("true".equals(this.getProperty("useBrowserHistory", "true"))) {
if ("true".equals(this.getProperty("useBrowserHistory", "false"))) {
this.useBrowserHistory = true;
}
else {
@@ -648,20 +649,20 @@ public class CordovaWebView extends WebView {
}
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);
this.cordova.getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
this.cordova.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();
Bundle bundle = this.cordova.getActivity().getIntent().getExtras();
if (bundle == null) {
return defaultValue;
}
@@ -671,11 +672,11 @@ public class CordovaWebView extends WebView {
}
return p.toString();
}
/*
* onKeyDown
* onKeyDown
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
@@ -700,11 +701,11 @@ public class CordovaWebView extends WebView {
}
return false;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
Log.d(TAG, "KeyDown has been triggered on the view");
// If back key
@@ -719,7 +720,7 @@ public class CordovaWebView extends WebView {
if (this.backHistory()) {
return true;
}
// If not, then invoke default behaviour
// If not, then invoke default behaviour
else {
//this.activityState = ACTIVITY_EXITING;
return false;
@@ -741,16 +742,16 @@ public class CordovaWebView extends WebView {
//What the hell should this do?
}
Log.d(TAG, "KeyUp has been triggered on the view");
return false;
}
public void bindButton(boolean override)
{
this.bound = override;
}
public void bindButton(String button, boolean override) {
// TODO Auto-generated method stub
if (button.compareTo("volumeup")==0) {
@@ -760,7 +761,7 @@ public class CordovaWebView extends WebView {
keyDownCodes.add(KeyEvent.KEYCODE_VOLUME_DOWN);
}
}
public void bindButton(int keyCode, boolean keyDown, boolean override) {
if(keyDown)
{
@@ -771,4 +772,9 @@ public class CordovaWebView extends WebView {
keyUpCodes.add(keyCode);
}
}
public boolean isBackButtonBound()
{
return this.bound;
}
}

View File

@@ -21,20 +21,26 @@ package org.apache.cordova;
import java.util.Hashtable;
import org.apache.cordova.api.CordovaInterface;
import java.io.IOException;
import java.io.InputStream;
import org.apache.cordova.api.LOG;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.view.View;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
@@ -44,7 +50,7 @@ import android.webkit.WebViewClient;
public class CordovaWebViewClient extends WebViewClient {
private static final String TAG = "Cordova";
CordovaInterface ctx;
CordovaInterface cordova;
CordovaWebView appView;
private boolean doClearHistory = false;
@@ -54,20 +60,20 @@ public class CordovaWebViewClient extends WebViewClient {
/**
* Constructor.
*
* @param ctx
* @param cordova
*/
public CordovaWebViewClient(CordovaInterface ctx) {
this.ctx = ctx;
public CordovaWebViewClient(CordovaInterface cordova) {
this.cordova = cordova;
}
/**
* Constructor.
*
* @param ctx
* @param cordova
* @param view
*/
public CordovaWebViewClient(CordovaInterface ctx, CordovaWebView view) {
this.ctx = ctx;
public CordovaWebViewClient(CordovaInterface cordova, CordovaWebView view) {
this.cordova = cordova;
this.appView = view;
}
@@ -100,7 +106,7 @@ public class CordovaWebViewClient extends WebViewClient {
try {
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse(url));
this.ctx.getActivity().startActivity(intent);
this.cordova.getActivity().startActivity(intent);
} catch (android.content.ActivityNotFoundException e) {
LOG.e(TAG, "Error dialing " + url + ": " + e.toString());
}
@@ -111,7 +117,7 @@ public class CordovaWebViewClient extends WebViewClient {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
this.ctx.getActivity().startActivity(intent);
this.cordova.getActivity().startActivity(intent);
} catch (android.content.ActivityNotFoundException e) {
LOG.e(TAG, "Error showing map " + url + ": " + e.toString());
}
@@ -122,7 +128,7 @@ public class CordovaWebViewClient extends WebViewClient {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
this.ctx.getActivity().startActivity(intent);
this.cordova.getActivity().startActivity(intent);
} catch (android.content.ActivityNotFoundException e) {
LOG.e(TAG, "Error sending email " + url + ": " + e.toString());
}
@@ -154,7 +160,7 @@ public class CordovaWebViewClient extends WebViewClient {
intent.setData(Uri.parse("sms:" + address));
intent.putExtra("address", address);
intent.setType("vnd.android-dir/mms-sms");
this.ctx.getActivity().startActivity(intent);
this.cordova.getActivity().startActivity(intent);
} catch (android.content.ActivityNotFoundException e) {
LOG.e(TAG, "Error sending sms " + url + ":" + e.toString());
}
@@ -178,7 +184,7 @@ public class CordovaWebViewClient extends WebViewClient {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
this.ctx.getActivity().startActivity(intent);
this.cordova.getActivity().startActivity(intent);
} catch (android.content.ActivityNotFoundException e) {
LOG.e(TAG, "Error loading url " + url, e);
}
@@ -241,6 +247,7 @@ public class CordovaWebViewClient extends WebViewClient {
* 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 url The url of the page.
*/
@@ -280,7 +287,7 @@ public class CordovaWebViewClient extends WebViewClient {
public void run() {
try {
Thread.sleep(2000);
ctx.getActivity().runOnUiThread(new Runnable() {
cordova.getActivity().runOnUiThread(new Runnable() {
public void run() {
appView.postMessage("spinner", "stop");
}
@@ -342,8 +349,9 @@ public class CordovaWebViewClient extends WebViewClient {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
final String packageName = this.ctx.getActivity().getPackageName();
final PackageManager pm = this.ctx.getActivity().getPackageManager();
final String packageName = this.cordova.getActivity().getPackageName();
final PackageManager pm = this.cordova.getActivity().getPackageManager();
ApplicationInfo appInfo;
try {
appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
@@ -451,4 +459,43 @@ public class CordovaWebViewClient extends WebViewClient {
this.authenticationTokens.clear();
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if(url.contains("?") || url.contains("#")){
return generateWebResourceResponse(url);
} else {
return super.shouldInterceptRequest(view, url);
}
}
private WebResourceResponse generateWebResourceResponse(String url) {
final String ANDROID_ASSET = "file:///android_asset/";
if (url.startsWith(ANDROID_ASSET)) {
String niceUrl = url;
niceUrl = url.replaceFirst(ANDROID_ASSET, "");
if(niceUrl.contains("?")){
niceUrl = niceUrl.split("\\?")[0];
}
else if(niceUrl.contains("#"))
{
niceUrl = niceUrl.split("#")[0];
}
String mimetype = null;
if(niceUrl.endsWith(".html")){
mimetype = "text/html";
}
try {
AssetManager assets = cordova.getActivity().getAssets();
Uri uri = Uri.parse(niceUrl);
InputStream stream = assets.open(uri.getPath(), AssetManager.ACCESS_STREAMING);
WebResourceResponse response = new WebResourceResponse(mimetype, "UTF-8", stream);
return response;
} catch (IOException e) {
LOG.e("generateWebResourceResponse", e.getMessage(), e);
}
}
return null;
}
}

View File

@@ -38,7 +38,7 @@ import android.telephony.TelephonyManager;
public class Device extends Plugin {
public static final String TAG = "Device";
public static String cordovaVersion = "1.8.0"; // Cordova version
public static String cordovaVersion = "1.9.0"; // Cordova version
public static String platform = "Android"; // Device OS
public static String uuid; // Device UUID
@@ -54,10 +54,10 @@ public class Device extends Plugin {
* Sets the context of the Command. This can then be used to do things like
* get file paths associated with the Activity.
*
* @param ctx The context of the main Activity.
* @param cordova The context of the main Activity.
*/
public void setContext(CordovaInterface ctx) {
super.setContext(ctx);
public void setContext(CordovaInterface cordova) {
super.setContext(cordova);
Device.uuid = getUuid();
this.initTelephonyReceiver();
}
@@ -110,7 +110,7 @@ public class Device extends Plugin {
* Unregister receiver.
*/
public void onDestroy() {
this.ctx.getActivity().unregisterReceiver(this.telephonyReceiver);
this.cordova.getActivity().unregisterReceiver(this.telephonyReceiver);
}
//--------------------------------------------------------------------------
@@ -125,7 +125,7 @@ public class Device extends Plugin {
private void initTelephonyReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
//final CordovaInterface myctx = this.ctx;
//final CordovaInterface mycordova = this.cordova;
this.telephonyReceiver = new BroadcastReceiver() {
@Override
@@ -153,7 +153,7 @@ public class Device extends Plugin {
};
// Register the receiver
this.ctx.getActivity().registerReceiver(this.telephonyReceiver, intentFilter);
this.cordova.getActivity().registerReceiver(this.telephonyReceiver, intentFilter);
}
/**
@@ -171,7 +171,7 @@ public class Device extends Plugin {
* @return
*/
public String getUuid() {
String uuid = Settings.Secure.getString(this.ctx.getActivity().getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
String uuid = Settings.Secure.getString(this.cordova.getActivity().getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
return uuid;
}

View File

@@ -138,7 +138,6 @@ public class DroidGap extends Activity implements CordovaInterface {
protected CordovaWebViewClient webViewClient;
protected LinearLayout root;
public boolean bound = false;
protected boolean cancelLoadUrl = false;
protected ProgressDialog spinnerDialog = null;
@@ -181,10 +180,6 @@ public class DroidGap extends Activity implements CordovaInterface {
// when another application (activity) is started.
protected boolean keepRunning = true;
private boolean volumeupBound;
private boolean volumedownBound;
/**
* Sets the authentication token.
*
@@ -260,7 +255,7 @@ public class DroidGap extends Activity implements CordovaInterface {
{
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
}
if(this.getBooleanProperty("setFullscreen", false))
{
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
@@ -786,7 +781,7 @@ public class DroidGap extends Activity implements CordovaInterface {
/**
* Launch an activity for which you would like a result when it finished. When this activity exits,
* Launch an activity for which you would like a result when it finished. When this activity exits,
* your onActivityResult() method will be called.
*
* @param command The command object
@@ -945,27 +940,10 @@ public class DroidGap extends Activity implements CordovaInterface {
* @return
*/
public Context getContext() {
LOG.d(TAG, "This will be deprecated December 2012");
return this.getContext();
}
/**
* Override the backbutton.
*
* @param override
*/
public void bindBackButton(boolean override) {
this.bound = override;
}
/**
* Determine of backbutton is overridden.
*
* @return
*/
public boolean isBackButtonBound() {
return this.bound;
}
/**
* Load the specified URL in the Cordova webview or a new browser instance.
*
@@ -982,16 +960,6 @@ public class DroidGap extends Activity implements CordovaInterface {
}
}
public void bindButton(String button, boolean override) {
// TODO Auto-generated method stub
if (button.compareTo("volumeup")==0) {
this.volumeupBound = override;
}
else if (button.compareTo("volumedown")==0) {
this.volumedownBound = override;
}
}
protected Dialog splashDialog;
/**
@@ -1008,40 +976,46 @@ public class DroidGap extends Activity implements CordovaInterface {
* Shows the splash screen over the full Activity
*/
@SuppressWarnings("deprecation")
protected void showSplashScreen(int time) {
protected void showSplashScreen(final int time) {
final DroidGap that = this;
// Get reference to display
Display display = getWindowManager().getDefaultDisplay();
// Create the layout for the dialog
LinearLayout root = new LinearLayout(this);
root.setMinimumHeight(display.getHeight());
root.setMinimumWidth(display.getWidth());
root.setOrientation(LinearLayout.VERTICAL);
root.setBackgroundColor(this.getIntegerProperty("backgroundColor", Color.BLACK));
root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT, 0.0F));
root.setBackgroundResource(this.splashscreen);
// Create and show the dialog
splashDialog = new Dialog(this, android.R.style.Theme_Translucent_NoTitleBar);
// check to see if the splash screen should be full screen
if ((getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN)
== WindowManager.LayoutParams.FLAG_FULLSCREEN) {
splashDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
splashDialog.setContentView(root);
splashDialog.setCancelable(false);
splashDialog.show();
// Set Runnable to remove splash screen just in case
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
Runnable runnable = new Runnable() {
public void run() {
removeSplashScreen();
// Get reference to display
Display display = getWindowManager().getDefaultDisplay();
// Create the layout for the dialog
LinearLayout root = new LinearLayout(that.getActivity());
root.setMinimumHeight(display.getHeight());
root.setMinimumWidth(display.getWidth());
root.setOrientation(LinearLayout.VERTICAL);
root.setBackgroundColor(that.getIntegerProperty("backgroundColor", Color.BLACK));
root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT, 0.0F));
root.setBackgroundResource(that.splashscreen);
// Create and show the dialog
splashDialog = new Dialog(that, android.R.style.Theme_Translucent_NoTitleBar);
// check to see if the splash screen should be full screen
if ((getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN)
== WindowManager.LayoutParams.FLAG_FULLSCREEN) {
splashDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
splashDialog.setContentView(root);
splashDialog.setCancelable(false);
splashDialog.show();
// Set Runnable to remove splash screen just in case
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
removeSplashScreen();
}
}, time);
}
}, time);
};
this.runOnUiThread(runnable);
}
/**

View File

@@ -162,4 +162,24 @@ public class ExifHelper {
this.outFile.saveAttributes();
}
public int getOrientation() {
int o = Integer.parseInt(this.orientation);
if (o == ExifInterface.ORIENTATION_NORMAL) {
return 0;
} else if (o == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
} else if (o == ExifInterface.ORIENTATION_ROTATE_180) {
return 180;
} else if (o == ExifInterface.ORIENTATION_ROTATE_270) {
return 270;
} else {
return 0;
}
}
public void resetOrientation() {
this.orientation = "" + ExifInterface.ORIENTATION_NORMAL;
}
}

View File

@@ -29,6 +29,7 @@ import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
@@ -73,7 +74,7 @@ public class FileTransfer extends Plugin {
String source = null;
String target = null;
try {
source = args.getString(0);
source = URLDecoder.decode(args.getString(0));
target = args.getString(1);
} catch (JSONException e) {
Log.d(LOG_TAG, "Missing source or target");
@@ -321,7 +322,7 @@ public class FileTransfer extends Plugin {
} catch (Throwable t) {
// Shouldn't happen, but will
JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn);
Log.wtf(LOG_TAG, error.toString(), t);
Log.e(LOG_TAG, error.toString(), t);
return new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
} finally {
if (conn != null) {
@@ -524,7 +525,7 @@ public class FileTransfer extends Plugin {
private InputStream getPathFromUri(String path) throws FileNotFoundException {
if (path.startsWith("content:")) {
Uri uri = Uri.parse(path);
return ctx.getActivity().getContentResolver().openInputStream(uri);
return cordova.getActivity().getContentResolver().openInputStream(uri);
}
else if (path.startsWith("file://")) {
int question = path.indexOf("?");

View File

@@ -223,9 +223,9 @@ public class FileUtils extends Plugin {
*/
private void notifyDelete(String filePath) {
String newFilePath = stripFileProtocol(filePath);
int result = this.ctx.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
int result = this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
MediaStore.Images.Media.DATA + " = ?",
new String[] { filePath });
new String[] { newFilePath });
}
/**
@@ -246,7 +246,7 @@ public class FileUtils extends Plugin {
// Handle the special case where you get an Android content:// uri.
if (decoded.startsWith("content:")) {
Cursor cursor = this.ctx.getActivity().managedQuery(Uri.parse(decoded), new String[] { MediaStore.Images.Media.DATA }, null, null, null);
Cursor cursor = this.cordova.getActivity().managedQuery(Uri.parse(decoded), new String[] { MediaStore.Images.Media.DATA }, null, null, null);
// Note: MediaStore.Images/Audio/Video.Media.DATA is always "_data"
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
@@ -728,9 +728,9 @@ public class FileUtils extends Plugin {
private boolean atRootDirectory(String filePath) {
filePath = stripFileProtocol(filePath);
if (filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + ctx.getActivity().getPackageName() + "/cache") ||
if (filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + cordova.getActivity().getPackageName() + "/cache") ||
filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath()) ||
filePath.equals("/data/data/" + ctx.getActivity().getPackageName())) {
filePath.equals("/data/data/" + cordova.getActivity().getPackageName())) {
return true;
}
return false;
@@ -819,16 +819,16 @@ public class FileUtils extends Plugin {
fs.put("name", "temporary");
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
fp = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
"/Android/data/" + ctx.getActivity().getPackageName() + "/cache/");
"/Android/data/" + cordova.getActivity().getPackageName() + "/cache/");
// Create the cache dir if it doesn't exist.
fp.mkdirs();
fs.put("root", getEntry(Environment.getExternalStorageDirectory().getAbsolutePath() +
"/Android/data/" + ctx.getActivity().getPackageName() + "/cache/"));
"/Android/data/" + cordova.getActivity().getPackageName() + "/cache/"));
} else {
fp = new File("/data/data/" + ctx.getActivity().getPackageName() + "/cache/");
fp = new File("/data/data/" + cordova.getActivity().getPackageName() + "/cache/");
// Create the cache dir if it doesn't exist.
fp.mkdirs();
fs.put("root", getEntry("/data/data/" + ctx.getActivity().getPackageName() + "/cache/"));
fs.put("root", getEntry("/data/data/" + cordova.getActivity().getPackageName() + "/cache/"));
}
}
else if (type == PERSISTENT) {
@@ -836,7 +836,7 @@ public class FileUtils extends Plugin {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
fs.put("root", getEntry(Environment.getExternalStorageDirectory()));
} else {
fs.put("root", getEntry("/data/data/" + ctx.getActivity().getPackageName()));
fs.put("root", getEntry("/data/data/" + cordova.getActivity().getPackageName()));
}
}
else {
@@ -943,7 +943,7 @@ public class FileUtils extends Plugin {
String contentType = null;
if (filename.startsWith("content:")) {
Uri fileUri = Uri.parse(filename);
contentType = this.ctx.getActivity().getContentResolver().getType(fileUri);
contentType = this.cordova.getActivity().getContentResolver().getType(fileUri);
}
else {
contentType = getMimeType(filename);
@@ -1026,7 +1026,7 @@ public class FileUtils extends Plugin {
private InputStream getPathFromUri(String path) throws FileNotFoundException {
if (path.startsWith("content")) {
Uri uri = Uri.parse(path);
return ctx.getActivity().getContentResolver().openInputStream(uri);
return cordova.getActivity().getContentResolver().openInputStream(uri);
}
else {
path = stripFileProtocol(path);
@@ -1038,13 +1038,13 @@ public class FileUtils extends Plugin {
* 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 ctx) the current applicaiton context
* @param cordova) the current applicaiton context
* @return the full path to the file
*/
@SuppressWarnings("deprecation")
protected static String getRealPathFromURI(Uri contentUri, CordovaInterface ctx) {
protected static String getRealPathFromURI(Uri contentUri, CordovaInterface cordova) {
String[] proj = { _DATA };
Cursor cursor = ctx.getActivity().managedQuery(contentUri, proj, null, null, null);
Cursor cursor = cordova.getActivity().managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(_DATA);
cursor.moveToFirst();
return cursor.getString(column_index);

View File

@@ -55,7 +55,7 @@ public class GeoBroker extends Plugin {
*/
public PluginResult execute(String action, JSONArray args, String callbackId) {
if (this.locationManager == null) {
this.locationManager = (LocationManager) this.ctx.getActivity().getSystemService(Context.LOCATION_SERVICE);
this.locationManager = (LocationManager) this.cordova.getActivity().getSystemService(Context.LOCATION_SERVICE);
this.networkListener = new NetworkListener(this.locationManager, this);
this.gpsListener = new GPSListener(this.locationManager, this);
}

View File

@@ -84,11 +84,11 @@ public class NetworkManager extends Plugin {
* Sets the context of the Command. This can then be used to do things like
* get file paths associated with the Activity.
*
* @param ctx The context of the main Activity.
* @param cordova The context of the main Activity.
*/
public void setContext(CordovaInterface ctx) {
super.setContext(ctx);
this.sockMan = (ConnectivityManager) ctx.getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
public void setContext(CordovaInterface cordova) {
super.setContext(cordova);
this.sockMan = (ConnectivityManager) cordova.getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
this.connectionCallbackId = null;
// We need to listen to connectivity events to update navigator.connection
@@ -102,7 +102,7 @@ public class NetworkManager extends Plugin {
updateConnectionInfo((NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO));
}
};
ctx.getActivity().registerReceiver(this.receiver, intentFilter);
cordova.getActivity().registerReceiver(this.receiver, intentFilter);
}
}
@@ -146,7 +146,7 @@ public class NetworkManager extends Plugin {
public void onDestroy() {
if (this.receiver != null) {
try {
this.ctx.getActivity().unregisterReceiver(this.receiver);
this.cordova.getActivity().unregisterReceiver(this.receiver);
} catch (Exception e) {
Log.e(LOG_TAG, "Error unregistering network receiver: " + e.getMessage(), e);
}

View File

@@ -143,7 +143,7 @@ public class Notification extends Plugin {
*/
public void beep(long count) {
Uri ringtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone notification = RingtoneManager.getRingtone(this.ctx.getActivity().getBaseContext(), ringtone);
Ringtone notification = RingtoneManager.getRingtone(this.cordova.getActivity().getBaseContext(), ringtone);
// If phone is not set to silent mode
if (notification != null) {
@@ -171,7 +171,7 @@ public class Notification extends Plugin {
if (time == 0) {
time = 500;
}
Vibrator vibrator = (Vibrator) this.ctx.getActivity().getSystemService(Context.VIBRATOR_SERVICE);
Vibrator vibrator = (Vibrator) this.cordova.getActivity().getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(time);
}
@@ -184,13 +184,13 @@ public class Notification extends Plugin {
*/
public synchronized void alert(final String message, final String title, final String buttonLabel, final String callbackId) {
final CordovaInterface ctx = this.ctx;
final CordovaInterface cordova = this.cordova;
final Notification notification = this;
Runnable runnable = new Runnable() {
public void run() {
AlertDialog.Builder dlg = new AlertDialog.Builder(ctx.getActivity());
AlertDialog.Builder dlg = new AlertDialog.Builder(cordova.getActivity());
dlg.setMessage(message);
dlg.setTitle(title);
dlg.setCancelable(false);
@@ -205,7 +205,7 @@ public class Notification extends Plugin {
dlg.show();
};
};
this.ctx.getActivity().runOnUiThread(runnable);
this.cordova.getActivity().runOnUiThread(runnable);
}
/**
@@ -220,13 +220,13 @@ public class Notification extends Plugin {
*/
public synchronized void confirm(final String message, final String title, String buttonLabels, final String callbackId) {
final CordovaInterface ctx = this.ctx;
final CordovaInterface cordova = this.cordova;
final Notification notification = this;
final String[] fButtons = buttonLabels.split(",");
Runnable runnable = new Runnable() {
public void run() {
AlertDialog.Builder dlg = new AlertDialog.Builder(ctx.getActivity());
AlertDialog.Builder dlg = new AlertDialog.Builder(cordova.getActivity());
dlg.setMessage(message);
dlg.setTitle(title);
dlg.setCancelable(false);
@@ -269,7 +269,7 @@ public class Notification extends Plugin {
dlg.show();
};
};
this.ctx.getActivity().runOnUiThread(runnable);
this.cordova.getActivity().runOnUiThread(runnable);
}
/**
@@ -284,10 +284,10 @@ public class Notification extends Plugin {
this.spinnerDialog = null;
}
final Notification notification = this;
final CordovaInterface ctx = this.ctx;
final CordovaInterface cordova = this.cordova;
Runnable runnable = new Runnable() {
public void run() {
notification.spinnerDialog = ProgressDialog.show(ctx.getActivity(), title, message, true, true,
notification.spinnerDialog = ProgressDialog.show(cordova.getActivity(), title, message, true, true,
new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
notification.spinnerDialog = null;
@@ -295,7 +295,7 @@ public class Notification extends Plugin {
});
}
};
this.ctx.getActivity().runOnUiThread(runnable);
this.cordova.getActivity().runOnUiThread(runnable);
}
/**
@@ -320,10 +320,10 @@ public class Notification extends Plugin {
this.progressDialog = null;
}
final Notification notification = this;
final CordovaInterface ctx = this.ctx;
final CordovaInterface cordova = this.cordova;
Runnable runnable = new Runnable() {
public void run() {
notification.progressDialog = new ProgressDialog(ctx.getActivity());
notification.progressDialog = new ProgressDialog(cordova.getActivity());
notification.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
notification.progressDialog.setTitle(title);
notification.progressDialog.setMessage(message);
@@ -339,7 +339,7 @@ public class Notification extends Plugin {
notification.progressDialog.show();
}
};
this.ctx.getActivity().runOnUiThread(runnable);
this.cordova.getActivity().runOnUiThread(runnable);
}
/**

View File

@@ -31,8 +31,9 @@ public class SplashScreen extends Plugin {
String result = "";
if (action.equals("hide")) {
//((DroidGap)this.ctx).removeSplashScreen();
this.webView.postMessage("splashscreen", "hide");
} else if (action.equals("show")){
this.webView.postMessage("splashscreen", "show");
}
else {
status = PluginResult.Status.INVALID_ACTION;

View File

@@ -141,7 +141,7 @@ public class Storage extends Plugin {
// If no database path, generate from application package
if (this.path == null) {
this.path = this.ctx.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
this.path = this.cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
}
this.dbName = this.path + File.pathSeparator + db + ".db";

View File

@@ -46,11 +46,11 @@ public class TempListener extends Plugin implements SensorEventListener {
* Sets the context of the Command. This can then be used to do things like
* get file paths associated with the Activity.
*
* @param ctx The context of the main Activity.
* @param cordova The context of the main Activity.
*/
public void setContext(CordovaInterface ctx) {
super.setContext(ctx);
this.sensorManager = (SensorManager) ctx.getActivity().getSystemService(Context.SENSOR_SERVICE);
public void setContext(CordovaInterface cordova) {
super.setContext(cordova);
this.sensorManager = (SensorManager) cordova.getActivity().getSystemService(Context.SENSOR_SERVICE);
}
/**

View File

@@ -19,6 +19,7 @@
package org.apache.cordova.api;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
/**
@@ -44,19 +45,6 @@ public interface CordovaInterface {
*/
abstract public void setActivityResultCallback(IPlugin plugin);
/**
* Causes the Activity to override the back button behavior.
*
* @param override
*/
public abstract void bindBackButton(boolean override);
/**
* A hook required to check if the Back Button is bound.
*
* @return
*/
public abstract boolean isBackButtonBound();
/**
* Get the Android activity.
@@ -64,7 +52,10 @@ public interface CordovaInterface {
* @return
*/
public abstract Activity getActivity();
@Deprecated
public abstract Context getContext();
@Deprecated
public abstract void cancelLoadUrl();
@@ -76,4 +67,5 @@ public interface CordovaInterface {
* @return Object or null
*/
public Object onMessage(String id, Object data);
}

View File

@@ -33,6 +33,7 @@ public abstract class Plugin implements IPlugin {
public String id;
public CordovaWebView webView; // WebView object
public CordovaInterface ctx; // CordovaActivity object
public CordovaInterface cordova;
/**
* Executes the request and returns PluginResult.
@@ -61,7 +62,8 @@ public abstract class Plugin implements IPlugin {
* @param ctx The context of the main Activity.
*/
public void setContext(CordovaInterface ctx) {
this.ctx = ctx;
this.cordova = ctx;
this.ctx = cordova;
}
/**

View File

@@ -1,53 +0,0 @@
# 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