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:

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

    ReplyDelete
  2. @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.

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

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

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. 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

    ReplyDelete
  7. @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.

    ReplyDelete
  8. 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?

    ReplyDelete
  9. @JHall

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

    ReplyDelete
  10. 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

    ReplyDelete
  11. @dferrero

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

    ReplyDelete
  12. 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

    ReplyDelete
  13. @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

    ReplyDelete
  14. 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.

    ReplyDelete
  15. 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..

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

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

    ReplyDelete
  18. 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..

    ReplyDelete
  19. 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...

    ReplyDelete
  20. 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...

    ReplyDelete
  21. 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...

    ReplyDelete
  22. 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...

    ReplyDelete
  23. @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

    ReplyDelete
  24. 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;

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

    ReplyDelete
  26. 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.

    ReplyDelete
  27. @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.

    ReplyDelete
  28. 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

    ReplyDelete
  29. @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.

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

    can you help me??

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

    ReplyDelete
  32. 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

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

    ReplyDelete
  34. 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<

    ReplyDelete
  35. @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.

    ReplyDelete
  36. 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 !!!

    ReplyDelete
  37. @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.

    ReplyDelete
  38. Simon>

    Any update on upgrading to PhoneGap1.4.1?

    ReplyDelete
  39. @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.

    ReplyDelete