Thursday, May 26, 2011

Installing the ChildBrowser Plugin on PhoneGap Android

I'm writing up a quick tutorial on how to get the ChildBrowser plugin for PhoneGap Android installed as a few folks on the mailing list are having troubles getting it going. First lets start off with a stock PhoneGap Android project in Eclipse:


Step one is to create the directory structure for the ChildBrowser.java file. Click on the src folder then right mouse click or control click on the folder.  From the popup menu select New and Package.


In the dialog box that appears type in com.phonegap.plugins.childBrowser then click the Finish button. Please note the package name is case sensitive so make sure it matches exactly.


Step two is adding the ChildBrowser.java class to your project.  Download the file from this link and save it in your projects src/com/phonegap/plugins/childBrowser directory.  Then click on you projects name then right mouse click and select Refresh.  Your project explorer should now look like this:

You shouldn't see any red exclamation marks at this point.  If you do you've probably named your package incorrectly.

Step three is to add the childbrowser.js file to your project.  Download the file from this link and save it in your projects assets/www directory. Then click on you projects name then right mouse click and select Refresh. Your project explorer should now look like this:


In step four we will need to modify the AndroidManifest.xml file to add an intent filter for the ChildBrowser.  Paste the following lines inside the <application/> tag:

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

Here is a gist of what my AndroidManifest.xml looks like.

In step five we need to modify our index.html file to a reference the childbrowser.js and call the ChildBrowser.  In the <head/> tag after the reference to phonegap.0.9.5.js add the following line:

<script type="text/javascript" charset="utf-8" src="childbrowser.js"></script>

and somewhere in your <body/> tag add a line like this:

<a href="#" onclick="window.plugins.childBrowser.showWebPage('http://www.google.com');">Open Google.com in child browser</a>

This will give you an app that shows you this:


and opens Google in the ChildBrowser when you click on the link.


The full gist of my index.html is available as well.

Hope this helps everyone!

