Wednesday, October 31, 2012

What's New in PhoneGap Android 2.2.0

Well we've tagged Apache Cordova 2.2.0 release candidate 2 which means that Cordova 2.2.0 will be out soon in source release form which will be followed quickly by the binary PhoneGap 2.2.0 release. Shaz wrote up a post on what's new in iOS so I was asked (shamed) to do this on for Android. So without further ado here's what you should expect on Android:

1. FileTransfer API changes

  • Added support for the onprogress event to get progress events for a FileTransfer operation
  • Added the abort function to cancel a FileTransfer operation

See the API doc.

2. Graduated the Globalization plugin to core

This plugin was previously in the phonegap-plugins repo (BB WebWorks 5, iOS, Android). The globalization object obtains information and performs operations specific to the user’s locale and timezone.

See the API doc.

3. Splashscreen API

The Splashscreen API is now formally documented for iOS and Android.

4. Android JavaScript to Java bridge improvements
  • The callback server is gone.
  • Uses events to specify when a result it ready.
  • Up to 25 times faster.
Read issue CB-638 for more information.

5. Partial support for video tag

We've been able to shim in support for the video tag. See my earlier blog post for more details.

6. Hardware acceleration is enabled by default

When you run bin/create to make a new PhoneGap Android project then android:hardwareAccelerated is set to true by default on the main activity.

See Android docs for an explanation of hardware acceleration.

7. useBrowserHistory now defaults to true

We've deprecated the current way that history is handled in Android apps in favour of the default way it is handled in the web view. To go back a page you should be using history.back(). Because of this change iframe's now work properly.

If you need to enable the old way to handle history you can set useBrowserHistory to false in config.xml.

8. Introduce CordovaPlugin class

CordovaPlugin will be replacing the Plugin class for extending PhoneGap functionality. It adds a new execute method public boolean execute(String action, String rawArgs, CallbackContext callbackContext) to enable developers passing large amounts of data to the native side provide their own JSON parser. It also cuts down on boiler-plate, makes multi-threading easier, and adds an application-wide thread-pool to CordovaInterface. Adds an onReset method that is called when top level navigation changes. This is where you should stop any long running processes like a file transfer that are no longer needed on the new page.

9. Various bug fixes
  • Back and Menu button events now fire if the cursor is inside a text view.
  • Fixed a path where the whitelist was not being checked in DroidGap.
  • FileTransfer.download now supports the trustAllHosts option to allow downloading from servers with self signed certificates.
  • Removed trailing space from contact.name.formatted.
  • Properly set contact's IM type.
  • navigator.language is now set properly when the language is switched in Android settings.

