I know this has been already asked here.
But even after following the accepted answer here (and similar other questions on SO) - I am unable to link my client side Android code to my JavaScript due to the Uncaught ReferenceError.
My Android code snippet -
public class WebActivityExample extends Activity {
WebView mWebView;
WebAppInterface WAInterface;
#Override
public void onCreate(Bundle savedInstanceState) {
this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
WAInterface = new WebAppInterface(this);
mWebView.addJavascriptInterface(WAInterface, "Android");
mWebView.loadUrl("http://myurlhere");
}
public class WebAppInterface {
Context mContext;
/** Instantiate the interface and set the context */
WebAppInterface(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();
System.out.println("toast " + toast);
}
}
}
My website is running AngularJS on the client side and PHP on the server side. Hence I have a index.php file that holds all my JavaScript files as well as my CSS files that need to be included for the entire application.
This is my HTML code -
(It is an Angular template view that includes the HTML button) -
<input type ="button" value="Say Hello!" onClick="showAndroidToast('Hello Android!')" />
This is my index.php file that holds all the JS/CSS files -
<html xmlns:ng="http://angularjs.org" id="ng-app" ng-app="myapp">
<head>
(various scripts and stylesheets included here)
</head>
<body>
....
....
<script type="text/javascript">
function showAndroidToast(toast) {
alert(toast);
Android.showToast(toast);
}
</script>
</body>
</html>
The onClick is definitely calling the showAndroidToast function since the alert pops up the message 'Hello Android' - but I am just not able to link it to the Android function 'showToast'. I've followed the docs on Android and various answers on Stackoverflow and have done exactly the same thing as asked - but still end up getting the Uncaught Reference error! What am I missing out on/ or doing wrong????
This is how the logcat error looks -
I/chromium: [INFO:CONSOLE(243)] "Uncaught ReferenceError: Android is not defined", source: ..
Update 1 :
After referring the following SO answers :
1. Can a java file have more than one class?
2. Android 4.2.1, WebView and javascript interface breaks
I created a new Java class called WebAppInterface and shifted the public class from this code snippet (within my main class) into the WebAppInterface.java class.
I also changed my Minimum APK version to 17.
Still facing the same issue. Any help would be appreciated.
Related
I've got a website (www.myexamplewebsite.com) that looks simplified like this:
<html>
<head>
</head>
<body>
<img src="img/speaker-icon.png" onclick="speakerFunction()">
<script>
function speakerFunction() {
var text = new SpeechSynthesisUtterance("This is a test.");
text.lang = 'en-US';
window.speechSynthesis.speak(text);
}
</script>
</body>
</html>
And I have also a simple Android-application which is basically a webview that displays my website:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView myWebView = (WebView) findViewById(R.id.myWebView);
myWebView.loadUrl("www.myexamplewebsite.com");
myWebView.setWebViewClient(new MyWebViewClient());
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
}
// Use when the user clicks a link from a web page in the WebView
private class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getHost().equals("www.myexamplewebsite.com")) {
return false;
}
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
}
}
My problem is the following:
When I visit the example website in a normal browser (Chrome, Firefox) on my desktop-pc it works how it should work. If I click on the image on the website, I can hear the text "This is a test."
If I visit the example website with the Chrome-App for Android on my smartphone it works also. But if I visit the website with the Firefox-App or within my own App with the webview (see above) then it doesn't work.
Update 1:
I specified the language explicitely and I tried it with the crosswalk framework but that also didn't solve the problem.
SpeechSynthesisUtterance is not supported by android webview
https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance
Although SpeechSynthesis is supported but since SpeechSynthesis work based on the SpeechSynthesisUtterance object passed into it, it won't all still work.
https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis
I have a web-service In that I have added bar-code reader for android
So with the Help of JavaScript I am calling my bar-code reader from web-view
So for that I followed this
and designed on server side...
I have Given this
at JavaScript
function mybarcd() {
MyApp.mybarcdt();
}
function actfromAnd(msg){
document.getElementById("brcd").value = msg;
}
at HTML/PHP
<div class="data">
<input id="brcd" type="text" value=""/>
<button type="button" onClick="mybarcd()">SCAN</button>
</div>
On Android side
In webview
webView.addJavascriptInterface(new WebAppInterface(this), "MyApp");
and new js interface
#JavascriptInterface
public void mybarcdt() {
IntentIntegrator intentIntegrator = new IntentIntegrator(Main_A.this);
intentIntegrator.setBeepEnabled(true);
intentIntegrator.setOrientationLocked(true);
intentIntegrator.setPrompt("Scan Barcode");
intentIntegrator.initiateScan();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if (result != null) {
if (result.getContents() == null) {
Log.d("ScanActivity", "Cancelled scan");
Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
} else {
Log.d("ScanActivity", "Scanned");
String bcval = result.getContents();
if (android.os.Build.VERSION.SDK_INT < 19) {
webView.loadUrl("javascript:actfromAnd(\""+bcval+"\")");
}else{
webView.evaluateJavascript("javascript:actfromAnd(\""+bcval+"\")", null);
}
System.out.println("javascript:actfromAnd(\""+bcval+"\")");
}
} else
super.onActivityResult(requestCode, resultCode, data);
}
My Problem is that Its working fine in a single Html/PHP file with Js on same page or separate page I have tested its scanning and Updating the value in input box...
But its not working since I have using multiple pages or frame in one webview...
its missing JS value... How ever form server its opening scanner at on-click... but after scanning the value is not passing to the input box with JS I am getting this error.....
I/chromium: [INFO:CONSOLE(1)] "Uncaught ReferenceError: actfromAnd is not defined", source: (1)
Update
1)I hava Tried this in Static Page with JS in side that PHP/HTML page
2)I also tried with same in a static Page with JS seperate page
On the above two conditions its worked fine
But In my web-service I have Given Same JS file which is running successfully in Static page I have a single JS file for My Webservice and Static page its working fine in static but not working in MY webservice live.. How ever JS is loading Because on click its wokring from that JS and its opening Camera
But responce after scanning its not going to web input
I understand that I am getting Error Because...
In my Live Page I have a MainMenu Inside that menu when I select a application its loading in iframe So my Android Activity responce after scanning Is pinging to that Mainmenu page But for menu there is no Js function named actfromAnd So I am getting Error...
Here I can't give URL of that particular page(iframe) Because of depending on the menus it will change I can Give Only Login or MainMenu link directly.but not for a particular page inside the menu
Can Any one suggest me on this kind...
Add this script in Web-service at your Parent Menu which has your iframe or iframes
<script>
function actfromAnd(msg){
window.frames['yourExactframe'].document.getElementById("brcd").value = msg;
}
</script>
If you are using same in more than one frame then declare your frame name globally
I tried your Code Working Fine... In my example Frame Hope It works fine for you
Nice question....
You should execute the javascript when the page is loaded
mWebView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
webview.loadUrl("javascript:myFunction()");
}
});
The code will be executed and will find your javascript function. The way you are doing now does not wait.
I am working on a task in which we need to put one of our HTML & JS based project inside a JavaFX project or any other suitable containers which are out there. The purpose is to create an app, which can directly be deployed and would prevent any users from checking out the source code of HTML & JS.
Some time back when I was checking out JavaFX, I read that it supports JS, and JS can be used with it. Is there any way to create a container inside which I can put my HTML&JS files by giving path, etc?
How can I go about this? Whatever I am trying to do, what is it called. Any help, pointers, suggestions, would be nice.
Initial test
public class Main extends Application {
private Scene scene;
MyBrowser myBrowser;
#Override
public void start(Stage primaryStage) throws Exception{
primaryStage.setTitle("Test web");
myBrowser = new MyBrowser();
scene = new Scene(myBrowser, 1920, 1200);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class MyBrowser extends Region {
final String hellohtml = "hello.html";
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
public MyBrowser(){
URL urlHello = getClass().getResource("hello.html");
webEngine.load(urlHello.toExternalForm());
getChildren().add(webView);
}
}
As #sillyfly suggested use a WebView:
File f = new File(..);
// ..
final WebView webview = new WebView();
webview.getEngine().load(f.toURI().toURL().toString());
The hard part for me is always to figure out the right location to be used to reference the file.
Another option is when you have the HTML in the form of a string to load that as content:
String html = ...
webview.getEngine().loadcontent(html)
Be sure to check out at least the JavaDoc on WebView and WebEngine`
I have two activity, one main activity(A) is an CordovaActivity, then I use intent to start another activity(B), in B i have an WebView(not CordovaActivity), and after I use this webview to load a simple webpage (alert something), I found the js code is not executed at all, even if I enable javascript by calling setttings.setJsenabel(true);
I start activity B from A
Load Url from webview in Activity B
simple web page
in the device, it does not alert anything
However, if I change the webview to CordovaWebView instead of the original Android native one, it works.....
That's because plain WebView doesn't support showing alerts by itself. You need to provide a WebChromeClient to it that implements WebChromeClient.onJsAlert method. For example:
mywebView.setWebChromeClient(new WebChromeClient() {
#Override
public boolean onJsAlert(
WebView view, String url, String message, final JsResult result) {
new AlertDialog.Builder(view.getContext())
.setTitle("Alert")
.setMessage(message)
.setPositiveButton("Ok",
new AlertDialog.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
}).setCancelable(false).create().show();
return true;
}
});
SO community
I'm currently writing a project to integrate some custom views and forms in Outlook.
The idea is to create an Outlook extension connected to our ERP.
As discovered in this sample project (http://msdn.microsoft.com/en-us/library/aa479346.aspx), one technique is to build an ActiveX component and load it from a lightweight local html page, like this :
<html>
<body rightmargin = '0' leftmargin ='0' topmargin ='0' bottommargin = '0' onload='OnBodyLoad()'>
<object classid='clsid:f746a8b6-3659-4f4c-8518-6336187854f2' ID='MyView' VIEWASTEXT width='100%' height='100%'/>
<script>
function OnBodyLoad() {
try {
var oApp = window.external.OutlookApplication;
var view = document.getElementById('MyView');
view.Initialize(oApp);
}
catch(err) {
alert(err.description);
}
}
</script>
</body>
</html>
As you can see the Outlook application instance is passed to the Initialize() method for further access from the ActiveX (this is the important point for me).
The C# class looks like this :
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.Guid("F746A8B6-3659-4F4C-8518-6336187854F2")]
public partial class MyView : UserControl
{
public MyView()
:base()
{
Application.EnableVisualStyles();
InitializeComponent();
}
public String Str { get; set; }
public void Initialize(Object app)
{
MessageBox.Show("Initialized");
//MessageBox.Show(app.Version);
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(this, "It works!");
}
}
It's signed and registered with RegAsm.
When I load it in IE, it works like a charm. I get the message "Initialized" at startup, and when I click on button1, the message "It works" pops up too.
BUT (there is of course a 'but' :) when I load this page in Outlook (folder properties / home page), the ActiveX component gets loaded and visible, but the Initialize call throws this error: "Object doesn't support this property or method". Clicking the button1 works.
Trying to assign something to the property from Str with javascript fails in Outlook too, and works in IE.
Did anyone here face the same problem, and knows what I'm missing?
Many thanks in advance,
Nicolas