Android Webview touch content - javascript

I want to get the content of that tag which I touch in webview in string.
Suppose I have 5 paragraph and I touch on one then I want content of that paragraph in string.
How can I achieve this?
Thanks

Well this is very easy, but you need to do it in parts, and you would need JavaScript.
1.- Enable JavaScript in your webview.
web.getSettings().setJavaScriptEnabled(true); //"web" is the object of type WebView
2.- Create a JavaScript Interface between the WebView and the Html.
public class JavaScriptInterface {
private Handler myHandler = new Handler();
public void getParagraph(final String paragraph){
myHandler.post(new Runnable() {
#Override
public void run() {
//Do something with the String
}
});
}
}
NOTE: Inside the method run, you will add whatever you need to process with the String retrieved from the Html. This class can be created inside the class where you create the WebView or as a separate class if you are going to use this same behavior from another activity.
3.- Send the Interface to the WebView.
web.addJavascriptInterface(new JavaScriptInterface(), "android");
/* In this case "android" is the name that you will use from the Html to call
your methods if is not too clear yet, please keep reading */
4.- You need to add the onClick event handler to each of your P tags.
<p onclick="android.getParagraph(this.innerText);">Text inside the paragraph</p>
/*android was the name we set for the interface in step 3, getParagraph is the name
of the method created on step2,"this.innerText" retrieves the text inside the paragraph*/
NOTE: All the names that you see on my example can be changed, BUT if you change the name on the java class remember to change all the calls in the html

Related

How to import my main app classes into my imported library module?

So I am creating an app that has a WebView to create notes in html. To do this I use a GitHub library called Rich Text Editor (that I put in my app project folder)
Now the problem is I want to call my function from my main app folder. How do I do that? The reason I want to do this is because I'm detecting the Button onclick from the WebView that I created using "#JavascriptInterface" in one of the class. When the user clicks the button, i need to take the value in the button and use it for my other functions in the main app folder.
Can anyone help me please?
This is my VideoViewingFragment from my main app folder
fun startsomething(vidTimestamp: Float){
youTubePlayerView.getYouTubePlayerWhenReady(object: YouTubePlayerCallback{
override fun onYouTubePlayer(youTubePlayer: YouTubePlayer) {
youTubePlayer.seekTo(vidTimestamp)}})}
This is my WebInterface class that I made and put in the Rich Text Editor Library:
class WebAppInterface(var mContext: Context) {
#JavascriptInterface
fun getString(text: String) {
//get text from the button click
// call the function from VideoViewingFragment
// This is where i want to call my functions from my activity in my other main app folder
}
This is the JavaScript function that is called from the .js file to call the getStringFromButtonClick (in my Rich Text Editor library module). This function is called every click.Only after the user creates a button with whatever text they want to put inside it... and after it is clicked, it is called.
function myFunction(text){
window.Android.showToast(text);}
I know this is quite a bad technique as it can cause code injection. But this is only for my own use.
Try with the following code it will help you.
class TestActivity : AppCompatActivity(), WebViewFragment.WebViewCallback {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test)
//Make sure your webViewFragment calling from this activity
}
override fun onButtonClick(text: String) {
toast(text)
}
}
//This is your webview fragment
class WebViewFragment : Fragment() {
private lateinit var webViewCallback: WebViewCallback
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is WebViewCallback) this.webViewCallback = context
}
#JavascriptInterface
fun getString(text: String) {
//get text from the button click
this.webViewCallback.onButtonClick(text)
// call the function from VideoViewingFragment
// This is where i want to call my functions from my activity in my other main app folder
}
interface WebViewCallback {
fun onButtonClick(text: String)
}
}

Highlight selenium clicks using AOP

I am trying to plug in js element highlighting to selenium framework. I have this code:
#Aspect
public class HighlightAspect {
#Pointcut("execution(* *.click())")
private void allClickMethods(){}
#Before("allClickMethods()")
public void proxyClick(ProceedingJoinPoint joinPoint){
WebElement element = (WebElement)joinPoint.getTarget();
highlight(element, "green");
}
private void highlight(WebElement element, String color) {
Browser.getBrowser().executeScript("arguments[0].style.backgroundColor = '"+color+"'", element);
}
}
I initialize spring context in 'main' class like:
private static ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("spring_config.xml");
And my src/main/resources/spring_config.xml looks like:
<aop:aspectj-autoproxy />
...
<bean
id="highlightAspect"
class="com.<my_name_space>.HighlightAspect">
</bean>
...
I don't receive any exceptions from JVM, but when I add a logger to proxyClick I see this method didn't happen to be executed.
Please, help me to make it work.
As far as I know,
ProceedingJoinPoint can't be used with #Before, it's only available with #Advice
Even in #Advice, as soon as you initiate the advice to proceed (i.e. click happens), there is NO guarantee that the element will be present in the DOM.

