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:

Antoine said...

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?

Simon Mac Donald said...

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

skogsmaskin said...

I have the same problem with PhoneGap 0.9.5.1.

Nothing happens. Can't see any errors either.

Tobias said...

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

Simon Mac Donald said...

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

Cory said...

Thank you very much for this tutorial!

White said...

I haved the same problem : nothing happens!

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

casper60 said...

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

Simon Mac Donald said...

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

Mahendra said...

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.

Simon Mac Donald said...

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

Reza Lesmana said...

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. :)

kumarpsk said...

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

Simon Mac Donald said...

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

kumarpsk said...

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

Simon Mac Donald said...

Read up on how to write a plugin.

Robert (aka Defused) said...

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

Jithin said...

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?

Simon Mac Donald said...

@Jithin

Need some more details.

Mitch said...

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

Simon Mac Donald said...

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

sidepa said...

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.

derghostface said...

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?

Simon Mac Donald said...

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

Simon Mac Donald said...

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

steve said...

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.

Simon MacDonald said...

@steve

Yes, please see my post on 1.9.0

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

balla85 said...

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.

Simon MacDonald said...

@balla85

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

Hitechwebsites said...

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

Simon MacDonald said...

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

Ewald Bos said...

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

Simon MacDonald said...

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

nicoprofe said...

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!

Simon MacDonald said...

@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

VISWANATHAN C said...

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

Simon MacDonald said...

@VISWANATHAN C

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

Sathvik Ponangi said...

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

Simon MacDonald said...

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