Logo

Calling Native Android Functions from WebView

webview

So Apparently This Works?

Ever been in a situation where your web app runs inside a native Android app and somehow… you can call native Java code? I wasn’t expecting it to work either — but here we are.

This is how I invoked an Android function right from the browser via WebView, with zero knowledge of the app's internals.

It feels illegal, but it’s not.

🧪 Step 1: Talk to Your App Dev Buddy

First, ask your Android developer to expose the native function through WebView and give you the exact object name and function signature.

Something like:

  • Object name: ContentSharingInterface
  • Function name: share
  • Args: title: String, url: String

This is the source code they were using to expose the function:

1import android.content.Context
2import android.webkit.JavascriptInterface
3import androidx.core.app.ShareCompat
4
5class ContentSharingInterface(
6 private val context: Context,
7) {
8 companion object {
9 const val TYPE_TEXT_PLAIN: String = "text/plain"
10 const val NAME = "ContentSharingInterface"
11 }
12
13 @JavascriptInterface
14 fun share(
15 title: String,
16 url: String,
17 ) {
18 val body = "$title\n$url"
19
20 ShareCompat.IntentBuilder(context)
21 .setSubject(title)
22 .setText(body)
23 .setType(TYPE_TEXT_PLAIN)
24 .startChooser()
25 }
26}

🧠 Step 2: Add Type Safety in TypeScript

You don’t want your linter screaming at you.

Extend the window object in global.d.ts:

1interface Window {
2 ContentSharingInterface?: {
3 share: (title: string, url: string) => Promise<void>
4 }
5}

🚀 Step 3: Actually Call the Native Code

When you want to call that Android-side share() function, just… do this:

1if ('ContentSharingInterface' in window) {
2 window.ContentSharingInterface.share(document.title, location.href)
3} else {
4 alert(
5 'Your app is too old. Please update to use the shiny new share feature.',
6 )
7}

Yes, that’s it. No fancy bridge libraries. No rocket science. If the app side exposed it via addJavascriptInterface() in WebView, it just… works.

🤖 But Why Does This Even Work?

Android’s WebView has this thing called addJavascriptInterface which lets you expose Java/Kotlin objects to JavaScript in your WebView. That object becomes globally accessible via window.<ObjectName> in your browser environment.

So if the app side did:

1webView.addJavascriptInterface(new ContentSharingInterface(), "ContentSharingInterface");

Then boom 💥 — your webpage suddenly has a new global object.

Of course, security concerns exist (this is why it's not allowed in file:// URLs), but for app-internal WebViews, it’s super handy.

✅ Wrap-Up

  • Native WebView bridges let your web app talk to Android code.
  • Ask your app dev to expose the interface properly with separate params.
  • Use TypeScript type guards and fallback alerts to stay safe.
  • And no, you’re not hallucinating — this is actually supported Android behavior.