Saturday, July 30, 2011

Upgrading your PhoneGap Android Application to 1.0.0

With the release of PhoneGap 1.0.0 some folks may run into some problems upgrading their existing applications to the latest version.  If you are not using "droidgap create" to generate a brand new Eclipse project using PhoneGap 1.0.0 here are a few things you should be aware of:
  1. Obviously you'll need to modify the script tag that references phonegap-{ver}.js to be phonegap-1.0.0.js.
  2. Secondly you'll need to remove the current phonegap-{ver}.jar from the build path and add phonegap-1.0.0.jar to the build path. 
  3. If you run your app and it gets the Force Close dialog then you probably didn't copy plugins.xml into the res/xml directory in your application. If the xml directory doesn't exist create it!
  4. If you are unable to open a second html page in your app then you're missing the following tag which should be placed in the application tag of your apps AndroidManifest.xml:

    <activity android:name="com.phonegap.DroidGap" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden">
    <intent-filter>
    </intent-filter>
    </activity>

    Please note after you add this activity you should have two activities under your applications tag. The above activity should not replace the one currently in your application tag.
  5. If you see and error about PluginManager.addService() not existing then you are using old style plugins. Go into the Plugins .js file and comment out of straight up delete the PluginManager.addService() line from the PhoneGap.addContructor() method.  Then you should add a plugin tag to the plugins tag in your plugins.xml.

    For instance if you are using the TTS plugin you'd add:

    <plugin name="TTS" value="com.phonegap.plugins.speech.TTS"/>
This may not be an exhaustive list of issues you may run into on an upgrade but it is all I can think of right now.  If you find something else comment on this post and I'll update it.

40 comments:

Hoxton Sax said...

Thanks - really helpful! Phonegap is fantastic - but their documentation and upgrade help is a little lacking so posts like this are invaluable!!

Simon MacDonald said...

@Horton

Glad you found the article helpful. As one of the core PhoneGap developers we acknowledge the documentation could be better and were trying to improve as we move forward with PhoneGap.

TubToilet said...

Does the name have to be "com.phonegap.DroidGap" or the name of your app?

Simon MacDonald said...

Yes, you need to add it exactly as typed. Please note your application tag should have two activities after the insertion.

Simon MacDonald said...
This comment has been removed by the author.
pab said...

Hi Simon,
i tried out with directory listing and i have done all what you said but some error occurs


D/PhoneGapLog( 560): file:///android_asset/www/phonegap.1.0.0.js: Line 604 : Error: Status=2 Message=Class not found
I/Web Console( 560): Error: Status=2 Message=Class not found at file:///android_asset/www/phonegap.1.0.0.js:604
D/PhoneGapLog( 560): file:///android_asset/www/phonegap.1.0.0.js: Line 612 : Error in error callback: DirectoryListPlugin13 = ReferenceError: Can't find variable: log
I/Web Console( 560): Error in error callback: DirectoryListPlugin13 = ReferenceError: Can't find variable: log at file:///android_asset/www/phonegap.1.0.0.js:612


thanks,
-pab

Simon MacDonald said...

@Pab


A couple of things. The "Class not found" message is happening because
the CallbackServer can't find the right Plugin to invoke on the Java
side. If you are using the class
com.trial.phonegap.plugin.directorylisting.DirectoryListPlugin from
the wiki you should have a line like this in your plugins.xml file:

<plugin name="DirectoryListPlugin"
value="com.trial.phonegap.plugin.directorylisting.DirectoryListPlugin"/>

Second in your error callback the function log() is not defined.
Change it to console.log() and it will work. I'm going to update the
wiki on that point.

Unknown said...

Thanks for all the info! I have a question. Have there been any updates to mailto:? I have been looking for a simple way to use mailto: to open the email client and add an attachement. The attachement is the tricky part. Is this possible with phonegap?

Simon MacDonald said...

@JHall

I've not tried to do that. You should jump on the PhoneGap google group and ask your question on that forum.

dferrero said...

I too got this error with log cat while attempting to run the simple Facebook Connect example.

D/PhoneGapLog( 560): file:///android_asset/www/phonegap.1.0.0.js: Line 604 : Error: Status=2 Message=Class not found
I/Web Console( 560): Error: Status=2 Message=Class not found at file:///android_asset/www/phonegap.1.0.0.js:604

Simon MacDonald said...

@dferrero

