diff --git a/bin/create2 b/bin/create2 new file mode 100755 index 00000000..a142bf23 --- /dev/null +++ b/bin/create2 @@ -0,0 +1,115 @@ +#! /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. +# +# create a cordova/android project +# +# USAGE +# ./create [path package activity] +# +set -e + +if [ -n "$1" ] && [ "$1" == "-h" ] +then + echo 'usage: create path package activity' + echo "Make sure the Android SDK tools folder is in your PATH!" + exit 0 +fi + +BUILD_PATH=$( cd "$( dirname "$0" )/.." && pwd ) +VERSION=$(cat $BUILD_PATH/VERSION) + +PROJECT_PATH=${1:-"./example"} +PACKAGE=${2:-"org.apache.cordova.example"} +ACTIVITY=${3:-"cordovaExample"} + +# clobber any existing example +if [ -d $PROJECT_PATH ] +then + echo "Project already exists! Delete and recreate" + exit 1 +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 +} + +function on_error { + echo "An error occured. Deleting project..." + [ -d $PROJECT_PATH ] && rm -rf $PROJECT_PATH +} + +# we do not want the script to silently fail +trap on_error ERR +trap on_exit EXIT + +ANDROID_BIN=$( which android ) +PACKAGE_AS_PATH=$(echo $PACKAGE | sed 's/\./\//g') +ACTIVITY_PATH=$PROJECT_PATH/src/$PACKAGE_AS_PATH/$ACTIVITY.java +MANIFEST_PATH=$PROJECT_PATH/AndroidManifest.xml + +TARGET=$($ANDROID_BIN list targets | grep id: | tail -1 | cut -f 2 -d ' ' ) + +# update the cordova-android framework for the desired target +$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 + +# compile cordova.js and cordova.jar +echo "Building cordova-$VERSION.jar and cordova-$VERSION.js ..." +(cd $BUILD_PATH/framework && ant jar &> /dev/null ) + +# 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/templates2/project/assets $PROJECT_PATH +cp -r $BUILD_PATH/bin/templates2/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 + +# interpolate the activity name and package +echo "Updating Activity and AndroidManifest ..." +cp $BUILD_PATH/bin/templates2/project/Activity.java $ACTIVITY_PATH +sed -i '' -e "s/__ACTIVITY__/${ACTIVITY}/g" $ACTIVITY_PATH +sed -i '' -e "s/__ID__/${PACKAGE}/g" $ACTIVITY_PATH + +cp $BUILD_PATH/bin/templates2/project/AndroidManifest.xml $MANIFEST_PATH +sed -i '' -e "s/__ACTIVITY__/${ACTIVITY}/g" $MANIFEST_PATH +sed -i '' -e "s/__PACKAGE__/${PACKAGE}/g" $MANIFEST_PATH diff --git a/bin/templates2/project/Activity.java b/bin/templates2/project/Activity.java new file mode 100644 index 00000000..d37247be --- /dev/null +++ b/bin/templates2/project/Activity.java @@ -0,0 +1,35 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +package __ID__; + +import android.app.Activity; +import android.os.Bundle; +import org.apache.cordova.*; + +public class __ACTIVITY__ extends DroidGap +{ + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + super.loadUrl("file:///android_asset/www/index.html"); + } +} + diff --git a/bin/templates2/project/AndroidManifest.xml b/bin/templates2/project/AndroidManifest.xml new file mode 100644 index 00000000..0cff488c --- /dev/null +++ b/bin/templates2/project/AndroidManifest.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bin/templates2/project/assets/www/index.html b/bin/templates2/project/assets/www/index.html new file mode 100644 index 00000000..39368e0d --- /dev/null +++ b/bin/templates2/project/assets/www/index.html @@ -0,0 +1,60 @@ + + + + + + + PhoneGap + + + + + + +

Welcome to Cordova!

+

this file is located at assets/www/index.html

+
+

Platform:  , Version:  

+

UUID:  , Name:  

+

Width:  , Height:   + , Color Depth:

+
+
+
X:
 
+
Y:
 
+
Z:
 