39 comments:

  1. Hello,

    I was following your tutorial but on clicking on the link nothing happens.
    In logCat I can see those errors:
    -ReferenceError: Can't find variable: PhoneGap in childbrowser.js
    -TypeError: Result of expression 'windows.plugins' [undefined]

    So I suppose that linking with the plugManager is not working.
    Any Idea?

    ReplyDelete
  2. Are you sure your child browser.js comes after the PhoneGap.js? Also what version of PhoneGap are you using?

    ReplyDelete
  3. I have the same problem with PhoneGap 0.9.5.1.

    Nothing happens. Can't see any errors either.

    ReplyDelete
  4. Hi,
    when I run the App i recive the error:
    Error: Status=2 Message:Class not found at file...

    using phonegap 0.9.5.1

    ReplyDelete
  5. @Tobias I need some more info than that to figure out what is going on. You are probably better off taking this type of discussion over to the PhoneGap Google Group.

    ReplyDelete
  6. Thank you very much for this tutorial!

    ReplyDelete
  7. I haved the same problem : nothing happens!

    And I found that in Build Path->Source->com.phonegap.plugins.childBrowser are excluded !

    ReplyDelete
  8. Is the ChildBrowser on Android supposed to show the native addressbar? Im not sure how this works on Android, but on the iPhone version it doesn't show the default address bar in the top. I can't find any video of how it is supposed to behave, so I'm not sure if its intentional.

    I have uploaded som images here:

    http://art-journal.dk/work/screen1.png
    http://art-journal.dk/work/screen2.png
    http://art-journal.dk/work/screen3.png

    Any help would be much appreciated.

    Kind regards,
    Casper Knudsen - Art-journal.dk

    ReplyDelete
  9. Hey Casper, yes, the address bar on top of the ChildBrowser is intentional. The Android and iOS versions are not exactly the same.

    ReplyDelete
  10. Hi Simon,

    Can you show an example of using the ChildBrowser plugin to post on Facebook wall in Android. There is an example for FBConnect in iOS, but not for Android.

    Any help in this will be highly appreciated.

    Thanks.

    ReplyDelete
  11. @Mahendra look for the FBConnect plugin as it will do what you want. Dave Johnson of Nitobi demoed it at PhoneGap day last Friday.

    ReplyDelete
  12. Hi, Simon

    thanks for this tutorial. And also the tutorial on the installing PhoneGap 1.0. However, I found out that I need to use a second argument (boolean true) for showWebPage if I want it to show it on the PhoneGap app directly. At least for the latest ChildBrowser plugin it needs to use it. Thanks. :)

    ReplyDelete
  13. Hello ,

    How to I call the android activity through the phonegap javascript, it is possible or not ,if possible means please give me a solution


    thanking you
    kumarp

    ReplyDelete
  14. @kumarspk

    This is a question best posted on the PhoneGap Google Groups but if you are looking to call an intent from JS you can use the Web Intent plugin.

    ReplyDelete
  15. sir,
    One more question How to i call android java class method using javascript in phonegap

    ReplyDelete
  16. So please, can anybody help, how to hide address bar in ChildBrowser?

    ReplyDelete
  17. Hai Simon MAc,



    Thanks for the coding...
    I used this one, but it is working fine in emulator, it is not working inmy samsung galaxy pop.... what is the problem?

    ReplyDelete
  18. How did you get the ChildBrowser window to appear full screen vs. as a modal dialog?

    ReplyDelete
  19. @Mitch

    If you use showWebPage it uses the modal dialog with an embedded web view. If you use openExternal it starts a separate browser using an intent.

    ReplyDelete
  20. How do you close a childbrowser (cb) from the cb?

    If I open a cb using showWebPage, then the page loaded into it doesn't seem to allow js, but this type of cb does close when the android back button is pressed.

    If I open a cb using openExternal, then all my js works in the loaded page, but there is no way to close the cb. Because the page inside the cb has it's own js, calling window.plugins.childBrowser.close() has no effect, because that command relates to the previous webview that originally opened the cb.

    So I suppose my questions are:
    Is there an equivalent to window.close() that I can call from withing the cb (to close itself)?
    Is there a way to access the js in the original webview with something like opener.window.plugins.childbrowser.close()?

    At the moment I can open a cb, but either the loaded webpage doesn't work (no js), or I can't close it... both of which are useless!

    Any help or advice would be greatly appreciated.

    ReplyDelete
  21. Thanks for the grat work. I'm looking forward to test the childBrowser on android. Do you know when the adaption for cordova support will be done?

    ReplyDelete
  22. @derghostface

    I already did it but didn't push it before heading out on vacation. You should be able to get it from github.com/macdonst/PhoneGap-plugins/android/childbrowser but you will have to select my "plugins-1.5.0" branch to get the latest code. All those paths are from memory so they may be a bit off.

    ReplyDelete
  23. @sidepa

    Typically you would listen for location changes in your main program which are broadcast from the child browser window. You could provide a close button in the child browser window that redirects to a new url that represents you want to close the browser window.

    ReplyDelete
  24. Has anything changed for cordova 1.9?

    I get the red X on my package with the following errors:

    The method getAssets() is undefined for the type CordovaInterface

    The method getSystemService(string) is underfined for the type cordocainterface

    The method runOnUiThread(runnable).....

    The method startActivity(intent) ....

    basically had a working test app until I loaded Childbrowser. I talke it out and it works again.

    ReplyDelete
  25. @steve

    Yes, please see my post on 1.9.0

    http://simonmacdonald.blogspot.ca/2012/07/phonegap-android-plugins-sometimes-we.html

    ReplyDelete
  26. Hi Simon, thanks for this awesome plugin! =)
    I'm using it on iphone to visualize a remote pdf file.
    This pdf could ben large (some MB), how can i visualize a message while loading, in your childbrowser page? How is it possibile save it from your childbrowser page?
    Thank you very much!
    Michele.

    ReplyDelete
  27. @balla85

    Sorry, I didn't write the iOS version. Not sure how to do what you want to do.

    ReplyDelete
  28. Hi Simon,
    I have been trying out the getPicture() using phonegap 1.61 and 1.9.0 on eclipse with applaud for android. I used the examples for the camera. After finding one of your comments about using 2.1 emulator, I managed to get it to work. I found that using DATA_URL to save the image worked on my phone(2.2), but you could only take one photo per day and save it. If you took another one the same day, it would overwrite the previous one. I am assuming that when saving the image that it only looks at the date and not the time in the image name.
    I then tried saving the image using FILE_URI. For the life of me I cannot find how to save this with a name.
    I tried using the following code, which I found on the internet, in the following:
    function onPhotoURISuccess(imageURI){
    // Uncomment to view the image file URI
    ....
    ....
    var gotFileEntry = function(fileEntry) {
    console.log("got image file entry: " + fileEntry.fullPath);
    var gotFileSystem = function(fileSystem){
    // copy the file
    fileEntry.moveTo(fileSystem.root, "pic.jpg", null, null);
    };
    // get file system to copy or move image file to
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFileSystem, fsFail);
    };
    //resolve file system for image
    window.resolveLocalFileSystemURI(imageURI, gotFileEntry, fsFail);
    }



    // file system fail
    function fsFail(error) {
    console.log("failed with error code: " + error.code);
    }

    This will save the images on the emulator fine, but they are not readable on the phone. They are saved in the album as well as on the root of the sd card. The album photos cannot be read, but the one on the card comes up with a broken image and then finally loads.
    I just need to be able to do one of the following:
    1) Take and save more than one picture a day.
    2) Know how to save the image with a name.
    3) Or load a picture after taking it without it being saved( I can save the image from the canvas).
    Any help would be greatly appreciated.
    Regards
    Rob

    ReplyDelete
  29. @Hitechwebsites / Rob

    Hey Rob, when you take a picture using the FILE_URI parameter it gets saved into the content store and the raw jpg file is saved on your sdcard. In the success callback of getPicture you take the URL you are passed and do a resolveLocalFileSystemURI just like you are doing. Then you'll be able to do a copy file and give file a new directory path and name.

    ReplyDelete
  30. Great tutorial, works great.
    But i have (i think) a small problem with the childbrowser plugin, the problem is the following;

    All of the Childbrowser code works ok, it connects to the externa webpage on our server and i run it in full screen mode (so no navigation bar / na buttons etc.) and i am looking for the code to place on our webpage that closes the window.

    What code do i need to place to close the childbrowser window on the webpage? on the webpage is just a image "Home" when i click that one i want to close the childbrowser session. Is that even possible?

    Thanks a lot of all your help in advance,

    Ewald

    ReplyDelete
  31. @Ewald

    What you want to do is create an event listener for onLocationChange. When the user navigates off the main page you are showing then you call the close command from your onLocationChange listener.

    ReplyDelete
  32. Hi Simon, what is the best way to put a email form in phonegap?
    Are useful for this task, the childbrowser or squlite plugins?

    Thanks!

    ReplyDelete
  33. @nicoprofe

    Well if you don't want to use a mailto link to start the email composer app you can always use a regular html form and then set document.location to be a mailto: link with the address, subject, body included in the link.

    https://tools.ietf.org/html/rfc2368

    ReplyDelete
  34. Childbrowser not working in Phonegap 2.2.0, but works with phonegap 2.1.0.

    ReplyDelete
  35. @VISWANATHAN C

    Define not working. What is the behaviour, stack trace, etc.

    ReplyDelete
  36. Any chance of a loading indicator/ progress bar being implemented? https://github.com/phonegap/phonegap-plugins/issues/571

    ReplyDelete
  37. @Sathvik Ponangi

    Once you have implemented the functionality to allow the developer to control if the loading image should be shown or not I will merge the pull request.

    ReplyDelete