As already mentioned in the previous post (Episode I) Windows Phone 7.1 has built in Internet Explorer 9. Because this version is the almost e one as IE9 desktop edition, WP is able to render HTML5 content. Comparing to Chrome is the HTML5 support score still not high, but some of important features like geo-location, canvas etc. works well. As long Widows Phone is executing the HTML5 application which is hosted on some web server, it is not a big deal to open IE on phone and to navigate to the URL of the HTML5 web application.
Browsing application as web page
In general you will probably want create you own Silverlight APP, which will browse the same page. In this case you will use the WebBrowserControl and point its source to the wanted page. When you create the new Windows Phone Application, just add the WebBrowserControl as a child of the ContentPanel.
Additionally put following code in Main_Loaded (or somewhere else) and explicitly navigate to application-uri.
void MainPage_Loaded(object sender, RoutedEventArgs e) { webBrowser1.Navigate(new Uri("http://daenet.de/myhtml5app.htm", UriKind.Relative)); } |
If all works fine, the application will be rendered in the browser control. Following picture shows the application built with jQuery Mobile.
If this is what you want to achieve you are done.Unfortunately, by default one real APP should be installed on device. This is because there are many scenarios in which network is not required at all. In this case your browser control cannot connect to the application hosted somewhere else. Additionally, if you deploy your HTML application to device it will behave as real Silverlight application. You can use marketplace, updates, purchasing etc., etc.. By using of one HTML web application only application shell will be included in proposed application life cycle. If you don’t care about this just ask yourself one question: “How are you going to prevent users to use your web application if they didn’t purchase the app?”. | |
Browsing application from string content
Anyhow, if the goal is to bring the Web Application to the phone to became the real APP you need to do much more. Because of the way how Windows Phone deal with files which belong to the APP, there are bunch problems which we have to solve, to make this working.
Fortunately, WebBrowserControl provides two additional methods (ways) to execute HTML based page. First method is by using NavigateToString(htmlPage).
This method will force the control to render and execute the code in htmlPage.
This is very simple and it works fine. At least as long you app is very small app. Imagine, you have to put all you code in simple string. Then you have to reference additional scripts or some jQuery add ins shared usually across different folders under application root. Theoretically this would work, but preparing of such application would require a tool which do all tricky staff. No question about debugging.
Browsing application from device
As already mentioned the goal in this post is to make real APP deployed on the phone which will for sure pass market place verification process. At the beginning you have to be aware of one thing. Currently there is no way for WebBrowserControl to navigate to HTML file which is located somewhere in file system at the phone.
Imagine you would put all HTML, javascript and media content in some project folder like HTML. If you select build action for each file under HTML folder to “Copy Allways” files will be copied to output folder, but they will not become the part of deployment. Remember you need all content to be a part of XAP. Another solution would be to embed files as content. This would make files a part of XAP, but the method Navigate(new Uri(“Button.htm”)); wouldn’t have any effect. So what to do? I figured out that Navigate work if the navigating file is placed in isolated Storage. So I implemented a peace of code which takes make file from application folder copy it to Isolated Storage. Interstingly, there is a method GetResourceStream()which is able to grab the stream of a file located in the appllication’s installation folder. Following example shows how to do that: StreamResourceInfo streamInfo = Application.GetResourceStream(fileResource); Stream fileStream = streamInfo.Stream; | |
Now, I have implemented the method which copies this stream to Isolated storage:
private static void copyFile(IsolatedStorageFile isoFile, string webResourceFileName, Stream webResourceStream) { webResourceFileName = createRequiredDirectory(isoFile, webResourceFileName);
using (IsolatedStorageFileStream isoFileStream = isoFile.OpenFile(webResourceFileName, FileMode.Create)) { byte[] buffer = new byte[1024]; int readBytes; do { readBytes = webResourceStream.Read(buffer, 0, buffer.Length); isoFileStream.Write(buffer, 0, readBytes); } while (readBytes > 0); isoFileStream.Flush();
isoFileStream.Close(); } } |
I do not want to comment all hidden details here, but this is the principal how to do it. One more thing is important here. The things are getting more complicated, when you have to build a real application. Real application will probably require some libraries shared in folders. For example jQuery Mobile use subfolders to store style sheets and images.
If you have all this, you will have to copy all files to exactly the same position as in output folder (in fact project folder). I did it and all worked fine with WP6.5 widgets (mobility day 2009 – Zagreb), HTML5, jQuery and jQuery Mobile.
Last but not least, I implemented a small library called Daenet.WidgetLibrary, which has one public static method LoadHtmlStaff(). This method has to be called at the beginning of you application. The method will copy all files under the folder HTML to exactly same folder structure in isolated storage.
All other you have to do is, drop the Web Browser control in Silverlight application and navigate to the start page.
Following code shows the native shell application in Silverlight for Windows Phone
public MainPage() { WidgetLibrary.LoadHtmlStaff();
InitializeComponent(); this.Loaded += new RoutedEventHandler(MainPage_Loaded); } void MainPage_Loaded(object sender, RoutedEventArgs e) { webBrowser1.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(webBrowser1_NavigationFailed); webBrowser1.Navigate(new Uri("RootPage.htm", UriKind.Relative)); } |
Your HTML application will be started
by invoking webBrowser1.Navigate(new Uri("RootPage.htm", UriKind.Relative));
Note that Danet.WidgetLibrary does copy only files which are set on Build Action = “Embedded Resource”!!!!. In a case of Android the platform already supports the build action called “Android Assets”. Such became automatically the part of build process and application’s installation package. Because Windows Phone does not support similar concept, there must be some peace of code which cover this task.
| VS-Windows Phone Project | VS – Monodroid Project |
Hope this helps you a bit to start up with Windows Phone as a real host of HTML applications. At the end note, I’m not a real friend of HTML staff, but it opens you the way to target new platforms with one code.
The assembly Daenet.WidgetLibrary will be downloadable after my session at Mobility Day 2011.
Damir
Posted
Sep 13 2011, 10:28 PM
by
Damir Dobric