From 7ca84aaa38b004ef27fed22deefbe1496c796e9f Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Tue, 24 Nov 2009 18:28:24 -0800 Subject: [PATCH 01/16] Updated README, removed old readme files. --- blackberry/README.md | 18 ++++++++++++++++++ blackberry/framework/README | 0 blackberry/framework/README.md | 3 --- 3 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 blackberry/README.md delete mode 100644 blackberry/framework/README delete mode 100644 blackberry/framework/README.md diff --git a/blackberry/README.md b/blackberry/README.md new file mode 100644 index 00000000..cbdcfb8e --- /dev/null +++ b/blackberry/README.md @@ -0,0 +1,18 @@ +PhoneGap BlackBerry +============================================================= +Allows developers to create BlackBerry applications using HTML, +CSS and JavaScript, and bridge into device functionality like +geolocation, SMS, device information, accelerometer, etc. via +a JavaScript API. + +Pre-requisites +------------------------------------------------------------- +Your best bet is to check the PhoneGap wiki for detailed +installation and setup instructions: +http://phonegap.pbworks.com/Getting+Started+with+PhoneGap+(BlackBerry) + +Create a PhoneGap project with Eclipse +------------------------------------------------------------- +1. Launch Eclipse, go to File->Import->Existing BlackBerry project. +2. Navigate over to where you cloned the git repo, and point it to the phonegap.jdp file located in blackberry/framework/. +3. Modify the contents of the "www" directory to add your own HTML, CSS and Javascript. \ No newline at end of file diff --git a/blackberry/framework/README b/blackberry/framework/README deleted file mode 100644 index e69de29b..00000000 diff --git a/blackberry/framework/README.md b/blackberry/framework/README.md deleted file mode 100644 index 9ca45cb0..00000000 --- a/blackberry/framework/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# GAP - -### Blackberry \ No newline at end of file From 5b139dfeaf051010dbac7b13cb69d5a79bea0ca2 Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Thu, 26 Nov 2009 15:42:01 -0800 Subject: [PATCH 02/16] Tweaked telephony "send" method to have proper name as per mobile-spec (woo the spec actually works!). Also tweaked Position JS object (unnecessary parameter). --- .../phonegap/api/impl/TelephonyCommand.java | 2 +- blackberry/js/position.js | 2 +- blackberry/js/telephony.js | 4 +- blackberry/util/AUTHORS | 30 + blackberry/util/CHANGELOG | 215 ++++++ blackberry/util/COPYING | 339 ++++++++++ blackberry/util/NEWS | 97 +++ blackberry/util/README | 619 ++++++++++++++++++ blackberry/util/bb-ant-tools.jar | Bin 0 -> 31534 bytes 9 files changed, 1304 insertions(+), 4 deletions(-) create mode 100644 blackberry/util/AUTHORS create mode 100644 blackberry/util/CHANGELOG create mode 100644 blackberry/util/COPYING create mode 100644 blackberry/util/NEWS create mode 100644 blackberry/util/README create mode 100644 blackberry/util/bb-ant-tools.jar diff --git a/blackberry/framework/src/com/nitobi/phonegap/api/impl/TelephonyCommand.java b/blackberry/framework/src/com/nitobi/phonegap/api/impl/TelephonyCommand.java index 4ff40097..1b1ea130 100644 --- a/blackberry/framework/src/com/nitobi/phonegap/api/impl/TelephonyCommand.java +++ b/blackberry/framework/src/com/nitobi/phonegap/api/impl/TelephonyCommand.java @@ -35,7 +35,7 @@ */ public class TelephonyCommand implements Command { - private static final String CODE = "PhoneGap=call"; + private static final String CODE = "PhoneGap=send"; public boolean accept(String instruction) { return instruction != null && instruction.startsWith(CODE); diff --git a/blackberry/js/position.js b/blackberry/js/position.js index 30d49721..55f73f69 100644 --- a/blackberry/js/position.js +++ b/blackberry/js/position.js @@ -1,5 +1,5 @@ -function Position(coords, timestamp) { +function Position(coords) { this.coords = coords; this.timestamp = new Date().getTime(); } diff --git a/blackberry/js/telephony.js b/blackberry/js/telephony.js index 68c5f094..3da69b4d 100644 --- a/blackberry/js/telephony.js +++ b/blackberry/js/telephony.js @@ -10,9 +10,9 @@ function Telephony() { * Calls the specifed number. * @param {Integer} number The number to be called. */ -Telephony.prototype.call = function(number) { +Telephony.prototype.send = function(number) { this.number = number; - PhoneGap.exec("call", [this.number]); + PhoneGap.exec("send", [this.number]); } if (typeof navigator.telephony == "undefined") navigator.telephony = new Telephony(); diff --git a/blackberry/util/AUTHORS b/blackberry/util/AUTHORS new file mode 100644 index 00000000..fe392fdf --- /dev/null +++ b/blackberry/util/AUTHORS @@ -0,0 +1,30 @@ +Written by: +----------- + Josh Kropf + + +Contributors (alphabetic order by last name): +--------------------------------------------- + Derek Konigsberg + - helped add preprocessor support to task + + Neil Sainsbury + - fixed several flaws in the .alx file generator + + Phil Smith + - added nopreverify switch to task and updated documentation + + Marek Uhel + - fixed bug in task + + Jeremy Wall + - use resource bundle for application title + - version matching for tag in .alx files + - conditional entry points in task + - several bug fixes related to .alx file generating + + atleta + - explicitly set preverify tool search path + + badgrs + - fixed incorrect naming of 'description' property diff --git a/blackberry/util/CHANGELOG b/blackberry/util/CHANGELOG new file mode 100644 index 00000000..46693490 --- /dev/null +++ b/blackberry/util/CHANGELOG @@ -0,0 +1,215 @@ +2009-09-15 Josh Kropf + + * RapcTask.java (nopreverify): applied patch from Phil Smith that passes + flag to rapc compiler instructing it to skip preverify step. + + +2009-09-11 Josh Kropf + + * JadtoolTask.java (executeRewrite): trim spaces from the value part of + key/value pairs in origional .jad file. + + +2009-09-11 Josh Kropf + + * JadtoolTask.java: applied patch from Marek Uhel to fix incorrect numbering + of RIM-COD-URL-* attributes in generated .jad file. + + +2009-07-08 Josh Kropf + + * JadtoolTask.java: task was updating element overrides but not + adding new ones. + + +2009-07-03 Josh Kropf + + * docs.txt: update documentation for element to make it clear + that this element is a nested element of the element. + + +2009-07-02 Josh Kropf + + * ApplicationType.java: Ensure destination directory for cod files is + always set to avoid cod files being copied to current working directory + by the task. + + +2009-03-11 Josh Kropf + + * ApplicationType.java: Neil Sainsbury's fixes to .alx file generation + + +2009-02-15 Josh Kropf + + * OverrideType.java: new type, basic key/value pair model + * JadtoolTask.java (overrides): nested parameters of type OverrideType + (executeRewrite): override jad fields selected by user + + +2009-02-10 Josh Kropf + + * Merged Jeremy Wall's bug fixes and enhancements + * ApplicationType.java: added version match properties to application tag + (generate): apply version match to both codSet and application tags + (generate): always include name,description,version,vendor,copyright + tags even if the contents is empty + * CodSetType.java (VersionMatch): removed package local class + (getVersionMatch): fixed version match string to use correct order of + square bracket and parentheses for inclusive and exclusive versions + * EntryPointType.java: added if and unless attributes + * JdpType.java (writeManifest): conditionally include alternate entry points + * Utils.java (getSHA1): pad hex byte with zero if less than two chars long + * VersionMatch.java: moved from package local class to public class + + +2009-01-18 Josh Kropf + + * JadtoolTask.java (executeRewrite): fixed bug that would generate .jad + file with all RIM-COD-* properties to end with 1 + * RapcTask.java (execute): added feature to expand directories listed + in the nested source path tags, eg: + + +2009-01-09 Josh Kropf + + * JdpType.java (getDesc, setDesc): renamed to getDescription, setDescription + + +2008-12-02 Josh Kropf + + * SigtoolTask.java (execute): cleaned/fixed code that checks touch file age + (executeSigtool): create touch files for each cod file signed + (touch): accept full path to cod file + + +2008-12-01 Josh Kropf + + * AlxTask.java (executeAlx): omit xml declaration form generated .alx + * BaseTask.java (isOutOfDate): removed method + * SigtoolTask.java (addCod): removed method, no more child element + (add): added method, accepts any resource collection type element + * ApplicationType.java (generate, copyCodFiles): removed nested loops + due to use of Union class in CodSetType + * CodSetType.java (resources): use Union instead Vector + * Utils.java (isUpToDate): new methods + + +2008-12-01 Josh Kropf + + * ApplicationType.java (generate): use just file name instead of relative + path for cod files in .alx file + * Utils.java: new class, static methods for working with File/Resource + * JadtoolTask.java: new class, the ant task + + +2008-11-30 Josh Kropf + + * AlxTask.java: new class, the ant task + * ApplicationType.java: new class, subtype of ant task + * BaseTask.java (execute): print version number to build log + * CodSetType.java: new class, subtype of ApplicationType + * RapcTask.java (execute): call superclass execute method + * SigtoolTask.java (execute): call superclass execute method + * etc/bb-ant-defs.xml: added alx/application/codset definitions + + +2008-11-26 Josh Kropf + + * EntryPointType.java, JdpType.java: applied patch by jwall1701 to support + using resource bundles for entry point titles + + +2008-11-01 Josh Kropf + + * RapcTask.java + (Define.if, Define.unless): added attributes to conditionally define + preprocessor tags added as nested elements of rapc task + (execute): enable preprocessor when defines attribute or nested define + elements are set + + +2008-11-01 Josh Kropf + + * RapcTask.java: applied patch by Derek Konigsberg for preprocessor support + (RapcTask.Define): new nested element class + (execute): when defines attribute or nested elements are set, + enable preprocessor + + +2008-07-30 Josh Kropf + + * RapcTask.java + (verbose,nodebug,nowarn,warnerror,noconvert): new compiler flags + + +2008-07-29 Josh Kropf + + * RapcTask.java (setJdeHome): remove code for locating JDE specific jar + files to avoid causing conflicts when using project level jde.home + property and setting jdehome property in rapc task + (execute): add api jar to import path + (executeRapc): get rapc jar path as local variable + + +2008/07/23 (josh) + +- Applied patch contributed by atleta to add property for explicitly setting + the search path for the preverify tool. + +2008/03/31 (josh) +- Applied patch contributed by badgrs to rename the description property + in JdpType from 'desc' to 'description'. + +2008/01/17 (josh) +- Quick update to RapcTask to automatically add the JDE\bin directory to + the PATH environment variable since people are consistently finding that + an error occurs trying to compile (ie: preverify.exe can't be found). +- Release 0.7 + +2007/08/10 (josh) +- Added property to Sigtool for automatically requesting signature without + password prompt (requires JDE 4.3.x) +- Sixth release (0.6) + +2007/07/19 (josh) +- Bug fix: set the failOnError property to true for the java process that + runs the rapc compiler + +2007/07/02 (josh) +- Added nested type EntryPointType to JdpType for adding alternate entry + points to CLDC applications +- Fifth release (0.5) + +2007/06/07 (josh) +- Added optional property to RapcTask for changing the vm used to + execute the rapc command +- Fourth release (0.4) + +2007/05/18 (josh) +- Fixed library flag generation in JdpType class for sytem modules and + applications that run on startup +- Third release (0.3) + +2007/05/17 (josh) +- RapcTask: added info message with number of files being compiled, and verbose + message when compilation is skipped +- Added "install" target in build script that copies the jar file into the + ant lib directory +- Removed build version from jar file name and added Version attribute to jar + manifest + +2007/05/16 (josh) +- Fixed bug in RapcTask that would cause library type projects to + be compiled as CLDC applications +- Second release (0.2) + +2007/05/07 (josh) +- Changed SigtoolTask to display a warning message if the cod file size was + the same before and after launching the SignatureTool +- Fixed bug that would create "file signed" indicator regardless if the file + was signed or not + +2007/04/30 (josh) +---------- +- First release (0.1) diff --git a/blackberry/util/COPYING b/blackberry/util/COPYING new file mode 100644 index 00000000..d511905c --- /dev/null +++ b/blackberry/util/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/blackberry/util/NEWS b/blackberry/util/NEWS new file mode 100644 index 00000000..991423b2 --- /dev/null +++ b/blackberry/util/NEWS @@ -0,0 +1,97 @@ + March 11, 2009 +============================================ + +Release 1.2.1 + +This is a bugfix release that deserves some attention. The task had +several flaws in the way it was generating XML. Basically I had it all wrong. + +Neil Sainsbury has sent in a patch that corrects this. An explanation of the +issue from his email: + +Currently alxtool produces for each codSet output of the form: +4.2 + + + myapp.cod + + + +The output should actually be of the form: + + 4.2 + + myapp.cod + + + + + March 9, 2009 +============================================ + +Release 1.2.0 + +After some back and forth with Neil Sainsbury, it was apparent that some +mechanism was required for changing properties (key/value fields) writen +to .jad files created by the task. One possible use case is to +change the MIDlet-Name field which controls the product name visible on the +device in Options->Applications. + +A new nested attribute of the task name has been defined. +See the README file or the website for syntax details. + + + February 10, 2009 +============================================ + +Release 1.1.0 + +Jeremy Wall has submitted several bug fixes and new features. The feature set +seems significant enough to increment the minor version digit. + + + alternate entry points can be conditionally compiled + + when generating .alx files, both application and codset tags + now support BlackBerry OS version matching expressions + + * fixed bad formatting in SHA hash when generating .jad files + * always include name, description, version, vendor, copyright child tags + when generating application tag in .alx files to avoid problems with loader + * corrected inclusive and exclusive brackets for BlackBerry version matching + + + December 4, 2008 +============================================ + +Ready to release 1.0.0. Here is a breakdown of the changes: + + + new task, generates .alx file and copy .cod files + + new task, update .jad file and extract sibling .cod files + + * Removed nested element from . The task can + now accept resource collection types (fileset, filelist) as direct + nested elements. + * Added support to the task for generating a text file listing + all the source files and passing said file to the rapc compiler. This + is a workaround for an error that can occur on Windows operating system + when building a project with many files or long pathnames. + + + + November 30, 2008 +============================================ +BB-Ant-Tools is poised to undergo some enhancements. I am working on adding +two more ant tasks: + + * - generate .alx file, and corresponding directory structure + * - updates .jad file with new set of .cod files + +In addition, the rapc task will get support for selecting source files from +a text file containing a list of source files. This will make compiling +large projects on the Windows platform possible as Windows has a limitation +on the length of a command line, thus currently limiting the number of files +that can be specified by the rapc task. + +The version numbering scheme has changed as well. The next release will be +marked 1.0.0 with following releases incrementing the minor version (1.x.0) +for minor functionality changes, and the patch version (1.0.x) for bug fix +releases. diff --git a/blackberry/util/README b/blackberry/util/README new file mode 100644 index 00000000..cdeb3215 --- /dev/null +++ b/blackberry/util/README @@ -0,0 +1,619 @@ +******************************************************************************** +* BlackBerry Ant Tools 1.2.4 * +******************************************************************************** + +Prerequisites: +-------------- + +- RIM JDE (tested with 4.1 and up) +- Java 1.5 or higher +- Apache Ant 1.7.x or higher + + + +Using: +------ + +- Copy the bb-ant-tools.jar into the your Ant lib directory, in $HOME/.ant/lib, + or add bb-ant-tools.jar to the classpath in your build script. +- Add the to your build script, eg: + + or + +- Enjoy (see examples below) + + + +Reference: +---------- + +The and tasks will first try to get the "jde.home" property +from the project. If this property is not set, then the "jdehome" attribute +must be explicitly set for these tasks. + + + +Runs the rapc compiler. The rapc task runs the compiler in much the same way +as the RIM JDE. The JDE project/workspace files are however not used for +building cod files. The nested element is used to specify all cod file +properties. + +The rapc task behaves similar to the javac task in that it will check the +modified time of the source files and compare it to the modified time of the +cod file. It will compile if one or more of the source files is newer than +the existing cod file. + + Parameters +============ + + jdehome + ---------------------------------------------------------------------------- + Sets the JDE home directory. This attribute is required when the "jde.home" + property is not defined at the project level. + + jdkhome + ---------------------------------------------------------------------------- + Sets an alternative JVM home directory. Use this to override the version + of the JVM used to execute the rapc compiler. When this attribute is not + defined, the systems default JVM is used. + + srcdir + ---------------------------------------------------------------------------- + Directory containing source files. This attribute is required when the + nested property is not used. An error is occurs if both the nested + property and the "srcdir" attribute is specified. + + destdir + ---------------------------------------------------------------------------- + Output directory of .cod file. When not defined, the base directory of the + Ant build file is used. + + exepath + ---------------------------------------------------------------------------- + Explicitly define the directory containing the preverify command used by + the rapc compiler. When not defined, the systems default PATH is used. + + output + ---------------------------------------------------------------------------- + Name of output file, eg: .cod, .cso, etc. This attribute + is required. + + import + ---------------------------------------------------------------------------- + Path of .jar files to import. Path strings consist of relative or absolute + path names delimited by a ';' (Windows) or ':' (Unix) character. The rapc + task will always add the net_rim_api.jar file by default. This attribute + is optional. + + importref + ---------------------------------------------------------------------------- + Path of .jar files to import given as a reference to a path defined + elsewhere. The rapc task will always add the net_rim_api.jar file by + default. This attribute is optional. + + defines + ---------------------------------------------------------------------------- + ':' or ';' delimited list of preprocessor tags. This attribute is optional. + See the note below regarding preprocessor usage. + + quiet + ---------------------------------------------------------------------------- + Tells the rapc compiler to be less chatty. Optional, defaults to true. + + verbose + ---------------------------------------------------------------------------- + Turn on verbose output of the rapc compiler. Optional, defaults to false. + + nodebug + ---------------------------------------------------------------------------- + Turn off generation of .debug files. Optional, defaults to false. + + nowarn + ---------------------------------------------------------------------------- + Disable warning messages. Optional, defaults to false. + + warnerror + ---------------------------------------------------------------------------- + Treat all warnings as errors. Optional, defaults to false. + + noconvert + ---------------------------------------------------------------------------- + Do not convert all images to PNG. Optional, defaults to false. + + nopreverify + ---------------------------------------------------------------------------- + Do not call the preverify executable. Optional, defaults to false. + + generatesourcelist + ---------------------------------------------------------------------------- + Generate list of source files in text file. Set this to true when java + returns "CreateProcess error=87" on Windows. Optional, defaults to false. + + sourcelistfile + ---------------------------------------------------------------------------- + Set the name of the source list file. Use this to override the name of + the file created when "generatesourcelist" is set to true. The default + file name is "sources.txt". + + Parameters specified as nested elements +========================================= + + + ---------------------------------------------------------------------------- + Zero or more preprocessor tag definitions nested as elements. + + tag + ------------------------------------------------------------------------ + Name of preprocessor tag eg: THE_DEFINED_TAG. Required. + + if + ------------------------------------------------------------------------ + Define tag only when the named property is set. Optional. + + unless + ------------------------------------------------------------------------ + Define tag only when the named property is NOT set. Optional. + + + ---------------------------------------------------------------------------- + Path like structure of files to compile. The element can contain + , , or any other path like element. A path defined + elsewhere can be referenced by setting the "refid" attribute of . + If the "srcdir" attribute was not defined, the element must contain + one or more resources to compile. + + + ---------------------------------------------------------------------------- + Path like structure of jar files to import. The rapc task will always add + the net_rim_api.jar file by default. This parameter is optional. + + + ---------------------------------------------------------------------------- + Collection of project attributes. + + type + ------------------------------------------------------------------------ + Type of cod file to create. Valid values are "library", "cldc", + "midlet". When "midlet" is specified, the midletclass property is + required. The default is "cldc". + + title + ------------------------------------------------------------------------ + Module title. The title appears below the icon and in the applications + list on the device. + + vendor + ------------------------------------------------------------------------ + Company name. The vendor string appears in the applications properties + on the device. + + version + ------------------------------------------------------------------------ + Module version number. Version number strings must contain only numbers + and dots. If not set, the default is 0.0. + + description + ------------------------------------------------------------------------ + Module description. The description string appears in the application + properties on the device. + + arguments + ------------------------------------------------------------------------ + Space delimited list of arguments passed to the main method. + + midletclass + ------------------------------------------------------------------------ + Fully qualified class name of the class extending + javax.microedition.midlet.MIDlet. + + systemmodule + ------------------------------------------------------------------------ + Set to true for a system module. System modules run in the background + and do not have an icon on the home screen. + + runonstartup + ------------------------------------------------------------------------ + Set to true if application should start when device starts. + + startuptier + ------------------------------------------------------------------------ + Startup priority relative to other applications. The default value is + 7, lower value = higher priority. + + ribbonposition + ------------------------------------------------------------------------ + Position of icon in ribbon. The default is 0, higher values move the + icon closer to the top of the ribbon. + + nameresourcebundle + ------------------------------------------------------------------------ + Name of resource bundle that contains the module title, + eg: ca.slashdev.MyAppResources + + nameresourceid + ------------------------------------------------------------------------ + The id of the resource that contains the module title, eg: 1234. + + icon + ------------------------------------------------------------------------ + Ribbon icon. Path must be relative to destdir, eg: ../img/ribbon1.png + + file + ------------------------------------------------------------------------ + Properties file containing the project attributes. Property names + must match the names defined above. + + - nested element of + ------------------------------------------------------------------------ + Defines zero or more alternate entry points, CLDC applications only. + The element is a nested element of and supports a subset + of project attributes. + + title + -------------------------------------------------------------------- + For non-system modules, defines the title for the ribbon icon. + + arguments + -------------------------------------------------------------------- + Space delimited list arguments passed to the main method. + + systemmodule + -------------------------------------------------------------------- + Set to true for a system module. System modules run in the + background and do not have an icon on the home screen. + + runonstartup + -------------------------------------------------------------------- + Set to true if application should start when device starts. + + startuptier + -------------------------------------------------------------------- + Startup priority relative to other applications. The default value + is 7, lower value = higher priority. + + ribbonposition + -------------------------------------------------------------------- + Position of icon in ribbon. The default is 0, higher values move + the icon closer to the top of the ribbon. + + nameresourcebundle + -------------------------------------------------------------------- + Name of resource bundle that contains the module title, + eg: ca.slashdev.MyAppResources + + nameresourceid + -------------------------------------------------------------------- + The id of the resource that contains the module title, eg: 1234. + + icon + -------------------------------------------------------------------- + Ribbon icon. Path must be relative to destdir, + eg: ../img/ribbon1.png + + file + -------------------------------------------------------------------- + Properties file containing the project attributes. Property names + must match the names defined above. + + if + -------------------------------------------------------------------- + Include entry point when the named property is set. Optional. + + unless + -------------------------------------------------------------------- + Include entry point when the named property is NOT set. Optional. + + Preprocessor +============== + +Apparently since version 4.0, rapc compiler has had support for a simple set +of preprocessor macros. To use the preprocessor you must: + + * have version 4.x or higher of JDE + * enable processing on a per file basis by placing //#preprocess in the very + first line of each .java file + * use //#ifdef , //#ifndef to begin a block of text that will be + conditionally compiled if the TAG is defined or undefined respectively + * use //#else after //#ifdef or //#ifndef + * close conditional blocks with //#endif + +Preprocessor defines can be specified as a colon or semi-colon delimited list +as an attribute of the tag OR zero or more nested elements. +See reference documentation for task above. + + Examples +========== + + + + + + + +... + + + + + + + +... + + + + + + + + + + + + + + + + + + + + + + +Sigtool task will launch the signature tool on a given cod file or set of +cod files. When the cod file is successfully signed, a file is created +along side the cod file to mark it as signed. + + Parameters +============ + + jdehome + ---------------------------------------------------------------------------- + Sets the JDE home directory. This attribute is required when the "jde.home" + property is not defined at the project level. + + codfile + ---------------------------------------------------------------------------- + Single cod file to sign. + + forceclose + ---------------------------------------------------------------------------- + Close signature tool even if signature failed. Default is false. + + close + ---------------------------------------------------------------------------- + Close after signature request if no errors have occured. Default is true. + + request + ---------------------------------------------------------------------------- + Request signature when application launches. Default is true. + + password + ---------------------------------------------------------------------------- + Removes the interactive password prompt. This implicitly sets "close" and + "request" to true. + + Parameters specified as nested elements +========================================= + +Sigtool task supports selecting cod files using nested resource collections +such as and . + + Examples +========== + + + + + + +... + + + + + + + + +Alx task creates a directory structure of cod files and an .alx file. The +purpose of the task is to generate a directory that can be easily zipped +for creating an installation package. Therefore cod files are always +copied to the destination directory. + +The task fully supports generating expressions that limit which files will +be selected by the application loader (Loader.exe) based on OS version. + + Parameters +============ + + destdir + ---------------------------------------------------------------------------- + Destination director for .cod files and .alx file. If the directory does + not exist, it will be created. This attribute is required. + + filename + ---------------------------------------------------------------------------- + Name of .alx file to generate. This attribute is required. + + Parameters specified as nested elements +========================================= + + + ---------------------------------------------------------------------------- + Nested elements of . The "id" attribute is required. The remaining + attributes are for information purposes only in the application loader + program (Loader.exe). + + id + ------------------------------------------------------------------------ + Unique id of the application, eg: com.mycompany.myapp. This attribute + is required. + + name - application name. + description - application description + version - version number, eg: 1.0 + vendor - vendor string, eg: My Company + copyright - copyright information + + file + ------------------------------------------------------------------------ + Optionally specify a properties file of application attributes, must + match names defined above. *NOTE*: 'title' is recognized as an alias + for 'name' so properties files created for type can be used here. + + greaterthan + ------------------------------------------------------------------------ + Only install application on versions of the BlackBerry software greater + than the given version. + + greaterthanequal + ------------------------------------------------------------------------ + Only install application on versions of the BlackBerry software greater + than or equal to the given version. + + lessthan + ------------------------------------------------------------------------ + Only install application on versions of the BlackBerry software less than + the given version. + + lessthanequal + ------------------------------------------------------------------------ + Only install application on versions of the BlackBerry software less than + or equal to the given version. + + + ------------------------------------------------------------------------ + One or more nested elements of element. + + Cod files must be listed using nested resource collections such as + and . + + Cod file sets can be used to target specific versions of the BlackBerry + software by setting either or both of the greaterthan and lessthan + properties. Both properties have the alternate inclusive version + greaterthanequal and lessthanequal. + + dir + -------------------------------------------------------------------- + Directory for cod files in destination directory. + + greaterthan + -------------------------------------------------------------------- + Only install cod files on versions of the BlackBerry software + greater than the given version. + + greaterthanequal + -------------------------------------------------------------------- + Only install cod files on versions of the BlackBerry software + greater than or equal to the given version. + + lessthan + -------------------------------------------------------------------- + Only install cod files on version of the BlackBerry software + less than the given version. + + lessthanequal + -------------------------------------------------------------------- + Only install cod files on version of the BlackBerry software + less than or equal to the given version. + + Examples +========== + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Simple task that takes an input .jad file and rewrites it with one or more +new cod files. The .jad file is updated with accurate .cod file sizes and +SHA1 checksums. + +The cod files are copied to the directory where the .jad file is created. +If the cod file contains siblings, the cod file is automatically extracted. + + Parameters +============ + + input + ---------------------------------------------------------------------------- + Input .jad file. This attribute is required. + + destdir + ---------------------------------------------------------------------------- + Destination directory for cod files and new jad file. This attribute is + required. + + Parameters specified as nested elements +========================================= + +Jadtool task supports selecting cod files using nested resource collections +such as and . At least one cod file must be selected. + + + ---------------------------------------------------------------------------- + Nested element of . Provides the ability to add and/or update + fields in the destination .jad file. + + key + ------------------------------------------------------------------------ + Name of .jad property to add/change + + value + ------------------------------------------------------------------------ + New value for .jad property + + Examples +========== + + + + + + + + + + + + + + +Licensing: +---------- +This product is distributed under the GPL. Please read through the file +COPYING for more information about our license. diff --git a/blackberry/util/bb-ant-tools.jar b/blackberry/util/bb-ant-tools.jar new file mode 100644 index 0000000000000000000000000000000000000000..2b7b5eb9bad80385f2e7ac973f93269cd62c24c3 GIT binary patch literal 31534 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 z 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 literal 0 HcmV?d00001 From ff58c13632fe04017125fda31711c46e80aa0712 Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Thu, 26 Nov 2009 15:44:37 -0800 Subject: [PATCH 03/16] Tweaked PhoneGap BlackBerry Contacts API to be named properly (AddressBook, not ContactManager). --- blackberry/js/contacts.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/blackberry/js/contacts.js b/blackberry/js/contacts.js index d83d8df9..aff579ce 100644 --- a/blackberry/js/contacts.js +++ b/blackberry/js/contacts.js @@ -18,15 +18,15 @@ Contact.prototype.displayName = function() return this.name; } -function ContactManager() { +function AddressBook() { // Dummy object to hold array of contacts this.contacts = []; this.timestamp = new Date().getTime(); } -if (typeof navigator.ContactManager == "undefined") navigator.ContactManager = new ContactManager(); +if (typeof navigator.AddressBook == "undefined") navigator.AddressBook = new AddressBook(); -ContactManager.prototype.formParams = function(options, startArray) { +AddressBook.prototype.formParams = function(options, startArray) { var params = []; if (startArray) params = startArray; if (options.pageSize && options.pageSize > 0) params.push("pageSize:" + options.pageSize); @@ -35,13 +35,13 @@ ContactManager.prototype.formParams = function(options, startArray) { if (options.contactID) params.push("contactID:" + options.contactID); return params; }; -ContactManager.prototype.chooseContact = function(successCallback, options) { +AddressBook.prototype.chooseContact = function(successCallback, options) { this.choose_onSuccess = successCallback; var params = ["choose"]; params = this.formParams(options,params); PhoneGap.exec("contacts", params); }; -ContactManager.prototype.displayContact = function(successCallback, errorCallback, options) { +AddressBook.prototype.displayContact = function(successCallback, errorCallback, options) { if (options.nameFilter && options.nameFilter.length > 0) { var params = ["search"]; params = this.formParams(options,params); @@ -49,18 +49,18 @@ ContactManager.prototype.displayContact = function(successCallback, errorCallbac this.search_onError = errorCallback; PhoneGap.exec("contacts", params); } else { - ContactManager.getAllContacts(successCallback,errorCallback,options); + this.getAllContacts(successCallback,errorCallback,options); return; } }; -ContactManager.prototype.getAllContacts = function(successCallback, errorCallback, options) { +AddressBook.prototype.getAllContacts = function(successCallback, errorCallback, options) { this.global_onSuccess = successCallback; this.global_onError = errorCallback; var params = ["getall"]; params = this.formParams(options,params); PhoneGap.exec("contacts", params); }; -ContactManager.prototype.newContact = function(contact, successCallback, errorCallback, options) { +AddressBook.prototype.newContact = function(contact, successCallback, errorCallback, options) { if (!contact) { alert("[PhoneGap Error] newContact function not provided with a contact parameter."); return; From 5c0d306815b4d721a0c53974d5bb6c4fb60c1de8 Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Fri, 27 Nov 2009 10:55:19 -0800 Subject: [PATCH 04/16] Tweaked minor changes to contacts API, lined up JS API to closer to mobile spec. --- .../phonegap/api/impl/ContactsCommand.java | 2 +- blackberry/framework/src/www/phonegap.js | 22 ++-- blackberry/js/contacts.js | 4 +- symbian.wrt/www/js/phonegap.js | 124 +++++++++--------- 4 files changed, 76 insertions(+), 76 deletions(-) diff --git a/blackberry/framework/src/com/nitobi/phonegap/api/impl/ContactsCommand.java b/blackberry/framework/src/com/nitobi/phonegap/api/impl/ContactsCommand.java index 7336bd04..caa2009e 100644 --- a/blackberry/framework/src/com/nitobi/phonegap/api/impl/ContactsCommand.java +++ b/blackberry/framework/src/com/nitobi/phonegap/api/impl/ContactsCommand.java @@ -49,7 +49,7 @@ public class ContactsCommand implements Command { private static final int REMOVE_COMMAND = 3; private static final int NEW_COMMAND = 4; private static final String CODE = "PhoneGap=contacts"; - private static final String CONTACT_MANAGER_JS_NAMESPACE = "navigator.ContactManager"; + private static final String CONTACT_MANAGER_JS_NAMESPACE = "navigator.AddressBook"; private static final String ERROR_NO_CONTACTID = ";alert('[PhoneGap Error] Contact ID not specified during contact removal operation.');"; diff --git a/blackberry/framework/src/www/phonegap.js b/blackberry/framework/src/www/phonegap.js index d878e1ed..020b907e 100644 --- a/blackberry/framework/src/www/phonegap.js +++ b/blackberry/framework/src/www/phonegap.js @@ -186,15 +186,15 @@ Contact.prototype.displayName = function() return this.name; } -function ContactManager() { +function AddressBook() { // Dummy object to hold array of contacts this.contacts = []; this.timestamp = new Date().getTime(); } -if (typeof navigator.ContactManager == "undefined") navigator.ContactManager = new ContactManager(); +if (typeof navigator.AddressBook == "undefined") navigator.AddressBook = new AddressBook(); -ContactManager.prototype.formParams = function(options, startArray) { +AddressBook.prototype.formParams = function(options, startArray) { var params = []; if (startArray) params = startArray; if (options.pageSize && options.pageSize > 0) params.push("pageSize:" + options.pageSize); @@ -203,13 +203,13 @@ ContactManager.prototype.formParams = function(options, startArray) { if (options.contactID) params.push("contactID:" + options.contactID); return params; }; -ContactManager.prototype.chooseContact = function(successCallback, options) { +AddressBook.prototype.chooseContact = function(successCallback, options) { this.choose_onSuccess = successCallback; var params = ["choose"]; params = this.formParams(options,params); PhoneGap.exec("contacts", params); }; -ContactManager.prototype.displayContact = function(successCallback, errorCallback, options) { +AddressBook.prototype.displayContact = function(successCallback, errorCallback, options) { if (options.nameFilter && options.nameFilter.length > 0) { var params = ["search"]; params = this.formParams(options,params); @@ -217,18 +217,18 @@ ContactManager.prototype.displayContact = function(successCallback, errorCallbac this.search_onError = errorCallback; PhoneGap.exec("contacts", params); } else { - ContactManager.getAllContacts(successCallback,errorCallback,options); + this.getAllContacts(successCallback,errorCallback,options); return; } }; -ContactManager.prototype.getAllContacts = function(successCallback, errorCallback, options) { +AddressBook.prototype.getAllContacts = function(successCallback, errorCallback, options) { this.global_onSuccess = successCallback; this.global_onError = errorCallback; var params = ["getall"]; params = this.formParams(options,params); PhoneGap.exec("contacts", params); }; -ContactManager.prototype.newContact = function(contact, successCallback, errorCallback, options) { +AddressBook.prototype.newContact = function(contact, successCallback, errorCallback, options) { if (!contact) { alert("[PhoneGap Error] newContact function not provided with a contact parameter."); return; @@ -818,7 +818,7 @@ Orientation.prototype.clearWatch = function(watchId) { if (typeof navigator.orientation == "undefined") navigator.orientation = new Orientation(); -function Position(coords, timestamp) { +function Position(coords) { this.coords = coords; this.timestamp = new Date().getTime(); } @@ -917,9 +917,9 @@ function Telephony() { * Calls the specifed number. * @param {Integer} number The number to be called. */ -Telephony.prototype.call = function(number) { +Telephony.prototype.send = function(number) { this.number = number; - PhoneGap.exec("call", [this.number]); + PhoneGap.exec("send", [this.number]); } if (typeof navigator.telephony == "undefined") navigator.telephony = new Telephony(); diff --git a/blackberry/js/contacts.js b/blackberry/js/contacts.js index aff579ce..00e03d28 100644 --- a/blackberry/js/contacts.js +++ b/blackberry/js/contacts.js @@ -41,7 +41,7 @@ AddressBook.prototype.chooseContact = function(successCallback, options) { params = this.formParams(options,params); PhoneGap.exec("contacts", params); }; -AddressBook.prototype.displayContact = function(successCallback, errorCallback, options) { +AddressBook.prototype.findContacts = function(successCallback, errorCallback, options) { if (options.nameFilter && options.nameFilter.length > 0) { var params = ["search"]; params = this.formParams(options,params); @@ -60,7 +60,7 @@ AddressBook.prototype.getAllContacts = function(successCallback, errorCallback, params = this.formParams(options,params); PhoneGap.exec("contacts", params); }; -AddressBook.prototype.newContact = function(contact, successCallback, errorCallback, options) { +AddressBook.prototype.addContact = function(contact, successCallback, errorCallback, options) { if (!contact) { alert("[PhoneGap Error] newContact function not provided with a contact parameter."); return; diff --git a/symbian.wrt/www/js/phonegap.js b/symbian.wrt/www/js/phonegap.js index d83181e2..46e93e44 100644 --- a/symbian.wrt/www/js/phonegap.js +++ b/symbian.wrt/www/js/phonegap.js @@ -868,68 +868,68 @@ function __sp_startCamera(camera_cb){ } -/* -Copyright © 2009 Nokia. All rights reserved. -Code licensed under the BSD License: -Software License Agreement (BSD License) Copyright © 2009 Nokia. -All rights reserved. -Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -Neither the name of Nokia Corporation. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission of Nokia Corporation. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -version: 1.0 -*/ - - -// Camera service interface - -var __device_camera_service_entry = {"name": null, - "version": null, - "proto": __device_camera, - "descriptor": __device_camera_descriptor, - "providers": [{"descriptor": __sp_camera_descriptor, "instance": __sp_camera_instance}] - }; - -function __device_camera_descriptor(provider){ - this.interfaceName = provider.interfaceName; - this.version = provider.version; -} - - -// Private camera prototype: called from service factory -function __device_camera(provider){ - //Private properties - this.provider = provider; - //Read-only properties - this.interfaceName = provider.descriptor.interfaceName; - this.version = provider.descriptor.version; - // this.supportedMediaTypes = provider.supportedMediaTypes; - // this.supportedSizes = provider.supportedSizes; - //Core methods - this.startCamera = __device_camera_startCamera; - this.stopViewfinder = __device_camera_stopViewfinder; - //Extended methods - this.takePicture = __device_camera_takePicture; -} - - -//Why bother to define these methods? Because the camera -//object defines the contract for providers! - -function __device_camera_startCamera(camera_cb){ - return this.provider.startCamera(camera_cb); -} - -function __device_camera_stopViewfinder(){ - this.provider.stopViewfinder(); -} - -function __device_camera_takePicture(format){ - this.provider.takePicture(format); -} +/* +Copyright © 2009 Nokia. All rights reserved. +Code licensed under the BSD License: +Software License Agreement (BSD License) Copyright © 2009 Nokia. +All rights reserved. +Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of Nokia Corporation. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission of Nokia Corporation. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +version: 1.0 +*/ + + +// Camera service interface + +var __device_camera_service_entry = {"name": null, + "version": null, + "proto": __device_camera, + "descriptor": __device_camera_descriptor, + "providers": [{"descriptor": __sp_camera_descriptor, "instance": __sp_camera_instance}] + }; + +function __device_camera_descriptor(provider){ + this.interfaceName = provider.interfaceName; + this.version = provider.version; +} + + +// Private camera prototype: called from service factory +function __device_camera(provider){ + //Private properties + this.provider = provider; + //Read-only properties + this.interfaceName = provider.descriptor.interfaceName; + this.version = provider.descriptor.version; + // this.supportedMediaTypes = provider.supportedMediaTypes; + // this.supportedSizes = provider.supportedSizes; + //Core methods + this.startCamera = __device_camera_startCamera; + this.stopViewfinder = __device_camera_stopViewfinder; + //Extended methods + this.takePicture = __device_camera_takePicture; +} + + +//Why bother to define these methods? Because the camera +//object defines the contract for providers! + +function __device_camera_startCamera(camera_cb){ + return this.provider.startCamera(camera_cb); +} + +function __device_camera_stopViewfinder(){ + this.provider.stopViewfinder(); +} + +function __device_camera_takePicture(format){ + this.provider.takePicture(format); +} /** * This class provides access to the device contacts. * @constructor From 72c71a45fe4dca8e87064c2904931b9e0c19b303 Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Fri, 27 Nov 2009 16:47:16 -0800 Subject: [PATCH 05/16] Updated geolocation JavaScript API - it was broken! --- blackberry/framework/src/www/phonegap.js | 7 +++---- blackberry/js/geolocation.js | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/blackberry/framework/src/www/phonegap.js b/blackberry/framework/src/www/phonegap.js index 020b907e..b21708b3 100644 --- a/blackberry/framework/src/www/phonegap.js +++ b/blackberry/framework/src/www/phonegap.js @@ -209,7 +209,7 @@ AddressBook.prototype.chooseContact = function(successCallback, options) { params = this.formParams(options,params); PhoneGap.exec("contacts", params); }; -AddressBook.prototype.displayContact = function(successCallback, errorCallback, options) { +AddressBook.prototype.findContacts = function(successCallback, errorCallback, options) { if (options.nameFilter && options.nameFilter.length > 0) { var params = ["search"]; params = this.formParams(options,params); @@ -228,7 +228,7 @@ AddressBook.prototype.getAllContacts = function(successCallback, errorCallback, params = this.formParams(options,params); PhoneGap.exec("contacts", params); }; -AddressBook.prototype.newContact = function(contact, successCallback, errorCallback, options) { +AddressBook.prototype.addContact = function(contact, successCallback, errorCallback, options) { if (!contact) { alert("[PhoneGap Error] newContact function not provided with a contact parameter."); return; @@ -417,8 +417,7 @@ Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallba var delay = 0; var timer = setInterval(function() { delay += interval; - - if (typeof(dis.lastPosition) == 'object' && dis.lastPosition.timestamp > referenceTime) { + if (dis.lastPosition != null && dis.lastPosition.timestamp > referenceTime) { successCallback(dis.lastPosition); clearInterval(timer); } else if (delay >= timeout) { diff --git a/blackberry/js/geolocation.js b/blackberry/js/geolocation.js index a7d78490..798e2aab 100644 --- a/blackberry/js/geolocation.js +++ b/blackberry/js/geolocation.js @@ -45,8 +45,7 @@ Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallba var delay = 0; var timer = setInterval(function() { delay += interval; - - if (typeof(dis.lastPosition) == 'object' && dis.lastPosition.timestamp > referenceTime) { + if (dis.lastPosition != null && dis.lastPosition.timestamp > referenceTime) { successCallback(dis.lastPosition); clearInterval(timer); } else if (delay >= timeout) { From 112619582396b15547222acff4cd2cb98d609003 Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Fri, 27 Nov 2009 16:56:13 -0800 Subject: [PATCH 06/16] Fixed to BlackBerry native code for GeoLocation functionality. --- .../phonegap/api/impl/GeoLocationCommand.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/blackberry/framework/src/com/nitobi/phonegap/api/impl/GeoLocationCommand.java b/blackberry/framework/src/com/nitobi/phonegap/api/impl/GeoLocationCommand.java index e1cb5c42..9dabf398 100644 --- a/blackberry/framework/src/com/nitobi/phonegap/api/impl/GeoLocationCommand.java +++ b/blackberry/framework/src/com/nitobi/phonegap/api/impl/GeoLocationCommand.java @@ -30,6 +30,7 @@ import net.rim.blackberry.api.invoke.Invoke; import net.rim.blackberry.api.invoke.MapsArguments; +import com.nitobi.phonegap.PhoneGap; import com.nitobi.phonegap.api.Command; import com.nitobi.phonegap.model.Position; @@ -44,24 +45,26 @@ public class GeoLocationCommand implements Command { private static final int MAP_COMMAND = 0; private static final int STOP_COMMAND = 1; private static final int START_COMMAND = 2; - private static final int CHECK_COMMAND = 3; private static final int CAPTURE_INTERVAL = 5; private static final String CODE = "PhoneGap=location"; private static final String GEO_NS = "navigator.geolocation."; private static final String GEO_STOP = GEO_NS + "started = false;" + GEO_NS + "lastPosition = null;"; private static final String GEO_START = GEO_NS + "started = true;"; - private static final String GEO_CHECK = GEO_NS + "setLocation("; - private static final String GEO_ERROR = GEO_NS + "setError("; + private static final String GEO_SET_LOCATION = GEO_NS + "setLocation("; + private static final String GEO_SET_ERROR = GEO_NS + "setError("; private static final String FUNC_SUF = ");"; private static final String ERROR_UNAVAILABLE = "'GPS unavailable on this device.'"; private static final String ERROR_OUTOFSERVICE = "'GPS is out of service on this device.'"; + + private PhoneGap berryGap; private Position position; private boolean availableGPS = true; private LocationProvider locationProvider; - public GeoLocationCommand() { + public GeoLocationCommand(PhoneGap phoneGap) { + this.berryGap = phoneGap; try { locationProvider = LocationProvider.getInstance(null); // Passing null as the parameter is equal to passing a Criteria that has all fields set to the default values, @@ -104,7 +107,6 @@ public String execute(String instruction) { return GEO_STOP; case START_COMMAND: locationProvider.setLocationListener(new LocationListenerImpl(this), CAPTURE_INTERVAL, 1, 1); return GEO_START; - case CHECK_COMMAND: if (position != null) return GEO_CHECK + position.toJavascript() + FUNC_SUF; } return null; } @@ -118,7 +120,6 @@ private int getCommand(String instruction) { if ("map".equals(command)) return MAP_COMMAND; if ("stop".equals(command)) return STOP_COMMAND; if ("start".equals(command)) return START_COMMAND; - if ("check".equals(command)) return CHECK_COMMAND; return -1; } @@ -132,10 +133,11 @@ private void updateLocation(double lat, double lng, float altitude, float accura position.setHeading(heading); position.setVelocity(speed); position.setTimestamp(time); + berryGap.pendingResponses.addElement(GEO_SET_LOCATION + position.toJavascript() + FUNC_SUF); } private String setError(String error) { - return GEO_ERROR + error + FUNC_SUF; + return GEO_SET_ERROR + error + FUNC_SUF; } private String getLocationDocument() { From 4821aaeceee1aa07c220174a0b7efadf82b7292f Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Fri, 27 Nov 2009 17:33:32 -0800 Subject: [PATCH 07/16] Updated Contacts JS API with proper find method and filter parameter. --- blackberry/framework/src/www/phonegap.js | 58 ++++++------------------ blackberry/js/contacts.js | 58 ++++++------------------ 2 files changed, 28 insertions(+), 88 deletions(-) diff --git a/blackberry/framework/src/www/phonegap.js b/blackberry/framework/src/www/phonegap.js index b21708b3..790fcb61 100644 --- a/blackberry/framework/src/www/phonegap.js +++ b/blackberry/framework/src/www/phonegap.js @@ -186,79 +186,49 @@ Contact.prototype.displayName = function() return this.name; } -function AddressBook() { +function Contacts() { // Dummy object to hold array of contacts this.contacts = []; this.timestamp = new Date().getTime(); } -if (typeof navigator.AddressBook == "undefined") navigator.AddressBook = new AddressBook(); +if (typeof navigator.contacts == "undefined") navigator.contacts = new Contacts(); -AddressBook.prototype.formParams = function(options, startArray) { +Contacts.prototype.formParams = function(options, startArray) { var params = []; if (startArray) params = startArray; - if (options.pageSize && options.pageSize > 0) params.push("pageSize:" + options.pageSize); - if (options.pageNumber) params.push("pageNumber:" + options.pageNumber); - if (options.nameFilter) params.push("nameFilter:" + options.nameFilter); - if (options.contactID) params.push("contactID:" + options.contactID); + if (options.limit && options.limit > 0) params.push("pageSize:" + options.limit); + if (options.page) params.push("pageNumber:" + options.page); return params; }; -AddressBook.prototype.chooseContact = function(successCallback, options) { +Contacts.prototype.chooseContact = function(successCallback, options) { this.choose_onSuccess = successCallback; var params = ["choose"]; params = this.formParams(options,params); PhoneGap.exec("contacts", params); }; -AddressBook.prototype.findContacts = function(successCallback, errorCallback, options) { - if (options.nameFilter && options.nameFilter.length > 0) { +Contacts.prototype.find = function(filter, successCallback, errorCallback, options) { + if (typeof(filter) != 'object') { + alert('[PhoneGap Error] filter parameter passed into navigator.contacts.find must be of type object.'); + return; + } + if (filter.name && filter.name.length > 0) { var params = ["search"]; + params.push('nameFilter:' + filter.name); params = this.formParams(options,params); this.search_onSuccess = successCallback; this.search_onError = errorCallback; PhoneGap.exec("contacts", params); } else { this.getAllContacts(successCallback,errorCallback,options); - return; } }; -AddressBook.prototype.getAllContacts = function(successCallback, errorCallback, options) { +Contacts.prototype.getAllContacts = function(successCallback, errorCallback, options) { this.global_onSuccess = successCallback; this.global_onError = errorCallback; var params = ["getall"]; params = this.formParams(options,params); PhoneGap.exec("contacts", params); -}; -AddressBook.prototype.addContact = function(contact, successCallback, errorCallback, options) { - if (!contact) { - alert("[PhoneGap Error] newContact function not provided with a contact parameter."); - return; - } else { - if (!contact.firstName || !contact.lastName || !contact.phoneNumber || !contact.address || !contact.email) { - alert("[PhoneGap Error] newContact function parameter 'contact' does not have proper contact members (firstName, lastName, phoneNumber, address and email)."); - return; - } - options.push("firstName:" + contact.firstName); - options.push("lastName:" + contact.lastName); - options.push("address:" + contact.address); - // Create a phone number parameter that we can parse on the BlackBerry end. - var phones = ''; - for (var i = 0; i < contact.phoneNumber.length; i++) { - phones += contact.phoneNumber[i].label + '='; - phones += contact.phoneNumber[i].value + '|'; - } - options.push("phoneNumber:" + phones.substr(0,phones.length-1)); - var emails = ''; - for (var j = 0; j < contact.email.length; j++) { - emails += contact.email[j].label + '='; - emails += contact.email[j].value + '|'; - } - options.push("email:" + emails.substr(0,emails.length-1)); - this.new_onSuccess = successCallback; - this.new_onError = errorCallback; - var params = ["new"]; - params = this.formParams(options,params); - PhoneGap.exec("contacts", params); - } };/** * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the * phone, etc. diff --git a/blackberry/js/contacts.js b/blackberry/js/contacts.js index 00e03d28..b41395f7 100644 --- a/blackberry/js/contacts.js +++ b/blackberry/js/contacts.js @@ -18,77 +18,47 @@ Contact.prototype.displayName = function() return this.name; } -function AddressBook() { +function Contacts() { // Dummy object to hold array of contacts this.contacts = []; this.timestamp = new Date().getTime(); } -if (typeof navigator.AddressBook == "undefined") navigator.AddressBook = new AddressBook(); +if (typeof navigator.contacts == "undefined") navigator.contacts = new Contacts(); -AddressBook.prototype.formParams = function(options, startArray) { +Contacts.prototype.formParams = function(options, startArray) { var params = []; if (startArray) params = startArray; - if (options.pageSize && options.pageSize > 0) params.push("pageSize:" + options.pageSize); - if (options.pageNumber) params.push("pageNumber:" + options.pageNumber); - if (options.nameFilter) params.push("nameFilter:" + options.nameFilter); - if (options.contactID) params.push("contactID:" + options.contactID); + if (options.limit && options.limit > 0) params.push("pageSize:" + options.limit); + if (options.page) params.push("pageNumber:" + options.page); return params; }; -AddressBook.prototype.chooseContact = function(successCallback, options) { +Contacts.prototype.chooseContact = function(successCallback, options) { this.choose_onSuccess = successCallback; var params = ["choose"]; params = this.formParams(options,params); PhoneGap.exec("contacts", params); }; -AddressBook.prototype.findContacts = function(successCallback, errorCallback, options) { - if (options.nameFilter && options.nameFilter.length > 0) { +Contacts.prototype.find = function(filter, successCallback, errorCallback, options) { + if (typeof(filter) != 'object') { + alert('[PhoneGap Error] filter parameter passed into navigator.contacts.find must be of type object.'); + return; + } + if (filter.name && filter.name.length > 0) { var params = ["search"]; + params.push('nameFilter:' + filter.name); params = this.formParams(options,params); this.search_onSuccess = successCallback; this.search_onError = errorCallback; PhoneGap.exec("contacts", params); } else { this.getAllContacts(successCallback,errorCallback,options); - return; } }; -AddressBook.prototype.getAllContacts = function(successCallback, errorCallback, options) { +Contacts.prototype.getAllContacts = function(successCallback, errorCallback, options) { this.global_onSuccess = successCallback; this.global_onError = errorCallback; var params = ["getall"]; params = this.formParams(options,params); PhoneGap.exec("contacts", params); -}; -AddressBook.prototype.addContact = function(contact, successCallback, errorCallback, options) { - if (!contact) { - alert("[PhoneGap Error] newContact function not provided with a contact parameter."); - return; - } else { - if (!contact.firstName || !contact.lastName || !contact.phoneNumber || !contact.address || !contact.email) { - alert("[PhoneGap Error] newContact function parameter 'contact' does not have proper contact members (firstName, lastName, phoneNumber, address and email)."); - return; - } - options.push("firstName:" + contact.firstName); - options.push("lastName:" + contact.lastName); - options.push("address:" + contact.address); - // Create a phone number parameter that we can parse on the BlackBerry end. - var phones = ''; - for (var i = 0; i < contact.phoneNumber.length; i++) { - phones += contact.phoneNumber[i].label + '='; - phones += contact.phoneNumber[i].value + '|'; - } - options.push("phoneNumber:" + phones.substr(0,phones.length-1)); - var emails = ''; - for (var j = 0; j < contact.email.length; j++) { - emails += contact.email[j].label + '='; - emails += contact.email[j].value + '|'; - } - options.push("email:" + emails.substr(0,emails.length-1)); - this.new_onSuccess = successCallback; - this.new_onError = errorCallback; - var params = ["new"]; - params = this.formParams(options,params); - PhoneGap.exec("contacts", params); - } }; \ No newline at end of file From 15afec15acb2a05d43815b1c4dde4831553ebc05 Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Mon, 30 Nov 2009 17:15:45 -0800 Subject: [PATCH 08/16] Updated Contacts API following the contacts API review meeting. Now should properly return new Contacts interface-based objects. --- .../phonegap/api/impl/ContactsCommand.java | 32 ++++++------------- blackberry/js/contacts.js | 18 +++++------ 2 files changed, 17 insertions(+), 33 deletions(-) diff --git a/blackberry/framework/src/com/nitobi/phonegap/api/impl/ContactsCommand.java b/blackberry/framework/src/com/nitobi/phonegap/api/impl/ContactsCommand.java index caa2009e..e775b9dd 100644 --- a/blackberry/framework/src/com/nitobi/phonegap/api/impl/ContactsCommand.java +++ b/blackberry/framework/src/com/nitobi/phonegap/api/impl/ContactsCommand.java @@ -49,7 +49,7 @@ public class ContactsCommand implements Command { private static final int REMOVE_COMMAND = 3; private static final int NEW_COMMAND = 4; private static final String CODE = "PhoneGap=contacts"; - private static final String CONTACT_MANAGER_JS_NAMESPACE = "navigator.AddressBook"; + private static final String CONTACT_MANAGER_JS_NAMESPACE = "navigator.contacts"; private static final String ERROR_NO_CONTACTID = ";alert('[PhoneGap Error] Contact ID not specified during contact removal operation.');"; @@ -279,7 +279,7 @@ private static void addContactToBuffer(StringBuffer buff, BlackBerryContact cont // TODO: Eventually extend this to return proper labels/values for differing phone/email types. buff.append("{"); if (contact.countValues(Contact.EMAIL) > 0) { - buff.append("email:[{'label':'mobile','value':'"); + buff.append("emails:[{'types':['mobile'],'address':'"); buff.append(contact.getString(Contact.EMAIL, 0)); buff.append("'}]"); } @@ -300,7 +300,7 @@ private static void addContactToBuffer(StringBuffer buff, BlackBerryContact cont } if (sentinel) { if (buff.length() > 1) buff.append(","); - buff.append("phoneNumber:[{'label':'mobile','value':'"); + buff.append("phoneNumber:[{'types':['mobile'],'number':'"); buff.append(phoneMobile); buff.append("'}]"); } @@ -308,30 +308,16 @@ private static void addContactToBuffer(StringBuffer buff, BlackBerryContact cont // See if there is a meaningful name set for the contact. if (contact.countValues(Contact.NAME) > 0) { if (buff.length() > 1) buff.append(","); - buff.append("firstName:'"); + buff.append("name:{"); + buff.append("givenName:'"); final String[] name = contact.getStringArray(Contact.NAME, 0); final String firstName = name[Contact.NAME_GIVEN]; final String lastName = name[Contact.NAME_FAMILY]; - buff.append((firstName != null ? firstName : "") + "',lastName:'"); + buff.append((firstName != null ? firstName : "") + "',familyName:'"); buff.append((lastName != null ? lastName : "") + "'"); - } - if (buff.length() > 1) buff.append(","); - buff.append("address:'"); - // Build up a meaningful address field. - if (contact.countValues(Contact.ADDR) > 0) { - String address = ""; - final String[] addr = contact.getStringArray(Contact.ADDR, 0); - final String street = addr[Contact.ADDR_STREET]; - final String city = addr[Contact.ADDR_LOCALITY]; - final String state = addr[Contact.ADDR_REGION]; - final String country = addr[Contact.ADDR_COUNTRY]; - final String postalCode = addr[Contact.ADDR_POSTALCODE]; - if (street!=null) address = street.replace('\'',' '); - if (city!=null) if (address.length() > 0) address += ", " + city.replace('\'',' '); else address = city.replace('\'',' '); - if (state!=null) if (address.length() > 0) address += ", " + state.replace('\'',' '); else address = state.replace('\'',' '); - if (country!=null) if (address.length() > 0) address += ", " + country.replace('\'',' '); else address = country.replace('\'',' '); - if (postalCode!=null) if (address.length() > 0) address += ", " + postalCode.replace('\'',' '); else address = postalCode.replace('\'',' '); - buff.append(address); + String formatted = (firstName != null ? firstName : ""); + formatted += (lastName != null? " " + lastName : ""); + buff.append(",'formatted':'" + formatted + "'}"); } buff.append("'}"); } diff --git a/blackberry/js/contacts.js b/blackberry/js/contacts.js index b41395f7..345e61b4 100644 --- a/blackberry/js/contacts.js +++ b/blackberry/js/contacts.js @@ -4,18 +4,16 @@ */ function Contact(jsonObject) { - this.firstName = ""; - this.lastName = ""; - this.name = ""; - this.phones = {}; - this.emails = {}; - this.address = ""; + this.name = { + formatted:'' + }; + this.phones = []; + this.emails = []; + this.id = ""; } -Contact.prototype.displayName = function() -{ - // TODO: can be tuned according to prefs - return this.name; +Contact.prototype.displayName = function() { + return this.name.formatted; } function Contacts() { From a828fabc500285eb187b32d90158d44883139891 Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Mon, 30 Nov 2009 17:19:35 -0800 Subject: [PATCH 09/16] Added build.xml to PhoneGap BlackBerry repository. Allows you to build BlackBerry application binaries from source using Apache Ant and BB Ant Tools (google it). --- blackberry/framework/build.xml | 68 ++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 blackberry/framework/build.xml diff --git a/blackberry/framework/build.xml b/blackberry/framework/build.xml new file mode 100644 index 00000000..126834fa --- /dev/null +++ b/blackberry/framework/build.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 2dcba1597c0aa76fddb381994db20351f6381320 Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Mon, 30 Nov 2009 17:34:34 -0800 Subject: [PATCH 10/16] Updated README with new Ant build instructions, expanded instructions on setting up fresh BlackBerry project in Eclipse. --- blackberry/README.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/blackberry/README.md b/blackberry/README.md index cbdcfb8e..5dd002a7 100644 --- a/blackberry/README.md +++ b/blackberry/README.md @@ -15,4 +15,31 @@ Create a PhoneGap project with Eclipse ------------------------------------------------------------- 1. Launch Eclipse, go to File->Import->Existing BlackBerry project. 2. Navigate over to where you cloned the git repo, and point it to the phonegap.jdp file located in blackberry/framework/. -3. Modify the contents of the "www" directory to add your own HTML, CSS and Javascript. \ No newline at end of file +3. Modify the contents of the "www" directory to add your own HTML, CSS and Javascript. +4. Before running, right-click on project root and make sure 'Activate for BlackBerry' is checked. +5. Run or debug from Eclipse as desired. +6. When you are satisfied with the application, make sure you sign it! (BlackBerry menu -> Request Signatures) + This step needs to be done every time you change your source code. If you are running in simulator, you do not need + to sign your binaries - it is only necessary for deployment to actual devices. +7. A few ways to deploy to device: + a) Right-click on the project root in Eclipse and click on 'Generate ALX file.' You can then use this + file in RIM's Desktop Manager software to load the binaries directly onto the device. + b) Use the javaloader.exe program that comes with the JDE component packs to load directly onto device. Usage: + javaloader -u load path/to/codfile.cod + The -u parameter specifies loading via USB. + c) Over-the-air installation. Set up your application .jad, .jar and .cod files onto a web server. See RIM's documentation + for more details or this succinct PDF for info: http://assets.handango.com/marketing/developerTeam/BlackBerryOTADeployment.pdf + +Building PhoneGap BlackBerry Projects with Apache Ant +------------------------------------------------------------- +You'll need all the prerequisites listed by BB Ant Tools (http://bb-ant-tools.sourceforge.net/). +1. Once you have cloned the PhoneGap repository, put your HTML, CSS and JavaScript application files in the phonegap/blackberry/framework/src/www folder. +2. Edit the build.xml file in phonegap/blackberry/framework and set the paths at the top of the file, in the elements, to match + your environment setup. +3. Open up a command-line and, assuming you have Ant on your system PATH, cd over to phonegap/blackberry/framework directory. +4. Run 'ant' from the command-line. It'll default to the 'build' task, which will build your binaries. You can also explicitly specify other tasks to run: + a) 'ant sign': Runs the 'build' task first, and then runs the signature tool on the compiled binary. Make sure to specify the 'password' + property at the top of the build.xml file, otherwise the signature tool will fail! + b) 'ant load-simulator': Runs the 'sign' task first, then copies the signed binaries over to the simulator directory you specified at the top of the + build.xml. When you run the simulator, you should see your application under the BB Menu -> Downloads. + c) 'ant load-device': Runs the 'sign' task first, then executes the javaloader tool to load the signed binaries onto an attached (via USB) device. \ No newline at end of file From 30ff75245fb7848bd761bd2185e57a83475b189c Mon Sep 17 00:00:00 2001 From: shazron Date: Tue, 1 Dec 2009 11:20:45 -0800 Subject: [PATCH 11/16] Added Plugins group to template, for adding Plugins --- .../___PROJECTNAME___.xcodeproj/project.pbxproj | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/iphone/PhoneGap-based Application/___PROJECTNAME___.xcodeproj/project.pbxproj b/iphone/PhoneGap-based Application/___PROJECTNAME___.xcodeproj/project.pbxproj index 0f655be3..449976e6 100755 --- a/iphone/PhoneGap-based Application/___PROJECTNAME___.xcodeproj/project.pbxproj +++ b/iphone/PhoneGap-based Application/___PROJECTNAME___.xcodeproj/project.pbxproj @@ -98,7 +98,7 @@ 1D3623250D0F684500981E51 /* ___PROJECTNAMEASIDENTIFIER___AppDelegate.m */, ); path = Classes; - sourceTree = ""; + sourceTree = SOURCE_ROOT; }; 19C28FACFE9D520D11CA2CBB /* Products */ = { isa = PBXGroup; @@ -114,6 +114,7 @@ 301BF56E109A69640062928A /* www */, 301BF52D109A57CC0062928A /* PhoneGapLib.xcodeproj */, 080E96DDFE201D6D7F000001 /* Classes */, + 307C750510C5A3420062BCA9 /* Plugins */, 29B97315FDCFA39411CA2CEA /* Other Sources */, 29B97317FDCFA39411CA2CEA /* Resources */, 29B97323FDCFA39411CA2CEA /* Frameworks */, @@ -167,6 +168,13 @@ name = Products; sourceTree = ""; }; + 307C750510C5A3420062BCA9 /* Plugins */ = { + isa = PBXGroup; + children = ( + ); + path = Plugins; + sourceTree = SOURCE_ROOT; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ From faddcaaa82695f7307c5be71166e06f52a985ec2 Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Tue, 1 Dec 2009 13:32:39 -0800 Subject: [PATCH 12/16] Fixed build script. --- blackberry/README.md | 1 + blackberry/framework/build.xml | 4 ++-- blackberry/framework/src/www/phonegap.js | 18 ++++++++---------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/blackberry/README.md b/blackberry/README.md index 5dd002a7..4a30385a 100644 --- a/blackberry/README.md +++ b/blackberry/README.md @@ -33,6 +33,7 @@ Create a PhoneGap project with Eclipse Building PhoneGap BlackBerry Projects with Apache Ant ------------------------------------------------------------- You'll need all the prerequisites listed by BB Ant Tools (http://bb-ant-tools.sourceforge.net/). + 1. Once you have cloned the PhoneGap repository, put your HTML, CSS and JavaScript application files in the phonegap/blackberry/framework/src/www folder. 2. Edit the build.xml file in phonegap/blackberry/framework and set the paths at the top of the file, in the elements, to match your environment setup. diff --git a/blackberry/framework/build.xml b/blackberry/framework/build.xml index 126834fa..b2aa38e5 100644 --- a/blackberry/framework/build.xml +++ b/blackberry/framework/build.xml @@ -12,7 +12,7 @@ - + @@ -36,7 +36,7 @@ - + diff --git a/blackberry/framework/src/www/phonegap.js b/blackberry/framework/src/www/phonegap.js index 790fcb61..5b331824 100644 --- a/blackberry/framework/src/www/phonegap.js +++ b/blackberry/framework/src/www/phonegap.js @@ -172,18 +172,16 @@ if (typeof navigator.camera == "undefined") navigator.camera = new Camera(); */ function Contact(jsonObject) { - this.firstName = ""; - this.lastName = ""; - this.name = ""; - this.phones = {}; - this.emails = {}; - this.address = ""; + this.name = { + formatted:'' + }; + this.phones = []; + this.emails = []; + this.id = ""; } -Contact.prototype.displayName = function() -{ - // TODO: can be tuned according to prefs - return this.name; +Contact.prototype.displayName = function() { + return this.name.formatted; } function Contacts() { From 1868917a2c0e4bcaa75a8c24faf0ffb5ca8ffa11 Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Tue, 1 Dec 2009 13:41:20 -0800 Subject: [PATCH 13/16] Tweaked build script to launch simulator properly now. Added more directions and clarification to BlackBerry readme. --- blackberry/README.md | 7 ++++--- blackberry/framework/build.xml | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/blackberry/README.md b/blackberry/README.md index 4a30385a..f6d325eb 100644 --- a/blackberry/README.md +++ b/blackberry/README.md @@ -36,11 +36,12 @@ You'll need all the prerequisites listed by BB Ant Tools (http://bb-ant-tools.so 1. Once you have cloned the PhoneGap repository, put your HTML, CSS and JavaScript application files in the phonegap/blackberry/framework/src/www folder. 2. Edit the build.xml file in phonegap/blackberry/framework and set the paths at the top of the file, in the elements, to match - your environment setup. + your environment setup. Also be sure to set your signature key password in the password . 3. Open up a command-line and, assuming you have Ant on your system PATH, cd over to phonegap/blackberry/framework directory. -4. Run 'ant' from the command-line. It'll default to the 'build' task, which will build your binaries. You can also explicitly specify other tasks to run: +4. Run 'ant' from the command-line. It'll default to the 'build' task, which will build your binaries into the 'build' directory. You can also + explicitly specify other tasks to run: a) 'ant sign': Runs the 'build' task first, and then runs the signature tool on the compiled binary. Make sure to specify the 'password' property at the top of the build.xml file, otherwise the signature tool will fail! b) 'ant load-simulator': Runs the 'sign' task first, then copies the signed binaries over to the simulator directory you specified at the top of the - build.xml. When you run the simulator, you should see your application under the BB Menu -> Downloads. + build.xml and finally runs the simulator. You should see your application under the BB Menu -> Downloads. c) 'ant load-device': Runs the 'sign' task first, then executes the javaloader tool to load the signed binaries onto an attached (via USB) device. \ No newline at end of file diff --git a/blackberry/framework/build.xml b/blackberry/framework/build.xml index b2aa38e5..e1e94695 100644 --- a/blackberry/framework/build.xml +++ b/blackberry/framework/build.xml @@ -55,8 +55,9 @@ - + + From bb28329ab882502bcb0d3812bf332ebb3030be5f Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Tue, 1 Dec 2009 14:13:34 -0800 Subject: [PATCH 14/16] Fixed bad instantiation of Geo command. --- blackberry/README.md | 3 ++- .../framework/src/com/nitobi/phonegap/api/CommandManager.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/blackberry/README.md b/blackberry/README.md index f6d325eb..33a81d95 100644 --- a/blackberry/README.md +++ b/blackberry/README.md @@ -32,7 +32,8 @@ Create a PhoneGap project with Eclipse Building PhoneGap BlackBerry Projects with Apache Ant ------------------------------------------------------------- -You'll need all the prerequisites listed by BB Ant Tools (http://bb-ant-tools.sourceforge.net/). +You'll need all the prerequisites listed by BB Ant Tools (http://bb-ant-tools.sourceforge.net/). If you want access to building using Ant from Eclipse, +check out http://www.slashdev.ca/2007/05/30/blackberry-development-with-ant-eclipse/ for instructions on how to do it. 1. Once you have cloned the PhoneGap repository, put your HTML, CSS and JavaScript application files in the phonegap/blackberry/framework/src/www folder. 2. Edit the build.xml file in phonegap/blackberry/framework and set the paths at the top of the file, in the elements, to match diff --git a/blackberry/framework/src/com/nitobi/phonegap/api/CommandManager.java b/blackberry/framework/src/com/nitobi/phonegap/api/CommandManager.java index 0d4f0490..63e7b79f 100644 --- a/blackberry/framework/src/com/nitobi/phonegap/api/CommandManager.java +++ b/blackberry/framework/src/com/nitobi/phonegap/api/CommandManager.java @@ -51,7 +51,7 @@ public CommandManager(PhoneGap phoneGap) { commands[1] = new ContactsCommand(); commands[2] = new NotificationCommand(); commands[3] = new TelephonyCommand(); - commands[4] = new GeoLocationCommand(); + commands[4] = new GeoLocationCommand(phoneGap); commands[5] = new DeviceCommand(); commands[6] = new MediaCommand(); commands[7] = new NetworkCommand(phoneGap); From 46078a4029d1abf4b10764f94e8bfce276d532bb Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Tue, 1 Dec 2009 14:21:46 -0800 Subject: [PATCH 15/16] Added property in BlackBerry build.xml to specify application name. --- blackberry/framework/build.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/blackberry/framework/build.xml b/blackberry/framework/build.xml index e1e94695..1efc1f26 100644 --- a/blackberry/framework/build.xml +++ b/blackberry/framework/build.xml @@ -13,6 +13,8 @@ + + @@ -28,7 +30,7 @@ - + From 73b0b7642f528ede38efafe6f155e56bc47f0406 Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Tue, 1 Dec 2009 14:56:52 -0800 Subject: [PATCH 16/16] How many times do I have to fix the casing on the Device JS object? --- .../phonegap/api/impl/DeviceCommand.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/blackberry/framework/src/com/nitobi/phonegap/api/impl/DeviceCommand.java b/blackberry/framework/src/com/nitobi/phonegap/api/impl/DeviceCommand.java index 24b9499b..5debc789 100644 --- a/blackberry/framework/src/com/nitobi/phonegap/api/impl/DeviceCommand.java +++ b/blackberry/framework/src/com/nitobi/phonegap/api/impl/DeviceCommand.java @@ -35,15 +35,15 @@ public class DeviceCommand implements Command { private static final String CODE = "PhoneGap=initialize"; private static final String EMULATOR = "Emulator"; - private static final String DEVICE_NAME = ";Device.name = '"; - private static final String DEVICE_FLASH = "';Device.flash = "; - private static final String DEVICE_PLATFORM = ";Device.platform = '"; - private static final String DEVICE_VENDOR = "';Device.vendor = '"; - private static final String DEVICE_BATTERY = "';Device.battery = "; - private static final String DEVICE_VERSION = ";Device.version = '"; - private static final String DEVICE_SIMULATOR = "';Device.isSimulator = "; - private static final String DEVICE_CAMERA = ";Device.hasCamera = "; - private static final String DEVICE_UUID = ";Device.uuid = "; + private static final String DEVICE_NAME = ";device.name = '"; + private static final String DEVICE_FLASH = "';device.flash = "; + private static final String DEVICE_PLATFORM = ";device.platform = '"; + private static final String DEVICE_VENDOR = "';device.vendor = '"; + private static final String DEVICE_BATTERY = "';device.battery = "; + private static final String DEVICE_VERSION = ";device.version = '"; + private static final String DEVICE_SIMULATOR = "';device.isSimulator = "; + private static final String DEVICE_CAMERA = ";device.hasCamera = "; + private static final String DEVICE_UUID = ";device.uuid = "; private static final String SEMI_COLON = ";"; /**