Generally when I see that error it is because the person has forgotten to add the plugin line to their plugins.XML.

panhala said...

Hi,
Here is issue for which, I never found any help after googling.
I am using phonegap1.1.0 and when I complete with xmlhttp request and change html page using Window.location.replace. I am getting continuous alert "gap_poll" infinitely.
Please help

Simon MacDonald said...

@panhala

Don't use window.location. Use navigator.app.loadUrl(url) instead. You should also go star this Android bug:

http://code.google.com/p/android/issues/detail?id=9122

Nilesh Bafna said...

Thanks your previous comment about window.location helped!!!

We are having another problem where the onDeviceReady is fired really late after every and any page load.

Till then other elements of the page are accessible and creates further problems when the user clicks them. We have database operations in onDeviceReady, hence fetching of data starts late.

John said...

hi i am new to the phonegap 1.0.0 .i tried with an example https://github.com/sconover/phonegap-android-plugin-examples
but i got error in
java script content:
var hello = function(win, fail) {
alert("test1 ");
if (window['HelloWorld'] == undefined)
PluginManager.addService("HelloWorld","com.test.HelloWorld");
PhoneGap.execAsync(win, fail, "HelloWorld", "sayHello", []);
};

ReferenceError: Can't find variable: PhoneGap at file:///android_asset/www/helloworld.js:8

what is the problem with it..

Pramod Yadav said...

Thanks a lot Simon for such to the point explanation. It was very helpful to me!...

Simon MacDonald said...

@John Sounds like you haven't referenced your phonegap-{version}.js in your .html file.

John said...

i have changed my javascript tag like this
"script type="text/javascript" charset="utf-8" src="phonegap-1.0.0.js"script"
still not working...can you help me..

Jonas said...

Saved my day! Thanks!
/Jonas

John said...

i am trying to upload an image using phonegap plugin in android ,got the example from : https://github.com/phonegap/phonegap-plugins/blob/master/Android/FileUploader/fileuploader.js

and my code for locally uploading is like this:

FileUploader.prototype.uploadByUri= function('http://localhost/upload/upload_file.php', "content://img/test.jpg", {foo: 'bar'}, 'myPhoto','anImage.jpg', "image/jpeg", callback, fail) {

return PhoneGap.exec(function(args) {
callback(args);
}, function(args) {
if(typeof fail == 'function') {
fail(args);
}
}, 'FileUploader', 'uploadByUri', [server, file, params, fileKey, fileName, mimeType]);
};
there is some error like this :"Cannot return from outside a function or method." i am trying with phonegap-1.0.0.js ; can any one help me...

John said...

i am trying to upload an image using phonegap plugin in android ,got the example from : https://github.com/phonegap/phonegap-plugins/blob/master/Android/FileUploader/fileuploader.js

and my code for locally uploading is like this:

FileUploader.prototype.uploadByUri= function('http://localhost/upload/upload_file.php', "content://img/test.jpg", {foo: 'bar'}, 'myPhoto','anImage.jpg', "image/jpeg", callback, fail) {

return PhoneGap.exec(function(args) {
callback(args);
}, function(args) {
if(typeof fail == 'function') {
fail(args);
}
}, 'FileUploader', 'uploadByUri', [server, file, params, fileKey, fileName, mimeType]);
};
there is some error like this :"Cannot return from outside a function or method." i am trying with phonegap-1.0.0.js ; can any one help me...

John said...

i am trying to upload an image using phonegap plugin in android ,got the example from : https://github.com/phonegap/phonegap-plugins/blob/master/Android/FileUploader/fileuploader.js

and my code for locally uploading is like this:

FileUploader.prototype.uploadByUri= function('http://localhost/upload/upload_file.php', "content://img/test.jpg", {foo: 'bar'}, 'myPhoto','anImage.jpg', "image/jpeg", callback, fail) {

return PhoneGap.exec(function(args) {
callback(args);
}, function(args) {
if(typeof fail == 'function') {
fail(args);
}
}, 'FileUploader', 'uploadByUri', [server, file, params, fileKey, fileName, mimeType]);
};
there is some error like this :"Cannot return from outside a function or method." i am trying with phonegap-1.0.0.js ; can any one help me...

John said...

i am trying to upload an image using phonegap plugin in android ,got the example from : https://github.com/phonegap/phonegap-plugins/blob/master/Android/FileUploader/fileuploader.js

