{"id":32,"date":"2012-03-10T23:16:15","date_gmt":"2012-03-10T17:46:15","guid":{"rendered":"http:\/\/ramkulkarni.com\/blog\/?p=32"},"modified":"2012-03-10T23:16:15","modified_gmt":"2012-03-10T17:46:15","slug":"creating-android-applications-with-html-user-interface","status":"publish","type":"post","link":"http:\/\/ramkulkarni.com\/blog\/creating-android-applications-with-html-user-interface\/","title":{"rendered":"Creating Android Applications with HTML User Interface"},"content":{"rendered":"<p>I created my first two Android applications completely using Android APIs. However I realized that I can build better user interface quickly using HTML, JavaScript and CSS. Android SDK provides WebView controls which is a browser control. So I started looking for ways to make WebView render local HTML files. Most APIs of WebView are simple to understand and use, except one important method, loadUrl.<\/p>\n<p>To begin with I was not sure where to store my HTML\/JS files in the Android project and what URL to use to load them. JavaDoc help for WebView did not mention how to load local assets into WebView. It turned out that you need to keep all your HTML\/JS files in the &#8216;assets&#8217; folder of you project and load them with URL file:\/\/android_asset\/.<br \/>\n<!--more--><br \/>\nHere are steps to load local HTML file in the Activity class &#8211;<\/p>\n<ol>\n<li>You first need to create a layout for your Activity in res\/layout folder of your Android project<\/li>\n<li>In the left pallet, click &#8216;Composite&#8217; view and drag and drop &#8216;WebView&#8217; control on to the layout<br \/>\n<a href=\"https:\/\/i0.wp.com\/138.197.85.232\/blog\/wp-content\/uploads\/2012\/03\/20120310_layout.jpg\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"31\" data-permalink=\"http:\/\/ramkulkarni.com\/blog\/creating-android-applications-with-html-user-interface\/20120310_layout\/\" data-orig-file=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2012\/03\/20120310_layout.jpg?fit=438%2C486\" data-orig-size=\"438,486\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Add WebView to layout\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2012\/03\/20120310_layout.jpg?fit=270%2C300\" data-large-file=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2012\/03\/20120310_layout.jpg?fit=438%2C486\" class=\"size-full wp-image-31 alignnone\" title=\"Add WebView to layout\" alt=\"Adding WebView to layout\" src=\"https:\/\/i0.wp.com\/138.197.85.232\/blog\/wp-content\/uploads\/2012\/03\/20120310_layout.jpg?resize=438%2C486\" width=\"438\" height=\"486\" srcset=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2012\/03\/20120310_layout.jpg?w=438 438w, https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2012\/03\/20120310_layout.jpg?resize=270%2C300 270w\" sizes=\"(max-width: 438px) 100vw, 438px\" data-recalc-dims=\"1\" \/><\/a><\/li>\n<li>In your activity class, associate above layout with the activity using setContentView method &#8211;\n<pre style=\"color: #000000; background: #f1f0f0;\">public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.main); \/\/ pass id of layout resource\n    }<\/pre>\n<\/li>\n<li>In the onStart method of the Activity, get reference to the WebView we created above and load URL\n<pre style=\"color: #000000; background: #f1f0f0;\">public void onStart() {\n        super.onStart();\n\n        WebView webView =  (WebView)findViewById(R.id.webView1);\n        \/\/enable JavaScript\n        webView.getSettings().setJavaScriptEnabled(true);\n        webView.loadUrl(\"file:\/\/\/android_asset\/index.html\");\n    }<\/pre>\n<\/li>\n<li>Create index.html in the &#8216;assets&#8217; folder of your project<\/li>\n<\/ol>\n<h2>Accessing Java class from JavaScript<\/h2>\n<p>With HTML, JavaScript and CSS you can create many useful Android applications. If you use HTML5 APIs, you could even create and access SQLLite database from JavaScript. However sometimes you many want to get access to Android APIs from your JavaScript code. You can do that as follows.<\/p>\n<p>Create a class that will act as an interface between Java code and JavaScript code<\/p>\n<pre style=\"color: #000000; background: #f1f0f0;\">public class java2JSAgent\n    {\n        public String getContacts()\n        {\n            String jsonResponse = null;\n            \/\/call Android APIs to get contacts\n            \/\/serialize to JSON and assign to jsonResponse\n\n            return jsonResponse;\n        }\n    }<\/pre>\n<p>Craeate and instance of this class in onStart method and associate it with the instance\u00a0of WebView<\/p>\n<pre style=\"color: #000000; background: #f1f0f0;\">webView.addJavascriptInterface(new java2JSAgent(), \"java2JSAgentVar\");<\/pre>\n<p>The second argument to addJavascriptInterface method is name<br \/>\nof the JavaScript variable<br \/>\n. You can now access the Java object in JavaScript code using this variable name<br \/>\n.<\/p>\n<pre style=\"color: #000000; background: #f1f0f0;\">&lt;script type=\"text\/javascript\"&gt;\n    var contactsJson = java2JSAgentVar.getContacts();\n&lt;\/script&gt;<\/pre>\n<p>So, using HTML, JavaScript, CSS and native Android APIs you can create quite powerful Android applications. And if you want to develop cross platform mobile applications using HTML and JS, then <a href=\"http:\/\/phonegap.com\/\" target=\"_blank\">PhoneGap<\/a> is your best bet.<\/p>\n<p>-Ram Kulkarni<\/p>\n<p><strong>Update :<\/strong><br \/>\nIn Android SDK 4.2, you have to annotate (@JavascriptInterface) methods in Java class that you want to make available to JavaScript. (see description of <a href=\"http:\/\/developer.android.com\/reference\/android\/webkit\/WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)\">addJavascriptInterface<\/a>). So in the above example the class java2JSAgent would be &#8211;<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\"><span style=\"color: #200080; font-weight: bold;\" data-mce-mark=\"1\">import<\/span><span style=\"color: #004a43;\" data-mce-mark=\"1\"> android<\/span><span style=\"color: #308080;\" data-mce-mark=\"1\">.<\/span><span style=\"color: #004a43;\" data-mce-mark=\"1\">webkit<\/span><span style=\"color: #308080;\" data-mce-mark=\"1\">.<\/span><span style=\"color: #004a43;\" data-mce-mark=\"1\">JavascriptInterface<\/span><span style=\"color: #406080;\" data-mce-mark=\"1\">;<\/span>\n\n<span style=\"color: #200080; font-weight: bold;\" data-mce-mark=\"1\">public<\/span> <span style=\"color: #200080; font-weight: bold;\" data-mce-mark=\"1\">class<\/span> java2JSAgent\n<span style=\"color: #406080;\" data-mce-mark=\"1\">{<\/span>\n        <span style=\"color: #308080;\" data-mce-mark=\"1\">@<\/span>JavascriptInterface\n        <span style=\"color: #200080; font-weight: bold;\" data-mce-mark=\"1\">public<\/span> <span style=\"color: #6679aa; font-weight: bold;\" data-mce-mark=\"1\">String<\/span> getContacts<span style=\"color: #308080;\" data-mce-mark=\"1\">(<\/span><span style=\"color: #308080;\" data-mce-mark=\"1\">)<\/span>\n        <span style=\"color: #406080;\" data-mce-mark=\"1\">{<\/span>\n            <span style=\"color: #6679aa; font-weight: bold;\" data-mce-mark=\"1\">String<\/span> jsonResponse <span style=\"color: #308080;\" data-mce-mark=\"1\">=<\/span> <span style=\"color: #200080; font-weight: bold;\" data-mce-mark=\"1\">null<\/span><span style=\"color: #406080;\" data-mce-mark=\"1\">;<\/span>\n            <span style=\"color: #595979;\" data-mce-mark=\"1\">\/\/call Android APIs to get contacts<\/span>\n            <span style=\"color: #595979;\" data-mce-mark=\"1\">\/\/serialize to JSON and assign to jsonResponse<\/span>\n\n            <span style=\"color: #200080; font-weight: bold;\" data-mce-mark=\"1\">return<\/span> jsonResponse<span style=\"color: #406080;\" data-mce-mark=\"1\">;<\/span>\n        <span style=\"color: #406080;\" data-mce-mark=\"1\">}<\/span>\n<span style=\"color: #406080;\" data-mce-mark=\"1\">}<\/span><\/pre>\n<p>Also when running this code with the latest SDK and emulator, I had to sometimes call webView.setWebChromeClient(new WebChromeClient()) after enabling JavaScript in the WebView. Otherwise I observed that JavaScript code on the HTML page was not getting executed. However I observed that this behavior was inconsistent.<\/p>\n<pre style=\"color: #000020; background: #f6f8ff;\"><span style=\"color: #200080; font-weight: bold;\">public<\/span> void onStart() <span style=\"color: #406080;\">{<\/span>\n        <span style=\"color: #200080; font-weight: bold;\">super<\/span><span style=\"color: #308080;\">.<\/span>onStart<span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span>\n\n        WebView webView <span style=\"color: #308080;\">=<\/span>  <span style=\"color: #308080;\">(<\/span>WebView<span style=\"color: #308080;\">)<\/span>findViewById<span style=\"color: #308080;\">(<\/span>R<span style=\"color: #308080;\">.<\/span>id<span style=\"color: #308080;\">.<\/span>webView1<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span>\n\n        <span style=\"color: #595979;\">\/\/enable JavaScript<\/span>\n        webView<span style=\"color: #308080;\">.<\/span>getSettings<span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #308080;\">.<\/span>setJavaScriptEnabled<span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">true<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span>\n        webView<span style=\"color: #308080;\">.<\/span>setWebChromeClient<span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">new<\/span> WebChromeClient<span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span>\n\n        webView<span style=\"color: #308080;\">.<\/span>loadUrl<span style=\"color: #308080;\">(<\/span><span style=\"color: #1060b6;\">\"file:\/\/\/android_asset\/index.html\"<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span>\n<span style=\"color: #406080;\">}<\/span><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I created my first two Android applications completely using Android APIs. However I realized that I can build better user interface quickly using HTML, JavaScript and CSS. Android SDK provides WebView controls which is a browser control. So I started looking for ways to make WebView render local HTML files. Most APIs of WebView are &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/ramkulkarni.com\/blog\/creating-android-applications-with-html-user-interface\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Creating Android Applications with HTML User Interface&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[3,1],"tags":[2],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2g9O8-w","jetpack-related-posts":[],"_links":{"self":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts\/32"}],"collection":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/comments?post=32"}],"version-history":[{"count":0,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts\/32\/revisions"}],"wp:attachment":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/media?parent=32"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/categories?post=32"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/tags?post=32"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}