+
+ Toggle Accelerometer + Get Location + Call 411 + Beep + Vibrate + Get a Picture + Get Phone's Contacts + Check Network +
+
Compass Heading:
Off
+
+ Toggle Compass + + + diff --git a/bin/templates2/project/assets/www/main.js b/bin/templates2/project/assets/www/main.js new file mode 100644 index 00000000..3a8b04a1 --- /dev/null +++ b/bin/templates2/project/assets/www/main.js @@ -0,0 +1,165 @@ +/* + 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. +*/ + +var deviceInfo = function() { + document.getElementById("platform").innerHTML = device.platform; + document.getElementById("version").innerHTML = device.version; + document.getElementById("uuid").innerHTML = device.uuid; + document.getElementById("name").innerHTML = device.name; + document.getElementById("width").innerHTML = screen.width; + document.getElementById("height").innerHTML = screen.height; + document.getElementById("colorDepth").innerHTML = screen.colorDepth; +}; + +var getLocation = function() { + var suc = function(p) { + alert(p.coords.latitude + " " + p.coords.longitude); + }; + var locFail = function() { + }; + navigator.geolocation.getCurrentPosition(suc, locFail); +}; + +var beep = function() { + navigator.notification.beep(2); +}; + +var vibrate = function() { + navigator.notification.vibrate(0); +}; + +function roundNumber(num) { + var dec = 3; + var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); + return result; +} + +var accelerationWatch = null; + +function updateAcceleration(a) { + document.getElementById('x').innerHTML = roundNumber(a.x); + document.getElementById('y').innerHTML = roundNumber(a.y); + document.getElementById('z').innerHTML = roundNumber(a.z); +} + +var toggleAccel = function() { + if (accelerationWatch !== null) { + navigator.accelerometer.clearWatch(accelerationWatch); + updateAcceleration({ + x : "", + y : "", + z : "" + }); + accelerationWatch = null; + } else { + var options = {}; + options.frequency = 1000; + accelerationWatch = navigator.accelerometer.watchAcceleration( + updateAcceleration, function(ex) { + alert("accel fail (" + ex.name + ": " + ex.message + ")"); + }, options); + } +}; + +var preventBehavior = function(e) { + e.preventDefault(); +}; + +function dump_pic(data) { + var viewport = document.getElementById('viewport'); + console.log(data); + viewport.style.display = ""; + viewport.style.position = "absolute"; + viewport.style.top = "10px"; + viewport.style.left = "10px"; + document.getElementById("test_img").src = data; +} + +function fail(msg) { + alert(msg); +} + +function show_pic() { + navigator.camera.getPicture(dump_pic, fail, { + quality : 50 + }); +} + +function close() { + var viewport = document.getElementById('viewport'); + viewport.style.position = "relative"; + viewport.style.display = "none"; +} + +function contacts_success(contacts) { + alert(contacts.length + + ' contacts returned.' + + (contacts[2] && contacts[2].name ? (' Third contact is ' + contacts[2].name.formatted) + : '')); +} + +function get_contacts() { + var obj = new ContactFindOptions(); + obj.filter = ""; + obj.multiple = true; + navigator.contacts.find( + [ "displayName", "name" ], contacts_success, + fail, obj); +} + +function check_network() { + var networkState = navigator.network.connection.type; + + var states = {}; + states[Connection.UNKNOWN] = 'Unknown connection'; + states[Connection.ETHERNET] = 'Ethernet connection'; + states[Connection.WIFI] = 'WiFi connection'; + states[Connection.CELL_2G] = 'Cell 2G connection'; + states[Connection.CELL_3G] = 'Cell 3G connection'; + states[Connection.CELL_4G] = 'Cell 4G connection'; + states[Connection.NONE] = 'No network connection'; + + confirm('Connection type:\n ' + states[networkState]); +} + +var watchID = null; + +function updateHeading(h) { + document.getElementById('h').innerHTML = h.magneticHeading; +} + +function toggleCompass() { + if (watchID !== null) { + navigator.compass.clearWatch(watchID); + watchID = null; + updateHeading({ magneticHeading : "Off"}); + } else { + var options = { frequency: 1000 }; + watchID = navigator.compass.watchHeading(updateHeading, function(e) { + alert('Compass Error: ' + e.code); + }, options); + } +} + +function init() { + // the next line makes it impossible to see Contacts on the HTC Evo since it + // doesn't have a scroll button + // document.addEventListener("touchmove", preventBehavior, false); + document.addEventListener("deviceready", deviceInfo, true); +} diff --git a/bin/templates2/project/assets/www/master.css b/bin/templates2/project/assets/www/master.css new file mode 100644 index 00000000..3aad33d3 --- /dev/null +++ b/bin/templates2/project/assets/www/master.css @@ -0,0 +1,116 @@ +/* + 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. +*/ + + + body { + background:#222 none repeat scroll 0 0; + color:#666; + font-family:Helvetica; + font-size:72%; + line-height:1.5em; + margin:0; + border-top:1px solid #393939; + } + + #info{ + background:#ffa; + border: 1px solid #ffd324; + -webkit-border-radius: 5px; + border-radius: 5px; + clear:both; + margin:15px 6px 0; + width:295px; + padding:4px 0px 2px 10px; + } + + #info > h4{ + font-size:.95em; + margin:5px 0; + } + + #stage.theme{ + padding-top:3px; + } + + /* Definition List */ + #stage.theme > dl{ + padding-top:10px; + clear:both; + margin:0; + list-style-type:none; + padding-left:10px; + overflow:auto; + } + + #stage.theme > dl > dt{ + font-weight:bold; + float:left; + margin-left:5px; + } + + #stage.theme > dl > dd{ + width:45px; + float:left; + color:#a87; + font-weight:bold; + } + + /* Content Styling */ + #stage.theme > h1, #stage.theme > h2, #stage.theme > p{ + margin:1em 0 .5em 13px; + } + + #stage.theme > h1{ + color:#eee; + font-size:1.6em; + text-align:center; + margin:0; + margin-top:15px; + padding:0; + } + + #stage.theme > h2{ + clear:both; + margin:0; + padding:3px; + font-size:1em; + text-align:center; + } + + /* Stage Buttons */ + #stage.theme a.btn{ + border: 1px solid #555; + -webkit-border-radius: 5px; + border-radius: 5px; + text-align:center; + display:block; + float:left; + background:#444; + width:150px; + color:#9ab; + font-size:1.1em; + text-decoration:none; + padding:1.2em 0; + margin:3px 0px 3px 5px; + } + #stage.theme a.btn.large{ + width:308px; + padding:1.2em 0; + } + diff --git a/bin/templates2/project/res/drawable-hdpi/icon.png b/bin/templates2/project/res/drawable-hdpi/icon.png new file mode 100644 index 00000000..4d276344 Binary files /dev/null and b/bin/templates2/project/res/drawable-hdpi/icon.png differ diff --git a/bin/templates2/project/res/drawable-ldpi/icon.png b/bin/templates2/project/res/drawable-ldpi/icon.png new file mode 100644 index 00000000..cd5032a4 Binary files /dev/null and b/bin/templates2/project/res/drawable-ldpi/icon.png differ diff --git a/bin/templates2/project/res/drawable-mdpi/icon.png b/bin/templates2/project/res/drawable-mdpi/icon.png new file mode 100644 index 00000000..e79c6062 Binary files /dev/null and b/bin/templates2/project/res/drawable-mdpi/icon.png differ diff --git a/bin/templates2/project/res/drawable-xhdpi/icon.png b/bin/templates2/project/res/drawable-xhdpi/icon.png new file mode 100644 index 00000000..ec7ffbfb Binary files /dev/null and b/bin/templates2/project/res/drawable-xhdpi/icon.png differ diff --git a/bin/templates2/project/res/drawable/icon.png b/bin/templates2/project/res/drawable/icon.png new file mode 100644 index 00000000..ec7ffbfb Binary files /dev/null and b/bin/templates2/project/res/drawable/icon.png differ diff --git a/bin/test_create2.js b/bin/test_create2.js new file mode 100644 index 00000000..1df5dd52 --- /dev/null +++ b/bin/test_create2.js @@ -0,0 +1,90 @@ +var project_path = '/tmp/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'), + spawn = require('child_process').spawn; + +var version = fs.readFileSync(__dirname + '/../VERSION').toString().replace('\n', ''); + +assert(version !== undefined); +assert(version !== ''); + +var create_project = spawn(__dirname + '/create2', + [project_path, + package_name, + project_name]); + +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(__dirname + '/framework/libs', function(exists) { + assert(!exists, 'libs directory did not get cleaned up'); + }); + path.exists(__dirname + util.format('/framework/assets/cordova-%s.js', version), function(exists) { + assert(!exists, 'javascript file did not get cleaned up'); + }); + path.exists(__dirname + 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'); + }); + + // check that project compiles && creates a cordovaExample-debug.apk + var compile_project = spawn('ant', ['debug'], {cwd: project_path}); + + compile_project.on('exit', function(code) { + assert.equal(code, 0, 'Cordova Android Project does not compile'); + // make sure cordovaExample-debug.apk was created + 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 + spawn('rm', ['-rf', project_path], function(code) { + assert.equal(code, 0, 'Could not remove project directory'); + }); + }); + }); + +});