Android webview javascript not working on API 18 or higher

I want to display a website in WebView with manipulating some DOM element. I mean, I want to remove a special div element or replace it with something.
For this purpose I did something like this:
For replacing something I use this model
document.getElementById("demo").innerHTML = "Hello World!";
I apply it for Android WebView like this:
public class WebClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, final String url) {
view.loadUrl("javascript:document.getElementById(\"jumbotron-company\").innerHTML = \"\";");
}
}
It is work on my device which API is 18 but not working on emulators or device which have API greater than 18
What #Mattia said is correct. Use evaluateJavascript if possible. It has another advantage of being able to return the value of the result back from JavaScript.
But if you want an API-agnostic workaround, make sure that the code you evaluate using loadUrl("javascript:...") just doesn't produce any return value. An assignment returns the assigned value. In newer versions of WebView this value is used as contents for a new page that replaces the existing one.
You can make sure that the expression you are evaluating doesn't produce a return value in two ways:
append void(0); statement at the end, e.g. loadUrl("javascript:elt.innerHTML='Hello World!';void(0);");
run your code inside a function that doesn't return a value, e.g. loadUrl("(function(){elt.innerHTML='Hello World!';})()");
From API level 19 you should use evaluateJavascript:
public void evaluateJavascript (String script, ValueCallback resultCallback)
Added in API level 19 Asynchronously evaluates JavaScript in the
context of the currently displayed page. If non-null, |resultCallback|
will be invoked with any result returned from that execution. This
method must be called on the UI thread and the callback will be made
on the UI thread.
Please refer to migration guide for WebView in Android 4.4:
http://developer.android.com/guide/webapps/migrating.html

Override current Javascript functions with Android Webview

I'm porting my website to Android, and using an Webview to show the content to user. There are a lot of Javascript functions in my website, and I want to intercept them. I already seen a "solution" here.
However, I think there should be a more proper way, using Javascript Interface:
this.webView.addJavascriptInterface(this.webJavascriptInterface, "Android");
This way, I have to modify my website to call both myFunction() and Android.myFunction(). I tried to leave a blank String in the interface:
this.webView.addJavascriptInterface(this.webJavascriptInterface, "");
but the result was as I guess, it couldn't work. Is there a way to override current Javascript functions in Webview?
// android
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
webView.loadUrl("javascript:function inputClick(val){native.abcd(val);}"); // override js function
}
});
webView.loadUrl("file:///android_asset/test.html");
webView.addJavascriptInterface(new Object() {
#JavascriptInterface
public void abcd(int val) {
Log.e(TAG, "#js abcd" + val);
}
}, "native");
<!-- html -->
<input type="button" onclick="inputClick(2)" value="button">
== add some explain at Sep 07,2015
because javascript function could be override, so you can override javascript function while page finished.
if not, normal implement maybe like this:
// js code
function inputClick(val) {
native.abcd(val); // native and abcd defined in WebView method addJavascriptInterface
}
but this normal implement is seems not work in iOS(Object-C), and must edit HTML page.
is just move the java-javascript bridge code from HTML to Java. (see method onPageFinished in example code)
You can do this by injecting a new javascript that redefines old function, basically you can override existing function with this.
For example, to override window.print() function, I use this
webView.loadUrl("javascript:window.print = function() {Android.printPage();}")

How do I pass return values from a javascript function to android?

I want to let my android app call a function written in javascript and expect a return value from that.
I understand that WebView.loadUrl works asynchronously, so what I am doing now is to let javascript notify my android app when it is done and pass in the return value by calling a java function using javascriptinterface.
I wonder if there are better ways of doing this and whether anyone has noticed any message loss between javascript and android.
I just got your problem.
Have a JS function like this.
function androidResponse() {
window.cpjs.sendToAndroid("I am being sent to Android.");
}
Set up Android (Java).
Have a final class like this
final class IJavascriptHandler {
IJavascriptHandler() {
}
// This annotation is required in Jelly Bean and later:
#JavascriptInterface
public void sendToAndroid(String text) {
// this is called from JS with passed value
Toast t = Toast.makeText(getApplicationContext(), text, 2000);
t.show();
}
}
Then on your WebView load have.
webView.addJavascriptInterface(new IJavascriptHandler(), "cpjs");
Call JS function
webView.loadUrl("javascript:androidResponse();void(0)");
UPDATED
Also I had a very bad time experiencing problems while passing hundreds of lines of string to JS from Java and I have subsequent post on StackOverflow with no good answers but finally resolved it knowing problme was of special characters inside string so take of special characters when you use string passing to and fro.
Passing Data From Javascript To Android WebView
HTML String Inside Nested String
HTML TextArea Characters Limit Inside Android WebView

Categories

Resources