EvaluateJavascript Using Android WebView with API level 18 - javascript

I've been developing an Android app for my business for a long time and it's been working fine, using a webview and calling back and forth between native features. In case it's relevant, here's the Java entry point to my app:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.activity_main);
myWebView = (WebView) findViewById(R.id.webview);
final Context that = this;
myWebView.addJavascriptInterface(new WebAppInterface(this, this), "Android");
myWebView.setWebViewClient(new WebViewClient(){
public void onPageFinished(WebView view, String url) {
myWebView.evaluateJavascript("pageFinished()", null);
}
});
pm = this.getPackageManager();
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowUniversalAccessFromFileURLs(true);
webSettings.setDomStorageEnabled(true);
WebView.setWebContentsDebuggingEnabled(true);
Window window = getWindow();
//window.setStatusBarColor(Color.parseColor("#3596d4"));
myWebView.loadUrl("file:///android_asset/index.html");
IntentFilter filter = new IntentFilter();
filter.addCategory(Intent.CATEGORY_DEFAULT);
filter.addAction(getResources().getString(R.string.activity_intent_filter_action));
registerReceiver(myBroadcastReceiver, filter);
mDetector = new GestureDetectorCompat(that, this);
myWebView.setOnTouchListener(touchListener);
}
Now when I set the minimum version to 18 in my gradle file, some lines got marked by Android Studio as 'not supported by API 18', most notably my myWebView.evaluateJavascript calls, but also some other stuff like WebView.setWebContentsDebuggingEnabled.
How can I do evaluateJavascript in API 18?
Also in some places, when I call evaluateJavascript, I expect a response back, for example:
myWebView.evaluateJavascript("Back.go()", new ValueCallback<String>() {
#Override
public void onReceiveValue(String canGoBack) {
if (canGoBack.equals("false")) {
moveTaskToBack(true);
} else {
// don't need to do anything, already called Back.go()
// that means the javascript already handled navigation
}
}
});
Will that be possible with API 18?

