I have a website with href in it which redirected me to https
<a id="mA" href="javascript:pLogin(2)" class="login-link__link private-cab-link"><i class="icon-user"></i>Авторизация</a>
So, I can click on it by JavaScript. It works in chrome console
javascript:(function(){document.getElementById('mA').click();})()
Now I'm trying to do the same in WebView by clicking my app's button.
public class RostelecomLoginActivity extends Activity {
WebView webView;
String url;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.activity_rostelecom_login);
Intent webIntent = getIntent();
String url = webIntent.getStringExtra("url");
webView = (WebView) findViewById(R.id.webView1);
webView.setWebViewClient(new MeWebViewClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setSaveFormData(true);
webView.getSettings().setSavePassword(true);
webView.loadUrl(url);
Button buttoner = (Button) findViewById(R.id.button1);
buttoner.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
webView.loadUrl("javascript:(function(){document.getElementById('mA').click();})()");
}
});
}
}
I'm using MyWebViewClient to allow all certificates
public class MeWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();
}
}
The js injection doesn't work. If I click on href in WebView it works.
What can be wrong?
click() isn't implemented in android js interface, you have to use HTML DOM Event Object, like this:
webView.loadUrl("javascript:(function(){"+
"l=document.getElementById('mA');"+
"e=document.createEvent('HTMLEvents');"+
"e.initEvent('click',true,true);"+
"l.dispatchEvent(e);"+
"})()");
You'll have to add a javaScript interface to the WebView to call a JavaScript function from android code.
Try something like this:-
Button buttoner = (Button) findViewById(R.id.button1);
buttoner.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
JavascriptInterface javasriptInterface = new JavascriptInterface(RostelecomLoginActivity.this);
webView.addJavascriptInterface(javasriptInterface, "MyInterface");
webView.loadUrl("javascript:(function(){document.getElementById('mA').click();})()");
}
});
Related
I use a WebView to load my page below:
<html>
<head>
</head>
<body>
<h1>first page</h1>
<script>
(function(){
function log(e){
console.log("Page is going to unload:"+e);
}
window.addEventListener('beforeunload',log);
window.addEventListener('unload',log);
})()
</script>
</body>
</html>
this page has worked well in Chrome or other PC-browser。
Here is the code in activity:
public class MainActivity extends AppCompatActivity {
WebView web;
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
web = findViewById(R.id.web);
web.setWebContentsDebuggingEnabled(true);
WebSettings webSettings = web.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
web.loadUrl("http://192.168.0.103:5000/WebContent/");
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onDestroy() {
Log.i("SSSS","acitvity destroyed");
super.onDestroy();
ConstraintLayout layout = this.findViewById(R.id.rootView);
layout.removeView(web);
web.destroy();
web = null;
}
}
when leave the activity that contains WebView ,I cannot catch any logs about page unload event,is anything wrong?
I didn't test this but based on the documentation you need to override WebChromeClient::onConsoleMessage and use WebView::setWebChromeClient.
This is because you are removing view and Webview in onDestroy
#Override
protected void onDestroy() {
Log.i("SSSS","acitvity destroyed");
super.onDestroy();
ConstraintLayout layout = this.findViewById(R.id.rootView);
layout.removeView(web); <----- This linse
web.destroy(); <------ Forcing webview to destroy and next explicitly set null
web = null;
}
I have an android activity that holds the webview and I have a page that contains a local variable marks. The local variable will be increased when user got the correct answer. In the webpage, there is a button called exit which is supposed to close the webpage and go back to the activity in android, and it should carry the local variable marks back to the activity too. I want to ask how the exit button can be done in the webpage to close the page and return local variable by using Javascript and how can the activity in android receive the local variable from the webpage.
My activity in android:
private WebView webview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
webview = new WebView(this);
webview.getSettings().setJavaScriptEnabled(true);
try {
webview.setWebViewClient(new WebViewClient());
webview.loadUrl("file:///android_asset/index.html");
}
catch(Exception ex)
{
ex.printStackTrace();
}
setContentView(webview);
}
My exit button is a div:
<div class="exit" onclick="finish()">Exit</div>
I am going to use the finish() function to return the variable and close the webpage back to the activity in android.
function finish() {}
To notify the host application that a page has finished loading. Then Call onPageFinished()
webview.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// do your stuff here
}
});
SOURCE
you can do one thing..On click on the exit call any url like http://../getmark?marks=2 and once url load in the webview finish/ exit from webview. In the activity
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// parse the url here to get marks
}
});
Register a javascriptinterface to your webview in onCreate:
this.webview.addJavascriptInterface(new MyJSInterface(this), "Android");
Implement setCount method in your Activity:
public void setCount (int count) {
//do what ever you want with count
}
Make a new JavascriptInterface-Class:
public class MyJSInterface {
private YourActivity yourActivity = null;
public MyJSInterface (YourActivity yourActivity) {
this.yourActivity = yourActivity;
}
#JavascriptInterface
public void invoke (int count) {
this.yourActivity.setCount(count);
}
}
And in javascript:
function finish(marks) {
if (Android !== undefined) {
if (Android.invoke !== undefined) {
Android.invoke(marks);
}
}
}
I want to open a webpage in a WebView and click automatically on a button after the page has loaded. This is my current WebView class:
public class WebViewFragment extends Fragment {
...
#Override
public void onResume() {
super.onResume();
openUrl();
}
private void openUrl() {
setCookies();
if (urlToOpen != null) {
//tell webview to handle redirects (by default browser launches on redirects)
webview.setWebViewClient(new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (getActivity() != null)
((MainActivity) getActivity()).onShowLoading();
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (getActivity() != null) {
executeJS();
((MainActivity) getActivity()).onHideLoading();
}
}
});
if (javascriptToExecute != null) {
webview.getSettings().setJavaScriptEnabled(true);
}
webview.loadUrl(urlToOpen);
}
}
private void executeJS() {
System.out.println("executeJS(): " + javascriptToExecute);
webview.loadUrl(javascriptToExecute);
}
}
I can use "javascript:$('#customer-info-edit').click();" or "javascript:document.getElementById('customer-info-edit').click();" both work fine.
But the problem is they work only one time. If I open the WebView for the first time, the button is clicked. However if I press physical back button and open the WebView again then the button is not clicked. Why isn't Javascript working every time?
I don't know what the problem exactly was, but I found a working solution: add 500ms delay before executing javascript.
Trying to make a "click counter" game in android studio.
int clicked = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView text = (TextView) findViewById(R.id.counter);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clicked++;
text.setText(clicked);
}
});
}
This is the code i set up for the counter. Any ideas about what i might be doing wrong?
Try: #Override public void onClick(View v) { clicked+=1; text.setText(String.valueOf(clicked);
text.invalidate();}
I wrote an Android app with toggle button but toggle button does not work well at the first time. But after unchecking, if you try again, it is working properly after that.
I listed below my codes.
Which codes I have to add to activate it for the first time?
public class MainActivity extends Activity{
private ToggleButton togg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
togg = (ToggleButton) findViewById(R.id.toggleButton1);
}
public void nameOfMethod(View v){
togg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (togg.isChecked()) {
//Toast.makeText(MainActivity.this, "Servise bağlanılıyor...", Toast.LENGTH_SHORT).show();
new Thread(new ClientThread()).start();
} else {
Toast.makeText(MainActivity.this, "Bağlantı sonlandırılıyor...", Toast.LENGTH_SHORT).show();
}
}
});
}
in .xml file:
<ToggleButton
android:id="#+id/toggleButton1"
android:layout_width="120dp"
android:layout_height="60dp"
android:layout_below="#+id/textView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:onClick="nameOfMethod"
android:textOn="Bağlantıyı bitir"
android:textOff="Bağlantıyı başlat" />
EDIT: It works just fine like that:
public class MainActivity extends Activity{
private ToggleButton togg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
togg = (ToggleButton) findViewById(R.id.toggleButton1);
togg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (togg.isChecked()) {
//Toast.makeText(MainActivity.this, "Servise bağlanılıyor...", Toast.LENGTH_SHORT).show();
new Thread(new ClientThread()).start();
} else {
Toast.makeText(MainActivity.this, "Bağlantı sonlandırılıyor...", Toast.LENGTH_SHORT).show();
}
}
});
}
with moving setOnClickListener method to onCreate(Bundle savedInstanceState) and deleting android:OnClick method in .xml file...
You should set checked status for the toggle button in xml or in your code.
Xml
android:checked="true"
Or code:
togg = (ToggleButton) findViewById(R.id.toggleButton1);
togg.setChecked(true);
Otherwise, you can use
togg.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO
}
});
instead of OnClickListener().
It will be ok if you still want to use OnClickListener, but remember to put it it onCreate instead of putting it in nameOfMethod. (Or remember call nameOfMethod in onCreate)
To put it onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
togg = (ToggleButton) findViewById(R.id.toggleButton1);
togg.setChecked(false);
togg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
...
}
});
}
Well it appears that you're setting your click listener AFTER the toggle button is selected the first time, which explains the behavior you're getting.
Move the code to set your listener outside of nameOfMethod() and it should work.
EDIT: Sorry If I wasn't clear, just remove the setOnClickListener method from your nameOfMethod(). nameOfMethod() is what will be called each time the toggle button is selected, so it really makes no sense to set a listener each time it's touched..that is why you're getting such unusual behavior.
Instead, in your nameOfMethod(), just go right ahead and set up your conditions based on the state of the toggleButton
if(toggleButton.isSelected()){
..........
{
else
.......