56 comments:

  1. IMPORTANT:

    Before Cordova 2.2.0, the Connection object existed at: navigator.network.connection.
    To match the spec, this was changed to navigator.connection in 2.2.0.

    this resulted in an error with my script which was the same as the example at http://docs.phonegap.com/en/2.2.0/cordova_connection_connection.md.html#Connection

    for me navigator.connection.type is 0 since I upgraded.

    seems like I dont have a decent way to check connection right now. any help on this will be appreciated.

    ReplyDelete
  2. @H.C.L. Bazić

    You can still use navigator.network.connection.type as it is being set properly even though it is deprecated. It won't be removed for about 6 months. I'll bring this to Andrews attention though. Thanks for the update.

    ReplyDelete
  3. Is there a fix for the webview freezing after being dormant for long periods of time in this release? It seems to be a big issue in Android 4.0.1 with cordova 2.1.0 currently.

    ReplyDelete
  4. @Adam

    Certainly there was a fix for this on the ASUS Transformer but looking at JIRA it seems you have a separate issue. We'll handle the discussion over on JIRA.

    ReplyDelete
  5. Wonderful Improvements here.

    Is there a fix to the orientation change for android 4.x devices.
    The activity seems to be reloading on devices > android 4.x ,despite handling orientation changes in manifest and overriding methods in main activity,and my app totally gets refreshed.There seems no native way for me to control it.

    Thanks for any help.

    ReplyDelete
  6. @Prasad Wagh

    I can't reproduce that problem. You should provide sample code/project that demonstrates it and we'll look at it.

    ReplyDelete
  7. I would like to know if the issue "Return from camera not reliable on Android" was resolved?

    https://groups.google.com/forum/?fromgroups=#!topic/phonegap/GFwv2OticKw

    thanks.

    ReplyDelete
  8. Is there anything new that needs to be done to take advantage of the android bridge improvements? Looking through the code it seems like it uses the new options by default by I am still experiencing annoying freezes on ICS.

    ReplyDelete
  9. @brian

    No, you shouldn't need to do anything. I know that Andrew/Joe and I are trying to figure out the freezes on ICS over on the mailing list. We need a good reproduction scenario to figure this out though.

    ReplyDelete
  10. @LUIS SOTO

    No, we haven't completely solved it. I made improvements in 1.9.0/2.0.0 but we are still working on a complete fix for this annoying Android issue.

    ReplyDelete
  11. Hello Simon,
    Does this release solve the problems with android ics url parameter?

    ReplyDelete
  12. @Ademola Olayioye

    Joe has indicated that it has been fixed. Have you tried the latest release? If it is still a problem let us know as soon as possible.

    ReplyDelete
  13. Thank you for your response.
    The latest release has indeed solved the problem.

    ReplyDelete
  14. hello, good job.
    I would like some information on hardware acceleration.
    It means that the canvas will be accelerated? you can start thinking about games?
    perhaps using canvas and easel.js ...

    ReplyDelete
  15. @michelangelo giacomelli

    Actually if you are relying on a canvas element in the web view you will probably want to turn off hw acceleration. It is still kinda buggy. But I'd say test it out for yourself.

    ReplyDelete
  16. how to download files with https protocol in android ? I'm try to use it, but keep getting an error.

    My download code:

    var fileTransfer = new FileTransfer();
    fileTransfer.download(
    task_url,
    fileListDir + fileName,
    function(entry) {
    mylog("download complete: " + entry.fullPath);
    },
    function(error) {
    mylog("download error source " + error.source);
    mylog("download error target " + error.target);
    mylog("upload error code" + error.code);
    });
    My log

    11-19 13:56:13.339: E/FileTransfer(17969): {"target":"/mnt/sdcard/task1/Picture_4.jpg","source":"https://91.228.199.95/ksiywFac63f2hs/fotos.gleb/Picture_4.jpg","code":3} 11-19 13:56:13.339: E/FileTransfer(17969): javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:477) 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:328) 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.setupSecureSocket(HttpConnection.java:185) 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:433) 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl$HttpsEngine.makeConnection(HttpsURLConnectionImpl.java:378) 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:205) 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:152) 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.cordova.FileTransfer.download(FileTransfer.java:486) 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.cordova.FileTransfer.execute(FileTransfer.java:88) 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.cordova.api.PluginManager$1.run(PluginManager.java:231) 11-19 13:56:13.339: E/FileTransfer(17969): at java.lang.Thread.run(Thread.java:1019) 11-19 13:56:13.339: E/FileTransfer(17969): Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:161) 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:664) 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method) 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:474) 11-19 13:56:13.339: E/FileTransfer(17969): ... 10 more 11-19 13:56:13.339: E/FileTransfer(17969): Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 11-19 13:56:13.339: E/FileTransfer(17969): at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:207) 11-19 13:56:13.339: E/FileTransfer(17969): at java.security.cert.CertPathValidator.validate(CertPathValidator.java:197) 11-19 13:56:13.339: E/FileTransfer(17969): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:156) 11-19 13:56:13.339: E/FileTransfer(17969): ... 13 more

    ReplyDelete
  17. @Gleb Kravchenko

    Looks like you are trying to download from a service with a self signed certificate. You need to enable debug mode to download:

    var fileTransfer = new FileTransfer();
    fileTransfer.download(
    task_url,
    fileListDir + fileName,
    function(entry) {
    mylog("download complete: " + entry.fullPath);
    },
    function(error) {
    mylog("download error source " + error.source);
    mylog("download error target " + error.target);
    mylog("upload error code" + error.code);
    },
    true);

    ReplyDelete
  18. Hi,Simon. Is there win8 doesn't support Cordova Opendatabase method?
    I use Cordova 2.2.0 in visual studio express for windows 8 with my project code, when I run, I got error: "javascript runtime error: boject dosen't support property or method openDatabase". So I am wondering the Win8 doesn't support the database in Cordova 2.2.0? Thanks

    ReplyDelete
  19. @Wei Zhang

    You should ask that question on the Google Group or talk to @purplecabbage. I haven't touched the WIndows Phone stuff at all.

    ReplyDelete
  20. How can apply that(https://issues.apache.org/jira/browse/CB-1829) fix to the 2.2.0 release? As is phonegap is unusable...

    ReplyDelete
  21. @Luigi Picaro

    You'd have to download the source code for cordova android with the 2.2.0 tag. Then you need to open the NetworkManager.java file and remove the onPause method and re-compile.

    ReplyDelete
  22. If the cursor is inside a text view and clicked on the back button the app exits in cordova 2.2. Is this an issue in cordova 2.2?

    ReplyDelete
  23. @unimity

    That bug should be fixed. I just tried it in 2.3.0rc1 and I can't reproduce it but then again I believed it was fixed for 2.2.0. What are the particulars of the reproduction scenario?

    ReplyDelete
  24. Hi,
    The scenario is keep the cursor in a text view and click on the back button the app exits. But if the cursor is in a textarea and clicked on back button, it works fine.

    ReplyDelete
  25. To avoid back button issue when the cursor is placed in text view , we included the below code.
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
    //if(appView.canGoBack()){
    // this.sendJavascript("javascript:BackButton()");
    // return true;
    //}
    this.sendJavascript("javascript:BackButton()");
    return true;
    }
    return super.onKeyDown(keyCode, event);
    }

    It works in android 2.2, android 2.3 but in android 4.1 back button is not working when included the above code

    ReplyDelete
  26. @unimity

    Weird, I can't reproduce in 2.3.0rc1 but I'll take a closer look at it before we cut rc2.

    ReplyDelete
  27. I'm posting here because there does not seem to be an obvious way of reporting bugs of that kind, not because I want an answer to something (Cordova bug reporting is not so obvious either); to this:
    "While with an Eclipse local build, the app version in the Android Applications sub-screen is correct, it reports a different, unrelated, and WRONG version with the official PG Build package; for instance our app is actually at "0.9.8" but it shows "1.1" !
    Yes, widget attributes in config.xml ARE:
    versionCode = "1"
    version = "0.9.8",
    they answered this: "This tracker is for Cordova, not for the Adobe PhoneGap Build service. Please contact them with your issue." So be it. A.R.

    ReplyDelete
  28. @Al Reno

    The bug tracker for Apache Cordova/PhoneGap is:

    https://issues.apache.org/jira/browse/CB

    ReplyDelete
  29. I don't think you understand my last post at all: I DID report the bug at https://issues.apache.org/jira/browse/CB-1975
    They closed it immedialely with the said comment ("This tracker is for Cordova, not for the Adobe PhoneGap Build service. Please contact them with your issue.")
    The ball is is YOUR camp Simon, weither you like it or not! YOU report it to your brilliant Build dudes at Adobe becaue THEY don't have the heart to have a bug reporting system, that's not my problem anymore! A.R.

    ReplyDelete
  30. @Al Reno

    Crap sorry Al. I sent you to the wrong place. If it is a PhoneGap Build problem you need to go to:

    http://community.phonegap.com/nitobi

    Also, I do not work for Adobe and I have nothing to do with the PhoneGap Build service.

    ReplyDelete
  31. Hi Simon,

    Please I am creating a fileUpload with the code below:


    File Transfer Example


    // Wait for Cordova to load
    //
    document.addEventListener("deviceready", onDeviceReady, false);

    // Cordova is ready
    //
    function onDeviceReady() {

    // Retrieve image file location from specified source
    navigator.camera.getPicture(uploadPhoto,
    function(message) { alert('get picture failed'); },
    { quality: 50,
    destinationType: navigator.camera.DestinationType.FILE_URI,
    sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY }
    );

    }

    function uploadPhoto(imageURI) {
    var options = new FileUploadOptions();
    options.fileKey="file";
    options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
    options.mimeType="image/jpeg";

    var params = {};
    params.value1 = "test";
    params.value2 = "param";

    options.params = params;

    var ft = new FileTransfer();
    ft.onprogress = function(progressEvent) {
    if (progressEvent.lengthComputable) {
    loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);
    } else {
    loadingStatus.increment();
    }
    };
    ft.upload(imageURI, encodeURI("http://some.server.com/upload.php"), win, fail, options);
    }

    function win(r) {
    console.log("Code = " + r.responseCode);
    console.log("Response = " + r.response);
    console.log("Sent = " + r.bytesSent);
    }

    function fail(error) {
    alert("An error has occurred: Code = " + error.code);
    console.log("upload error source " + error.source);
    console.log("upload error target " + error.target);
    }



    However getting the following error: Web Console(9547): processMessage failed: Stack: ReferenceError: loadingStatus is not defined.

    Please am I doing something wrong here: I am aware the link is just a sample link but the error is pointed at loadingStatus?

    Thanks.

    Ismael

    ReplyDelete
  32. @Akorede Ismael Olusola Enitan Jimoh

    It's pretty obvious from the error: " ReferenceError: loadingStatus is not defined". In a nutshell that means that object has not been created at the point you are trying to use it.

    ReplyDelete
  33. Hi Simon,
    Is it possible to "integrate facebook check in functionality " in phonegap ..?

    ReplyDelete
  34. @Mayur Panchal

    It is possible but I've never done it. I really hate Facebook. You should try Dave's plugin:

    https://github.com/davejohnson/phonegap-plugin-facebook-connect/

    ReplyDelete
  35. Prasad Wagh described how the app always reloads completely on orientation change - is there a fix for that?

    I am having trouble with the orientation always reloading my app completely.

    Thank You

    ReplyDelete
  36. @Tommi Joutsiniemi

    Did you apply the following config changes to your main activity?

    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"

    ReplyDelete
  37. Yes, I applied the android:configChanges into my main activity, but without screenSize, because my minimum SDk version is 7. I also had to remove hardware acceleration from the manifest for the same reason.

    Still no fix, my app reloads completely when I reorient the device.

    ReplyDelete
  38. @Tommi Joutsiniemi

    It sounds like you are doing it wrong. You should always build with the latest SDK in this case API level 17. Then you can set a minimum SDK of 7. This will allow you to have all of those config changes I mentioned in your manifest and you app will work on Android 2.1 or greater.

    ReplyDelete
  39. That is exactly how I do it. But still, this must be a problem in my setup if nobody else has this reload problem. I just have no idea where to look. I am using Sencha Touch 2.1 commercial and phonegap 2.3.0 (also tested with 2.4.0rc1). I basically have the default Sencha-generated app with PhoneGap integration.

    Cheers
    Tommi

    ReplyDelete
  40. @Tommi Joutsiniemi

    Paste up your manifest somewhere I can take a look. Don't do it in the comments as it doesn't accept xml.

    ReplyDelete
  41. My AndroidManifest.xml:
    https://dl.dropbox.com/u/5306505/AndroidManifest.xml

    I tested my app on v2.2 emulator and reorientation works OK. On my v4.1 HTC one X device it doesn't. Do you think I should create a v4.2 emulator and find a v2.2 device to test... would that reveal something, possibly?

    ReplyDelete
  42. @Tommi Joutsiniemi

    You are missing "screenSize" from the config changes. I guess I wasn't clear about the API level thing. When you target 17 you can have screenSize in the manifest without impacting your ability to run on an API 7 level phone. Try adding it in and seeing if the problem goes away.

    ReplyDelete
  43. ta-DAA!

    screenSize did it, thank you so much!

    I have a simple app which was generated with the latest ST ("sencha generate"), and merged to a newly generated PhoneGap project ("create" in PhoneGap). (BTW, the magic was to have www and android folders side by side at app's root, and then make a symbolic link from android/assets/www point to that www - that way it should be relatively easy to use that same www folder on a possible future iPhone version of the app.)

    Anyway, here's how I probably managed to get confused: I had 2.2 as the target SDK at some point (initially, after I generated the skeleton), and I had to edit the manifest to make my app work. Then when I changed the target SDK to v4.2 I undid those changes but apparently forgot to bring back screenSize.

    I hope I didn't blame PhoneGap at any point, it works perfectly...

    Thank You again

    Cheers
    Tommi

    ReplyDelete
  44. @Tommi Joutsiniemi

    No worries, just happy it is working for you.

    ReplyDelete
  45. Hi, I appreciate very much the improvements made on html5 video tag support.
    I spent the last couple of days (and nights) facing problems related to the integration of a video in an Android PhoneGap Application i'm developing. My base platform is Android 4.0.3 and 4.0.4.
    After finding the correct encoding (webm video) I realized that the video playback result is actually very different from one device to another. In my Asus Transformer (as well as on Samsung Galaxy Note) the video is rendered inline in the phonegap webview (the video is inside the page and has the correct size, set to 320x180 pixels, just for example). The, very excited by this incredible result, I tested my app on another device (Zenithink ZPad C91 tablet) and the video is shown fullscreen... :'(
    Checking the LogCat I fount this:
    MediaPlayer error(-38, 0)
    setScreenOnWhilePlaying(true) is ineffective without a SurfaceHolder

    I googled a little bit but I can't figure out what is wrong. Maybe you can give me a clue or can suggest how to fix this problem.

    Do you plan to work on phonegap and video tag support?

    Thankyou very much

    Best Regards

    ReplyDelete
  46. @Gabriele

    Welcome to Android fragmentation. If you want a consistent, unfortunately fullscreen, appearance you could use my VideoPlayer plugin.

    ReplyDelete
  47. Thank you Simon! It is comforting to know that I was not wrong.. Even if my problem is still there! :)
    I'll try your VideoPlayer plugin for sure: I read many beatiful comments about it and i'm looking forward to try it! I really hope it will help me with my app! I'll let you know.
    Thank you very much!

    ReplyDelete
  48. i am uploading 000000001.db file to server by using file transfer api of phonegap but it gives me error
    file not found error code=1
    can anyone help me out how to get rid of this fucking things.

    ReplyDelete
  49. how can i send you my code whats your email?
    function uploadPicture() {
    alert('uploading file');
    // Get URI of picture to upload
    var img = document.getElementById('camera_image');
    // var imageURI = img.src;

    //"/data/data/com.suave.nexttrainer/app_database/file_0/0000000001.db";

    var imageURI = "/data/data/com.suave.nexttrainer/app_database/file_0/0000000001.db";


    alert(imageURI);
    /* if (!imageURI || (img.style.display == "none")) {
    document.getElementById('camera_status').innerHTML = "Take picture or select picture from library first.";
    return;
    }*/

    // Verify server has been entered
    server = document.getElementById('serverUrl').value;
    alert('server');
    if (server) {

    // Specify transfer options
    var options = new FileUploadOptions();
    options.fileKey="file";
    options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
    options.mimeType="image/jpeg";
    options.chunkedMode = false;

    // Transfer picture/file to server
    var ft = new FileTransfer();
    alert('ft');
    ft.upload(imageURI, server, function(r) {
    document.getElementById('camera_status').innerHTML = "Upload successful: "+r.bytesSent+" bytes uploaded.";
    }, function(error) {
    document.getElementById('camera_status').innerHTML = "Upload failed: Code = "+error.code;
    }, options);
    }

    ReplyDelete
  50. @Mohsin Qureshi

    Two things:

    1) try using

    "var imageURI = "file:///data/data/com.suave.nexttrainer/app_database/file_0/0000000001.db";

    2) Is com.suave.netxtrainer your app package? Because only that app can read from that directory.

    ReplyDelete
  51. i do like that but in my log cat it shows this .
    its the path of sever on which i have to upload the database file "http://nextrainer.com/nexdbbackup/upload.php"


    02-20 01:50:51.194: E/FileTransfer(1624): {"target":"http:\/\/nextrainer.com\/nexdbbackup\/upload.php","source":"file:\/\/\/data\/data\/com.suave.nexttrainer\/app_database\/file_0\/0000000001.db","code":1}
    02-20 01:50:51.194: E/FileTransfer(1624): java.io.FileNotFoundException: /data/data/com.suave.nexttrainer/app_database/file_0/0000000001.db: open failed: ENOENT (No such file or directory)

    ReplyDelete
  52. @Mohsin Qureshi

    Are you sure that "/data/data/com.suave.nexttrainer/app_database/file_0/0000000001.db" actually exists? If you run "adb shell" then cd to "/data/data/com.suave.nexttrainer/app_database/file_0" do you see the file? You'll have to do that on the emulator if you don't have a rooted phone.

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

    ReplyDelete