and my code for locally uploading is like this:

FileUploader.prototype.uploadByUri= function('http://localhost/upload/upload_file.php', "content://img/test.jpg", {foo: 'bar'}, 'myPhoto','anImage.jpg', "image/jpeg", callback, fail) {

return PhoneGap.exec(function(args) {
callback(args);
}, function(args) {
if(typeof fail == 'function') {
fail(args);
}
}, 'FileUploader', 'uploadByUri', [server, file, params, fileKey, fileName, mimeType]);
};
there is some error like this :"Cannot return from outside a function or method." i am trying with phonegap-1.0.0.js ; can any one help me...

Simon MacDonald said...

@John you should use the FileTransfer API in PhoneGap's core instead of that old plugin. It'll do what you want.

http://docs.phonegap.com/en/1.1.0/phonegap_file_file.md.html#FileTransfer

John said...

Thanks a lot for your previous replays,how to load external url when the page load in android or how to replace super.loadUrl("file:///android_asset/www/index.html");with a www.google.com;

Simon MacDonald said...

@John, I don't really understand your question. Would it be possible for you to rephrase it or give some more details?

John said...

thanks for your replay , what i am actually looking is that can we load a web page(eg: www.google.com) instead of index.html.in android.

Simon MacDonald said...

@John, then you just need to change the loadUrl path and add the proper info to your phonegap.xml for whitelisting if you are using PhoneGap 1.1 or above.

John said...

thanks for your replay , how can we write a phonegap plugin in phonegap1.0.0;what i need is that fetch the device gps from the native code and give back to the javascript

Simon MacDonald said...

@John, why don't you come over to the PhonGap Google Group and ask these questions? They are getting off topic from the spirit of this post.

as said...

Console(10102): Uncaught TypeError: Cannot read property 'tts' of undefined at file:///android_asset/www/index.html

can you help me??

Simon MacDonald said...

@as did you include the tts.js file in your index.html? I'm assuming you want to do TTS.

as said...

yes i include it in my index.hmtl like this after the javascript/phonegap-1.0.0.js:
script type="text/javascript" charset="utf-8" src="javascript/tts.js"></script

Simon MacDonald said...

@as how do you call it in your html code?

as said...

in the head-tag in a script-tag like this:
function onLoad() { document.addEventListener("deviceready", onDeviceReady, false); }

function onDeviceReady() { window.plugins.tts.startup(startupWin, fail);}

function startupWin(result) {
if (result == TTS.STARTED) { window.plugins.tts.getLanguage(win, fail); window.plugins.tts.speak("The text to speech service is ready"); window.plugins.tts.isLanguageAvailable("en", function() {
addLang("en");}, fail); window.plugins.tts.isLanguageAvailable("fr", function() addLang("fr");
}, fail);
}
}
function addLang(lang) {
var langs = document.getElementById('langs');
var anOption = document.createElement("OPTION")
anOption.innerText = lang;
anOption.Value = lang;
langs.options.add(anOption); }

function changeLang() {
var yourSelect = document.getElementById('langs'); window.plugins.tts.setLanguage(yourSelect.options[yourSelect.selectedIndex].value, win, fail);}

function win(result) { console.log(result);}

function fail(result) {
console.log("Error = " + result); }

function speak() { window.plugins.tts.speak(document.getElementById('playMe').value);
}

then in the body-tag:
onload="onLoad()"
an input with id="playMe" and type ="text"/>
than an select-tag with id="langs" and onchange="changeLang()"
and href to javascript:speak()">Speak<

Simon MacDonald said...

@as that is a weird one. Obviously you are getting a deviceready event or you would not be getting that error in your onDeviceReady() method. You should probably come over to the google group as it'll be easier to resolve this over email.

p said...

Hello Simon,
The VideoPlayer plugin is indeed helpful for playing thevideo on Android platform.
Thanx it worked.. Is there a way to package the plugin onto a jar file. I tried it but found many errors !!!

Simon MacDonald said...

@p

I've never bothered to look into a way to .jar up the plugin. That might be something we look into in future PhoneGap release for plugin packaging.

George said...

Simon>

Any update on upgrading to PhoneGap1.4.1?

Simon MacDonald said...

@George

Nothing jumps out at me as being significantly different for 1.4.1 upgrade from previous versions. Now when we go to 1.5 things will get a bit different.