How can I do evaluateJavascript in API 18?
Use loadUrl("javascript:..."), where the...` is your JavaScript code.
Will that be possible with API 18?
No, sorry. The closest thing is to have your JavaScript code call something on your WebAppInterface that you injected via addJavascriptInterface().
Note that at the present time only ~4% of Android devices using the Play Store are running API Level 18 or older.

Related

How to call javascript method when loading Android

I'm a beginner at android.
I used javascript method in android. And I want to call it when the app is loaded for first time.
For example,
testMethod = function(str) {
alert("hi" + str);
}//javascript
and
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setDefaultTextEncodingName("utf-8");
mWebView.loadUrl("file:///index.html");
mWebView.addJavascriptInterface(androidBridge, "jsinterface");
mWebView.loadUrl("javascript:testMethod('javascript')");
}
What I was thinking here is the alert will pop up immediately when I start the app.
But nothing happens.
About this, I have two questions.
1.Can I call and use the javascript method in Android's onCreate method?
2.If it is possible, How can I do?
if you want to show a popup on start just use the default AlertDialog. see the code below.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showMessage("My Message Here", "Title here");
}
private void showMessage(String data, String title){
new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(data)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue
}
})
.show();
}
check out whether index.html is REALLY loaded. I guess that webview didn't load your html properly, bcz it's not an invalid file path. try file:///mnt/sdcard/index.html. (or something likely)
try to put mWebView.loadUrl("javascript:testMethod('javascript')") in view.post or view.postDelayed.

How can I request to open an URL without opening the webbrowser?

#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View v) {
mScannerView = new ZXingScannerView(this);
setContentView(mScannerView);
mScannerView.setResultHandler(this);
mScannerView.startCamera();
}
#Override
protected void onPause() {
super.onPause();
mScannerView.stopCamera();
}
#Override
public void handleResult(final Result result) {
//Do anything with result here :D
Log.w("handleResult", result.getText());
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Scan result");
builder.setMessage(result.getText());
AlertDialog alertDialog = builder.create();
alertDialog.show();
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(result.getText().toString()));
startActivity(browserIntent);
mScannerView.resumeCameraPreview(this);
}
}
I want to directly open the URL once scanning is done and then reopen the camera. Can anyone please help me ?
Use a webview load the URL like below:
webView= (WebView) findViewById(R.id.webview);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient());
Try and create your own activity to handle request to open URL .
When I started learning about android and its intents I found it very confusing. But category BROWSABLE in the Manifest does the following.
The target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message.
Read more on: http://developer.android.com/guide/components/intents-filters.html
The two other answers opens the standard web browser and goes to the address specified. If you want a custom browser make the second activity like a web view like this example.

Site don't want loading at api <19(KitKat)

I need to open the site in my application, but it is loaded only on devices with Android 4.4 and newer. But I need to site opened and with older versions of devices. I tried to connect the HTML5, but it seems made a mistake somewhere. The site contains HTML5 and JS code. Here's an example of my Activiti
WebView web;
ProgressBar progressBar;
#SuppressLint("SetJavaScriptEnabled")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.web);
setView();
initToolbar();
web = (WebView) findViewById(R.id.webview);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setMax(100);
progressBar.setProgress(0);
web.setWebChromeClient(new myWebChromeClient());
web.setWebViewClient(new myWebClient());
web.getSettings().setJavaScriptEnabled(true);
web.getSettings().setDisplayZoomControls(true);
web.getSettings().setLoadWithOverviewMode(true);
web.getSettings().setUseWideViewPort(true);
web.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
web.getSettings().setPluginState(WebSettings.PluginState.ON);
enableHTML5AppCache();
web.loadUrl("https://mobile.akbars.ru");
}
private void enableHTML5AppCache() {
web.getSettings().setDomStorageEnabled(true);
// Set cache size to 8 mb by default. should be more than enough
web.getSettings().setAppCacheMaxSize(1024*1024*8);
web.getSettings().setAppCachePath("/data/data/"+ getPackageName() +"/cache");
web.getSettings().setAllowFileAccess(true);
web.getSettings().setAppCacheEnabled(true);
web.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
}
public void setValue(int progress) {
this.progressBar.setProgress(progress);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d("ACTIVTTY", "change rotation");
}
public class myWebClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
progressBar.setVisibility(View.VISIBLE);
view.loadUrl(url);
return true;
}
/*#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
progressBar.setVisibility(View.VISIBLE);
}*/
/*#Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
}*/
}
public class myWebChromeClient extends WebChromeClient {
#Override
public void onProgressChanged(WebView view, int newProgress) {
WebViewActivity.this.setValue(newProgress);
super.onProgressChanged(view, newProgress);
}
}
// To handle "Back" key press event for WebView to go back to previous screen.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK) && web.canGoBack()) {
web.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
At Android 5.0 and later this site can open in default browser but in early versions of Android it open only in google chrome.
Is there a way to inherit Google Chrome in my webview?
Or some another ideas to open this site?
SITE: https://mobile.akbars.ru
In my opinion, no there is no way to inherit Google Chrome in my webview (older versions). Only simple webview is the solution. According to the version, HTML5 support also need to be checked.
I think you can use https://crosswalk-project.org/documentation/android.html
Reliably build responsive user interfaces with Flexbox. Your app will render correctly on any Android 4.0+ device when you use the Crosswalk Project.

webView loadURL not working on HTML button click

I have a webView in my application. The webView initially opens an HTML page I created with a few buttons on it. The buttons do various tasks (I'm trying to learn how to use webViews) like: 1)show android toast, 2)show javascript alert, 3)vibrate phone, 4)show current geolocation, 5)open google maps in webView.
It's this last one that's not working. I've searched this site and many others, but haven't found a solution that works.
I'm fairly certain I have all the manifest file 'stuff' correct (everything else is working, including the initial internet based web page). I'm happy to post that too though if you think it's needed.
My activity_main.xml file has never given me issues, but again, I'm happy to post that if you think it'll help.
Here are snippets from my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myWebView = (WebView) findViewById(R.id.webView);
myWebView.loadUrl(url); // this one works
myWebView.setWebViewClient(new MyWebViewClient());
WebSettings webSettings = myWebView.getSettings();
webSettings.setBuiltInZoomControls(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setGeolocationEnabled(true);
...
}
That all works and again the other html buttons work.
Then there's this:
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();
}
#JavascriptInterface
public void vibrateDevice() {
Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mVibrator.vibrate(500);
}
#JavascriptInterface
public void showMapCurPos() {
new Handler().post(new Runnable() {
String url2 = "http://www.google.com/maps/#53.001153,-95.0752916,15z";
#Override
public void run() {
myWebView.clearCache(true);//Here you call the methond in UI thread
myWebView.loadUrl(url2);
}
});
}
}
Everything works there, except for showMapCurPos(). I've already tried just a simple myWebView.loadUrl(...) along with several attempts at intents. Depending on what I've tried, sometimes that method crashes the app, but most of the time the new URL just doesn't get displayed and it stays on the original URL.
Please forgive me if this is a repeat question, but I really have searched this site and many others for an answer (probably for a solid 8 hours or so). I've tried many of those answers to no avail. I'm guessing it's something simple and has to do with my lack of understanding of webViews or activities or intents or all three or maybe even my newness to android development.
I can't write a comment yet, so I'm writing this as an answer.
You could try this answer:
myWebView.post(new Runnable() {...});
instead of using new Handler

Android webview "location.replace" doesn't work

I have an Android webview with a page that redirects to another page, using location.replace(url).
Lets say that I have page "A" that redirects to page "B" (using location.replace). When pressing "back" button from page "B", the page returns to page "A", which redirects it to page "B" again.
When I debug the history api (history.length), I can clearly see that on page "B" the length has incremented in "1" (only on Android 4.X webview. On iOS / web browser / Android 2.X it remains the same), which is a bug! (location.replace shouldn't change history.lenght!)
I work with Yaniv on this project and we found the cause of the problem, it was introduced when we tried to add mailto: links handling according to this answer.
The answer suggested using the following extending class of WebViewClient:
public class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(MailTo.isMailTo(url)){
MailTo mt = MailTo.parse(url);
// build intent and start new activity
return true;
}
else {
view.loadUrl(url);
return true;
}
}
}
The problem was that explicitly telling the WebViewClient to load the URL and returning true (meaning "we handled this") added the page to the history. WebViews are quite capable of handling regular URLs by themselves, so returning false and not touching the view instance will let the WebView load the page and handle it as it should.
So:
public class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(MailTo.isMailTo(url)){
MailTo mt = MailTo.parse(url);
// build intent and start new activity
return true;
}
else {
return false;
}
}
}
function locationReplace(url){
if(history.replaceState){
history.replaceState(null, document.title, url);
history.go(0);
}else{
location.replace(url);
}
}
Try this way..
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView mainWebView = (WebView) findViewById(R.id.webView1);
WebSettings webSettings = mainWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mainWebView.setWebViewClient(new MyCustomWebViewClient());
mainWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
mainWebView.loadUrl("file:///android_asset/www/A.html");
}
Or get help from this and this link

Categories

Resources