Skip to content
Nate Ebel edited this page Jul 19, 2022 · 3 revisions

🖥 Lab 18: Integrating a Web App into Your Application

Integrate the Twitter PWA into the app as an alternative to using Implicit Intents.

Objectives

  1. Review existing use of Intent to launch Twitter

    • Notice that this takes user to another app to carry out the action
  2. Load Twitter's PWA using a WebView

    1. Add a WebView to activity_twitter.xml
    2. Enable Javascript on the WebView
    3. Call WebView.loadUrl() with "https://mobile.twitter.com". Can use the given utility method by calling binding.webView.loadTwitter().
  3. Load Twitter's PWA directly into the "Composer"

    1. Replace the loading of "https://mobile.twitter.com" with "https://mobile.twitter.com/intent/tweet?hashtags=$csvFormattedHashtags" by calling binding.webView.loadTwitterComposer()
  4. Display a native ProgressBar when PWA is loading

    1. Create a ProgressChromeClient class that extends WebChromeClient
    2. Update the constructor to take a single ProgressBar property
    3. Within onProgressChanged() show the ProgressBar any time the current progress is between 1-99
    4. Set an instance of ProgressChromeClient as the webChromeClient on the WebView
    5. Re-launch your TwitterActivity to observe your native ProgressBar being updated in response to loading of the PWA
  5. Display yor own simple web app that bridges between Javascript and Kotlin

    1. Review the class SimpleWebAppInterface
    2. Review WebView.loadSimpleWebApp(activity: Activity) within WebViewContentExtensions.kt
    3. Invoke loadSimpleWebApp() from TwitterActivity.onCreate()
    4. Re-launch your TwitterActivity to observe that actions taken from the Javascript are responded to natively in Kotlin code

Challenges

  1. Add additional styling/actions to the HTML defined in loadSimpleWebApp() and respond natively
  2. Add a FloatingActionButton that is drawn over your custom HTML/Javascript and that launches the Twitter PWA when clicked
    1. This demonstrates the mixing of native controls with web content for a hybrid approach

🖥 Lab 18 Hints: Integrating a Web App into Your Application

💡 Helpful Resources

💡 How to load Twitter's PWA into a WebView?

fun WebView.loadTwitter() {
  loadUrl("https://mobile.twitter.com")
}

💡 How to load Twitter's PWA into a WebView directly to the Composer

/**
 * Will load Twitter's PWA "Twitter Lite" and open up to the composer with a set of pre-populated
 * hashtags
 */
fun WebView.loadTwitterComposer(vararg hashtags: String) {
  val formattedHashtags = hashtags.toList().reduceRightIndexed { index, s, acc ->
    val separator = if(index == hashtags.size -1) "" else ","
    acc + separator + s
  }
  loadUrl("https://mobile.twitter.com/intent/tweet?hashtags=$formattedHashtags")
}

💡 Where can I find some simple HTML/Javascript to load into my WebView?

Look no further!

Ensure that you've added the SimpleWebAppInterface class to yor project. Then, add the WebView.loadSimpleWebApp() extension function and invoke it after setting up your WebView in onCreate()

The created instance of SimpleWebAppInterface will be used to connect to click handlers defined in the Javascript

/**
 * Basic example of a Kotlin -> Javascript bridging implementation
 */
class SimpleWebAppInterface(private val activity: Activity) {

    @JavascriptInterface
    fun showToast(toast: String) {
        Toast.makeText(activity, toast, Toast.LENGTH_SHORT).show()
    }

    @JavascriptInterface
    fun navigateBack() {
        activity.finish()
    }
}

/**
 * Will load some basic html/javascript with a bridging class to communicate back to the Activity
 */
fun WebView.loadSimpleWebApp(activity: Activity) {
  addJavascriptInterface(SimpleWebAppInterface(activity), "SimpleWebAppInterface")

  val html = """
      <!DOCTYPE html>
      <html>
      <head>
      <style>
      body {background-color: powderblue;}
      h1   {color: blue;}
      p    {color: red;}
      </style>
      </head>
      <body>
      
      <input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
      <input type="button" value="Finish" onClick="navigateBack()" />
      <h1>Simple Web App</h1>
      <p>Connect HTML/Javascript elements to our mobile app</p>
      </body>
      
      <script type="text/javascript">
          function showAndroidToast(toast) {
              SimpleWebAppInterface.showToast(toast);
          }
          
          function navigateBack() {
              SimpleWebAppInterface.navigateBack();
          }
      </script>
      
      </html>
    """.trimIndent()
  val encodedHtml = Base64.encodeToString(html.toByteArray(), Base64.NO_PADDING)
  loadData(encodedHtml, "text/html", "base64")
}
Clone this wiki locally