Another post about PhoneGap 3.0! So - I don't work with plugins a lot. I play with them every now and then, but I would certainly not consider myself an expert. Therefore, most of what I'm about to share here may be common knowledge, and if so, great, but I lost an hour or so yesterday trying to understand how to install a plugin via the command line and I figured a quick overview may help others.
As you know, PhoneGap 3 made it so that all of the core features (accelerometer, camera, etc) were plugins. To use those features you first had to add the plugin to your project. Luckily, this is rather easy to do at the command line. So for example, here is how you add Camera support:
phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git
Until yesterday, I had not tried this with a custom plugin. The last time I worked with a plugin the process was roughly like so (and this was for Android):
- Download the bits, typically a Java file (or files) and a JavaScript file.
- Place the Java bits in the right src folder.
- Place a copy of the JS file in my assets folder.
- Include the JS file in my index.html.
- Make the appropriate calls to my plugin.
In PhoneGap 3, you can use the same command to add a custom plugin as you would use a regular core plugin. The plugin must be compatible (I'm ignoring that aspect for this blog post as I assume the reader is concerned with installing and not creating plugins) with 3.0. For my tests, I made use of the Speech Synthesis plugin by Simon MacDonald. This plugin supports basic TTS and is pretty cool, but note that the docs aren't quite ready yet. They will be soon. For now, I'm just using it because a) it is pretty simple and b) I can bug Simon on IM for help.
So - to install it, I'd run this at the command line:
phonegap local plugin add https://github.com/macdonst/SpeechSynthesisPlugin
It should "just work", note though that the CLI doesn't recognize what platforms your plugin supports. So for example, the SpeechSynthesis plugin only supports Android (iOS support is forthcoming), but unless you knew that ahead of time, you would have no idea. Keep that in mind.
At this point, I looked into my plugins folder:

My assumption at this point was to copy all the JS files into my www folder and add script tags to my index.html.
That is not necessary!
In 3.0 (see footnotes), the build process not only handles copying the Java file over, it copies the JavaScript and injects it into your HTML. Basically, I don't have to do anything special on the HTML side to make use of my plugin. That kicks ass! But I wish I had known that earlier. You can literally just start using the plugin after deviceready has fired:
var u = new SpeechSynthesisUtterance();
u.text = "You know you're going to make the app say something naughty.";
u.lang = 'en-US';
speechSynthesis.speak(u);
Some Notes:
-
My understanding is that the ability to install plugins via the command line is actually part of the "plugman" project which is older than 3.0. So part of what I'm talking about here may not be necessarily "new", but it was new to me. I'm definitely willing to be corrected here, but I assume this particular usage is something many folks may not try until 3.0.
-
I mentioned that Simon's plugin isn't documented quite yet. That will be corrected very soon. But the plugin actually follows the W3C API for Speech Synthesis (you knew they had one, right?) and you can find out more here: Speech Synthesis
Archived Comments
I will be using Phonegap 3 and a bluetooth plugin for an app that I've been planning. Your post answers some questions about plugins that I have not had time to research yet.
Thanks!
My pain is your gain. ;)
Can you direct me to something that explains what the heck the "plugman project" is? I know it is on github, but I don't really understand what it is. Has it just been incorporated into PhoneGap cli? Is it something I have to use via cli?
Thanks
Michael - please take this with a LARGE grain of salt:
My understanding is that if plugins follow a particular API and have a proper XML file, they can be installed via plugman. So basically, it is more than just making a PG plugin, it's creating a way so that it can be installed via the CLI.
I *believe* the phonegap CLI is using plugman under the hood. Frankly it doesn't matter to me as it just plain works, but I'll try to get a real answer for you.
Ok. If it is under the hood I don't care so much either. I just wasn't clear if I was supposed to be doing something with plugman.
Are there any implications/tips if using PG Build?
PS - Thank you for your continued coverage of things that keep us awake at night.
PGB doesn't support 3.0... yet. But it is coming soon.
i am working with android phonegap, and is trying to implement twitter login to my android application , but cannot find a way to do so;howmuchever I tried.Please help me.
Sorry, I've not had a chance yet to do Twitter auth with PhoneGap. Best I can recommend is to Google for it.
Using node.js to install phonegap is confusing, you should go back to a regular package in a zip file. The npm folder where phonegap gets installed is in the C:\Users\my\AppData\Roaming or maybe the AppData local folder for some.
The Phonegap build folder for cloud should come as a seperate installation
I had phonegap build phonegap this and that in the npm folder and in the npm cache folder. There was also different android files and folders in all of them.
Kind of reminds me of some Zend folders that I was using that were 14 levels deep just to store one .css file or one flower picture. Personally I would rather find and search through a few folders for multiple files than get lost in a 2000 folders, 20 levels deep MVC Node framework; too me that is the 9th circle of Hell
There is way way too much ambiguity in the folder directory traversal with node.js and phonegap. Here is an example in windows 7
C:\Users\me\AppData\Roaming\npm\node_modules\phonegap\node_modules
\cordova\node_modules\npm\node_modules\read-installed\test
The way that everything is stored and personally navigating between all these hundreds of folders makes me as a developer want to put a Gun in my Mouth!!
Comments inline:
"Using node.js to install phonegap is confusing, you should go back to a regular package in a zip file. The npm folder where phonegap gets installed is in the C:\Users\my\AppData\Roaming or maybe the AppData local folder for some. "
I do NOT speak for the PhoneGap team. But this is not going to happen. To your second sentence - where npm installs phonegap shouldn't typically be a concern. npm handles making it available as a command line program. You should be able to run "phonegap" in CMD or Terminal and not be concerned where it explicitly installed the bits. If you are, npm is fairly standard about where it installs stuff.
"The Phonegap build folder for cloud should come as a seperate installation "
I thin that would be a huge mistake. With one command you can build locally or via the cloud. I think that's awesome.
"I had phonegap build phonegap this and that in the npm folder and in the npm cache folder. There was also different android files and folders in all of them."
Not to sound crass, but why do you care? Part of the coolness of npm is that it handles dependancies for you. So if phonegap the tool needs Foo the tool, it will fetch it as well. Who cares? Let npm worry about downloading the bits and dependancies and just *use* the tool.
The rest of your comment is concerned about so I'll just repeat myself: Why do you care about the bits *behind* phonegap the CLI? You don't need to be to use it.
"I think that would be a huge mistake. With one command you can build locally or via the
cloud. I think that's awesome."
Ok I'll give you that one. My opinion is I just like choice to keep things minimal
"Not to sound crass, but why do you care? Part of the coolness of npm is that it handles
dependencies for you. So if phonegap the tool needs Foo the tool, it will fetch it as well. Who
cares? Let npm worry about downloading the bits and dependencies and just *use* the tool."
I have used node.js before and a developer forgot to connect to another person's
git and left dependencies out in the makefile that pointed to build.js.
I had to go find eventemitter.js, binarypack.js and reliable.js on github from three different
developers and then rebuild.
I ran linux in servers with the command line only installing things and doing make files it would do the same thing sometimes as node.js and install things in the folders of its choosing. Later when I wanted to go find out where one of the mysql config files went so I could cross reference it with with a percona server file lo and behold I could not find it until doing some extensive cd'ing, find /tmp /var/tmp . $HOME -name fooing , grepping and switching back and forward to in the cpanel file directory. Thank god for Cpanel, I would have spent way to much time typing in the CL instead of just clicking in the cpanel file directory.
The "Coolness" is not so cool to me when I would like to inspect the "bits"(files) and
possibly modify or extend them, but then get sick of traversing through bunches of 20 level
deep folders. I like things neat and organized it's just me and when I see the way node.js
handles folders it is overkill too me.
Example
\npm\node_modules\phonegap\node_modules\cordova\node_modules\npm\node_modules\read-installed\test\somefile.js
The above should just be
\npm\node_modules\phonegap\read-installed\somefile.js
For set it and forget it people I can see your point. But for people like me I hope you see
my point. You didnt sound crass.
@Ryan: So would it be fair to say - you are interested in the *source* of phonegap CLI and want to dig into that more? If so - then I would NOT install from npm and get the source directly.
If so... let me know. The cordova stuff is very easy to find. I'm not sure where the phonegap CLI is in GitHub.
I really appreciate this article. Your stuff about phonegap has really helped me understand the changes in 3.0. But right now I'm having a hard time converting a plugin that works with 2.9 to work with phonegap 3.x. I forked the project here to try to get it working. I'd appreciate any help. Thanks.
https://github.com/aharris8...
Unfortunately I've never written a plugin. I do know that my coworker, Holly Shinsky, is updating a plugin for 3.0 and is planning on blogging it. Her blog is: http://devgirl.org/. She isn't on IM now so I can't ask her status, but I know it is in the works.
Thanks, I've been following her blog as well.
The bigger issue i see with CLI is that some nice plugins that were written for pre-3.0 era (like LocalNotification for instance in gitHub)...are not yet CLI-ready and therefore not accessible thru plugman.
No plugin.xml to these pre-3.0 plugins, therefore cordova/phonegap/plugman all fail the install
So we're on our own to add them manually to the config.xml and the plugins directory. Not tried it yet.
Unless someone has done this already and can share info?
"The bigger issue i see with CLI is that some nice plugins that were written for pre-3.0 era (like LocalNotification for instance in gitHub)...are not yet CLI-ready and therefore not accessible thru plugman."
Which - to be clear - is an issue for the plugin author, not PhoneGap. I know that isn't helpful, but to be fair, when the platform updates, it is up to the individual author to handle the changes.
Can you please elaborate this part:
".. note though that the CLI doesn't recognize what platforms your plugin supports."
Does this mean phonegap cli will inject plugin in all platforms you decide to support? I understand that obviously Java code won't work with iOS so native souce files won't be added, but what about javascript includes?
Thanks
Zoran, in the plugin, there is a file called plugin.xml that has instructions for how the phonegap cli is supposed to install it, and it specifies what platforms it supports and where to put the platform specific files. For example, in the Speech Synthesis plugin it has a platform tag with the attribute name="android" and inside that tag it specifies where to put the java files and how to alter the res/xml/config.xml file. It can also specify how to alter the AndroidManifest file. The javascript files should be the same for all platforms so they're specified outside of the platforms tag in plugin.xml.
Hey,
I'm new to PG 3.0, but not to Phonegap. I kinda liked the CLI approach. Here is what I tried and built for PG 3.1 and it is not working.. Can you guess why? I'm sure this line is the problem. I'm sure that I've downloaded the plugin and it is there in the plugins folder. I didnt need to add anything to the index.html folder right?
onDeviceReady: function() {
alert('onDeviceReady');
app.speakNow();
app.receivedEvent('deviceready');
},
//Speak now
speakNow: function(){
alert('speakNow-BEGIN');
var u = new SpeechSynthesisUtterance();
u.text = "You know you're going to make the app say something naughty.";
u.lang = 'en-US';
speechSynthesis.speak(u);
alert('speakNow-END');
},
// Update DOM on a Received Event
receivedEvent: function(id) {
alert('receivedEvent');
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}
Any help would be appreciated.
Can you say where it didn't work? Did anything get logged?
How are plugin updates handled? If I upgrade the core phonegap with the npm command, does it also update the plugins or do I do these independently?
Thanks!
From what I know you rm them then add them - so 2 quick command lines (well, 2 per).
ahhh - thought there would be something more integrated...thanks!
Does anyone know of a good list of 3.x plugins?
Justin
How about plugins.cordova.io?
There is also: plugreg.com
So, I guess the answer is no. :) I would require a list to have descriptions of what the plugin actually does to consider it good.
Thanks anyways
Hi! I've been working on this for a while now and I got this error:
https://fbcdn-sphotos-c-a.a...
What does this mean? I can't seem to troubleshoot this.
sorry about the broken link.
Here it is: http://rencamp.tk/data/uplo...
It looks to be related to the SpeechSynthesis plugin. I'd check with that author.
Hi raymond, I'm also migrating a project to cordova 3 which used the TTS plugin and I'm having more than an issue making it work again, the lack of documentation is not helping,
do you have a working sample, even an HelloWorld project, of the plugin running?
I placed the snippet you stated in a *ttsTest* function called by *receivedEvent* after the *onDeviceReady* has been fired, my whole index.js is as follow :
_________________________
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicity call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
// ctrl.init();
},
// Update DOM on a Received Event
receivedEvent: function(id) {
// var parentElement = document.getElementById(id);
// var listeningElement = parentElement.querySelector('.listening');
// var receivedElement = parentElement.querySelector('.received');
//
// listeningElement.setAttribute('style', 'display:none;');
// receivedElement.setAttribute('style', 'display:block;');
//
// console.log('Received Event: ' + id);
*app.ttsTest();*
},
*ttsTest*: function() {
var u = new SpeechSynthesisUtterance();
u.text = "You know you're going to make the app say something naughty.";
u.lang = 'en-US';
speechSynthesis.speak(u);
}
};
app.initialize();
_________________________
however it seems to fail silently, nothing appears in the logcat of the webview, I did tried to log a test message coming from the function and it does get printed, just clueless about what goes wrong :\
Of *that* plugin? No - I haven't used it for a while. I'd suggest Simon's instead.
Nope i meant for speechSynthesis, TTS plugin is from Simon too (https://github.com/macdonst... but for cordova 2.9, I'm trying to use the speechSynthesis plugin for cordova 3 but using the following snippet didn't result in a speech action of the smartphone :
_
var u = new SpeechSynthesisUtterance();
u.text = "You know you're going to make the app say something naughty.";
u.lang = 'en-US';
speechSynthesis.speak(u);
_
you wrote that this would work after deviceReady still it seems to fail without any error in logcat
Oh, sorry, misunderstood you. Have you tried contacting him about a 3.0 version?
Mmmm ok now this is interesting, just tryed to change the language locale passed with the utterance to match my device language, 'it', and it worked...
I do remember that with the previous TTS plugin I could set a different speech language not matching the one of the device...why would it not work anymore? :\
I'm running test on a Galaxy Note 2, the voice that spoke in italian is the one of the Samsung TTS which also support english and which worked with tts plugin so it's not the tts software missing the voice for the english language...
Ok figured out the problem, not the locale but the timing of initialization for the TTS engine,
in the previous plugin there is the *startup* function wich inits the TTS engine and with its succes callback ensures that any *speak* action is correctly executed :
https://github.com/macdonst...
in SpeechSynthesis instead the start action is delegated to the speak action instead, meaning that with the first utterance you also start the engine,
https://github.com/macdonst...
but this means that you don't know exactly how much it will take for the action to take place, in my case it seems that the utterance is not executed even after the TTS has been activated, just tryed to exit and re-enter fast the app and it would speak only after a couple of tentatives,
I guess I'll push this issue to Simon (maybe he knows already)
Yeah, I'd recommend filing a bug. (And if things get fixed, can you let us know here. :)
Hi! I stuck here... in some articles i read thats i need to add the gap:plugin tag in the config.xml file in order to the plugins work. But in others articles i read that i need to add the feature tag! Here you say that only i need the command phonegap local plugin add...
Im confused!
Thanks a lot Raymond! :)
Carlos it depends on if you are building locally or via Build. If you are doing locally, you should not have to edit the files at all - as I said above.
Raymond have you ever deleted your iOS platform folder and then done a build iOS? I have done this and now none of my plugins work. They never get rebuilt in the project. I tried simply dragging them into the folder and that did not work. I added via Xcode to the project and that did not work. I get a lot of errors.
I also tried re-adding via CLI and that doesn't work.
No, I have not. I have used the 'remove' feature via the CLI. If you didn't do that then you probably did something wrong (*) and you should maybe just build a virgin project at the CLI and copy over your assets.
* To be clear, I'm not saying it is your fault per se, but that you were maybe not supposed to do that?
Do you do 'remove' of the project? Is that documented somewhere?
At the CLI help, yes. Type "cordova" and you will see it.
remove is not phonegap command, so if we are using phone gap how do we do it?
and......
sbceras-mbp:SBCERAApp Good SBCERA$ cordova remove android
/usr/local/lib/node_modules/cordova/src/cli.js:112
throw new Error('Cordova does not know ' + cmd + '; try help for a lis
^
Error: Cordova does not know remove; try help for a list of all the available commands.
at new CLI (/usr/local/lib/node_modules/cordova/src/cli.js:112:15)
at Object.<anonymous> (/usr/local/lib/node_modules/cordova/bin/cordova:41:16)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
@Michael: Sorry - I thought you were using the Cordova CLI. As to your second post, see the Cordova CLI help. It isn't "cordova remove android" but "cordova platforms remove android"
@Simone Rescio
Yes, please file an issue on GitHub for me. I believe that the engine should start up when the SpeechSynthesis.js file is parsed.
Raymond do you know if there is a way to switch from phonegap to cordova with an existing project?
Hmm. I haven't tried using both CLIs in one project. It may or may not work. Honestly, I'd make a new project and just copy www over. Seems like it would be easiest. (imo)
Can you please help me to install one of yours plugin https://github.com/macdonst... via the cordova plugin add command, on phonegap 3.3 I am actually facing a lot of problems in installing the plugin. Else please provide me with a detailed procedure on how to install this plugin...
Did you mean me? That isn't my plugin. Simon is on this thread though so he may be able to help.
Can u please help, I want the IMEI number of the device using phonegap, can you tell me how to do so, I don't know how to do in Phonegap.
I need to update this plugin, actually many of my plugins to 3.x compliance. I've just added it to my to do list. Shouldn't take a ton of time. Hope to get to it this weekend.
Thanks a ton for all your help :)
Anyone know if Cordova CLI pushes down latest plugin files on each "cordova build" call by default? If not is there a param to force that? The plugin rm/plugin add is super tedious and prevents makes it really hard to test out local plugin changes.
I'm not sure I get you. If you do plugin add, it fetches it remotely, so it is always latest. The build operation is just copying stuff over so it will NOT get the latest bits. But honestly - how often do you think the plugins are being updated? Looking at the Dialogs plugin, it was last updated 14 days ago.
Thanks Raymond. I was updating a plugin locally to use a background thread for IOS but kept wondering why my Plugin.m file wasn't being pushed down to /platforms/ios each build. I guess you answered that - plugins don't get pushed down each build.
Just for sake of pointing it out - if I had a custom plugin and wanted to test some plugin changes I would - based on how Cordova CLI is setup - have to:
- Commit my local plugin changes to GitHub (or wherever)
- Then do a cordova plugin rm,
- Then do a cordova plugin add
- Then run my app in device/simulator.
Unless I'm missing something - based on the above it sure would be nice if a simple 'cordova build ios' simply pushed plugin changes from /plugins/PLUGIN to /platforms/[platform]/plugins for me.
Maybe I'm doing it wrong?
Oh, so you were actually modifying the source code of the plugin locally. That's not something I've done when using the CLI. I'm not sure I'd use the CLI. I mean I'd use it to start the project, but then I'd switch to the editor for the platform my plugin is working with (well the platform I'm working on). I'd use XCode for an iOS plugin for example.
This questions seems kind of simple to me and I've wondered it myself. I have a project that uses several plugins. I usually try to update the Cordova core when a new version comes out. I run the CLI command to do that. How do we do the same thing with plugins? How do we update our plugins to use the latest version?
I believe the procedure is to rm then re-add.
Thanks so much for posting this! I was trying and trying to get this working and didn't realize all I had to do was call:
var u = new SpeechSynthesisUtterance();
Would you be able to describe how you knew that's how you interact with the plugin? I am trying to wrap my head around interacting with plugins, and it's quite confusing.
Thanks!
To be honest I don't remember, but I'm friends w/ Simon so I may have just asked him on IM.
I'm wondering if anyone has any advice regarding using PhoneGap to send and receive information from a web server. Is there a standard way of doing this? Any best practices? I'm pretty new to app development and any advice would be helpful
Ajax. Seriously - it is that simple. :)
As for 'best practices' - well - the "typical" advice would apply here. By typical I mean the similar advice for any app using Ajax. Be careful what you send over the wire and be careful how much you send over the wire.
I'm working on a custom PhoneGap plugin and I'm wondering exactly what some of the other commenters are wondering. What's the workflow for modifying plugins and then running the app for testing locally? It seems that most of the information online is focused around using third party plugins..
I've posted in SO here, in case anybody wants to take a stab at answering http://stackoverflow.com/qu...
Hi,
I find this plugin just amazing. I have a problem trying to retrieve all the available languages. I could add the in SpeechsSnthesis java but I want to be able to populate a combo box in my App with the available languages, how can access the list from javascript? Can anyone help?
MAny thanks in advance
Hello Sir
I developed a plugin for android and in which i would like to call javascript function myfunction()
ealier i was using webView.sendJavascript(<js function="" to="" call="">)
but now it says deprecated and is also not working. Could you please help out
Did you read the plugin development guide? http://cordova.apache.org/d...
Yes sir i did read the plugin guide, but that does not provide me information on alternate to sendjavascript.
Later i found
webView.loadUrl("javascript:functionname")
to be working
but
when i get the error
[INFO:CONSOLE(927)] "Uncaught Error: Error calling method on NPObject.", source: file:///android_asset/www/cordova.js (927)
The plugin stops working.
though device ready alert came, still after the above error line, it says the device ready has not fired after 5 seconds. Kindly help me out.
Sorry - but I've never written my own plugin. I'd suggest the PhoneGap Google group.
if we keep java and js file, can we use the plugin directly? I mean, Did we don't need to change any xml files?
I'm not really sure what you are asking here. Can you rephrase?
I need to install the plugin which is in git. U said to copy java and js file and place them in respective folders, but i had seen somewhere to change plugin.xml also..so i was confused..can u explain it
I don't think you actually *read* the blog post. I did not say that. Please read it again.