Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS communicate with Webview in Native Android ('Android' is not defined no-undef)

I have written web part in ReactJS (not React Native - very important). I have also simple Android application, that contains a WebView, where I'm opening a website that is running on ReactJS. Is there a proper way to communicate between the Android native WebView (that opens a ReactJS website) and a ReactJS website?

I already went through this Facebook React Native Communication, but that is a model case for React Native. That means, that is useless in the native Android app extending an Activity by ReactActivity and so on...

This is the ReactJS source code, where I wanted to perform a JS call Mobile.showToast("Test") (not just here, in many .tsx files), but it didn't compile. The compile error is 'Mobile' is not defined no-undef:

import * as React from "react";
import {
  Button,
} from "components";

class Login extends React.PureComponent {
  public render() {
    return (
      <Fullscreen>
        <Content>
          <Button onClick={this.handleRedirect} fullWidth>
        </Content>
      </Fullscreen>
    );
  }

  private handleRedirect = () => {
    //Here I wanted to call JS call for Android JavascriptInterface interrogation
    Mobile.showToast("Test");
  };
}

export default Login;

And this is source code for appending javascriptInterface + JS calls (in this example only call is showToast):

webView.addJavascriptInterface(new MobileAppInterface(getContext()), "Mobile");


import android.content.Context;
import android.webkit.JavascriptInterface;
import android.widget.Toast;

public class MobileAppInterface {

    Context mContext;

    /**
     * Instantiate the interface and set the context
     */
    public MobileAppInterface(Context c) {
        mContext = c;
    }

    /**
     * Show a toast from the web page
     */
    @JavascriptInterface
    public void showToast(String toast) {
        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
    }
}
like image 847
jantursky Avatar asked Oct 02 '18 23:10

jantursky


1 Answers

In your React method, since you named your JavascriptInterface "Mobile", you will need to modify your method to use window.Mobile.showToast("Test"); since the interface is exported to the global window object:

class Login extends React.PureComponent {

    ...

    private handleRedirect = () => {
        if (window.Mobile)
            window.Mobile.showToast("Test");
    };
}

If, for example, you named your JavascriptInterface "Android",

webView.addJavascriptInterface(new MobileAppInterface(getContext()), "Android");

then your method body would need to be the following:

class Login extends React.PureComponent {

    ...

    private handleRedirect = () => {
        if (window.Android)
            window.Android.showToast("Test");
    };
}

Source

  1. Global window object https://developer.mozilla.org/en-US/docs/Glossary/Global_object
like image 111
VIN Avatar answered Sep 28 '22 18:09

VIN