TagHandler to handle Youtube tag <iframe>? - android

I'm parsing html using Html.fromHtml(). My problem is that my html text has youtube embeded links (basically <iframe> tags)
So, since Html class does NOT support <iframe> tag, I need to define my own TagHandler to handle it. What I'm trying to do is to convert the <iframe> to a regular <a> tag so that it can be rendered correctly.
//convert this
<iframe src="http://www.youtube.com/embed/xAEdMI2ZE88" frameborder="0" width="560" height="315"></iframe>
//To this
Click to Watch
My problem is that I couldn't find a way to get the src link of the youtube from the <iframe> tag.
Here is my TagHandler's handleTag() method:
#Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
if (tag.equals("iframe")) {
if(opening) {
output.append("<a href=");
//How to get YouTube video link and append it?
}
else {
output.append("Click To Watch</a>");
}
}
}
Thanks in advance.

You can also use this regex.
htmlString.replaceAll("<iframe\\s+.*?\\s+src=(\".*?\").*?<\\/iframe>", "<a href=$1>CLICK TO WATCH</a>");

I, for now, took CommonsWare advice and modify the String before passing it to Html.fromHtml.
//Opening tag
Pattern p = Pattern.compile("<iframe src");
Matcher m = p.matcher(htmlString);
while (m.find())
htmlString= m.replaceAll("<a href");
//Closing tag
p = Pattern.compile("frameborder=.*</iframe>");
m = p.matcher(htmlString);
while (m.find())
htmlString= m.replaceAll(">CLICK TO WATCH</a>");

Related

How to replace special character from HTML document

I have a string "© 2015" in my HTML document. I'm parsing the HTML document using TagHandler.
opinion_description.setText(Html.fromHtml(description, this, new Html.TagHandler() {
#Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
}
}));
I'm not handling anything inside handleTag(), as the tagHandler itself is handling everything. But it's not parsing the above mentioned string. So, I'm manually replacing the string with "".
if(description.contains("Ã-Â"))
description.replace("Ã-Â","");
But it's not working. Is there any better way to parse this string.
Thanks in advance.

Get JSON from a div in html

I have a hidden div which by JavaScript gets filled with json text. I need to find this div and read the json text from it. How can this be done?
<html>
<div id="hiddenJSON">
{
"id":"1234",
"Name":"Jonas",
"Address":"Test Road 5",
"Phone":"1234-1234-1234"
}
</div>
</html>
try below code :-
Pattern p = Pattern.compile(Pattern.quote("<div id=\"hiddenJSON\">") + "(.*?)" + Pattern.quote("</div>"));
Matcher m = p.matcher(text);
while (m.find()) {
System.out.println(m.group(1));
}
But better solution is you have to receive data without html tag so talk with back end person.
It would be best to use a library for this such as JSoup. Check out this question about parsing html code
Here is how i solved this:
result is the response from #JavascriptInterface
WebView Fragment
WebView wv = ...
wv.addJavascriptInterface( this, "android" );
wv.loadUrl( "javascript:android.showHTML(document.getElementById('hiddenJSON').innerHTML);" );
Interface in my WebView Fragment
#JavascriptInterface
public void showHTML( String result ) {
// handle JSON (result)
}
Problem:
I had to get the result from my WebView in order to get the JavaScript to run (filling this hidden div with JSON).

How to pass parameter into HTML file from android

I can show up HTML file content in android webview well.Now how could i pass parameter into HTML file.For ex.my HTML content has an video player
i need to pass dynamic values(URL) into HTML file for playing dynamic video.My HTML file is located on asset folder.How could i do this?
Thanks.
I came upon this problem today, however I needed this to work with UTF-8 encoding, so this was my approach, hopefully it will help someone and clarify some of the previous answers to this question.
HTML:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<h1>%ERR_TITLE%</h1>
<h2>%ERR_DESC%</h2>
</body>
</html>
Java:
String content = IOUtils.toString(getAssets().open("error.html"))
.replaceAll("%ERR_TITLE%", getString(R.string.error_title))
.replaceAll("%ERR_DESC%", getString(R.string.error_desc))
mWebView.loadDataWithBaseURL("file:///android_asset/error.html", content, "text/html", "UTF-8", null);
As for IOUtils:
http://commons.apache.org/proper/commons-io/download_io.cgi
Instead of passing directly the video URL (following you example), i would have used tokens in the Html file. For example:
<embed src="$VIDEO_URL$" autostart="false" />
where the $VIDEO_URL$ will be the token wich will be replaced during the runtime with a real video URL.
Also, since you cannot change the contents of your asset folder during runtime you should load the html file contents into a String variable and use the replace method to replace the token with a real URL and, finally, pass that string to your webview. Something like this:
//The html variable has the html contents of the file stored in the assets folder
//and real_video_url string variable has the correct video url
html = html.replace("$VIDEO_URL$", real_video_url);
webview.loadData(html, "text/html", "utf-8");
If i would like to have something dynamic in my HTML i would have an html with dynamic parts written like this:
<B>%NAME%</B>
Then i would load my HTML:
String template = Utils.inputStreamToString(assets.open("html/template.html"));
then
Then i would replace all dynamics parts with what i want like this:
String data = template.replaceAll("%NAME%", "Alice McGee");
then i would pass it to my webView!
WebView webView = new WebView(this);
webView.loadDataWithBaseURL("file:///android_asset/html/", data, "text/html", "utf-8", null);
I managed to pass variables in a different way.
My problem was that everytime I switched to another app, when coming to the webapp, the webview kept reloading. I guess that's because of the following line in my onCreate() method: myWebView.loadUrl(url); I had the idea to pass these state variables in the url, but as you know it is not possible yet.
What I did was to save the state of some variables using onSaveInstanceState(Bundle outState) {...} and restore them with onRestoreInstanceState(Bundle savedInstanceState){...}.
In onCreate method after setting up myWebView I did the following:
myWebView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String urlString)
{
Log.i("onPageFinished", "loadVariables("+newURL+")");
if(newURL!="")
myWebView.loadUrl("javascript:loadVariables("+"\""+newURL+"\")");
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
jsInterface = new JSInterface(this,myWebView);
myWebView.addJavascriptInterface(jsInterface, "Android");
if (savedInstanceState != null)
{
// retrieve saved variables and build a new URL
newURL = "www.yoururl.com";
newURL +="?var1=" + savedInstanceState.getInt("key1");
newURL +="?var2=" + savedInstanceState.getInt("key2");
Log.i("myWebApp","NEW URL = " + newURL);
}
myWebView.loadUrl("www.yoururl.com");
So, what it happens is that first I load the page with the default URL (www.yoururl.com) and onPageFinished I call a new javascript method where I pass the variables.
In javascript loadVariables function looks like this:
function loadVariables(urlString){
// if it is not the default URL
if(urlString!="www.yoururl.com")
{
console.log("loadVariables: " + urlString);
// parse the URL using a javascript url parser (here I use purl.js)
var source = $.url(urlString).attr('source');
var query = $.url(urlString).attr('query');
console.log("URL SOURCE = "+source + " URL QUERY = "+query);
//do something with the variables
}
}
here assets means what?
String template = Utils.inputStreamToString(assets.open("html/template.html"));

Jsoup select() return nothing in Android application

I'm making an Android app for my board community. The board provider gives me RSS feeds from general categories but don't generate feeds from topics. So I retreive topics URLs from these feeds and want to parse HTML with Jsoup and give it to a WebView.
It works nice except with the select() function which returns nothing.
The "HTML RETREIVED" log gives me : <html><head><title>The topic title</title></head><body></body></html>
h1 tags are in the code on test purpose : it displays well on WebView and the title of the parsed webpage too.
I also putted the log line right after the select() line. It returns nothing too.
I've tried in a pure Java project to parse with Jsoup only and it goes well.
So I assumed something's wrong with Android.
PS : Internet permission is active in the manifest.
Did I miss something ?
Here is the code :
String html;
Bundle param = this.getIntent().getExtras();
String url = param.getString("url");
try {
Document doc = Jsoup.connect(url).get();
doc.select(".topic .clear").remove();
String title = doc.title().toString();
html = doc.select(".username strong, .entry-content").toString();
html = "<html><head><title>"+title+"</title></head><body><h1>"+title+"</h1>"+html+"</body></html>";
WebView webview = new WebView(this);
getWindow().requestFeature(Window.FEATURE_PROGRESS);
setContentView(webview);
webview.getSettings().setJavaScriptEnabled(true);
final Activity activity = this;
webview.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
activity.setProgress(progress * 1000);
Log.d("LOADING",""+ progress);
}
});
webview.loadData(html, "text/html", "UTF-8");
//webview.loadUrl(url);
Log.i("HTML RETREIVED", ""+html);
} catch (IOException e) {
Log.e("ERROR", "Error while generate topic");
}
Ok I've found out something interesting.
The class I wanted to select was not here because I'm getting the mobile version of the webpage. It appears Android App use a mobile user-agent, which is quite normal but not said anywhere.
Anyway I know what thinking about now.

Parse HTML in Android

I am trying to parse HTML in android from a webpage, and since the webpage it not well formed, I get SAXException.
Is there a way to parse HTML in Android?
I just encountered this problem. I tried a few things, but settled on using JSoup. The jar is about 132k, which is a bit big, but if you download the source and take out some of the methods you will not be using, then it is not as big.
=> Good thing about it is that it will handle badly formed HTML
Here's a good example from their site.
File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");
//http://jsoup.org/cookbook/input/load-document-from-url
//Document doc = Jsoup.connect("http://example.com/").get();
Element content = doc.getElementById("content");
Elements links = content.getElementsByTag("a");
for (Element link : links) {
String linkHref = link.attr("href");
String linkText = link.text();
}
Have you tried using Html.fromHtml(source)?
I think that class is pretty liberal with respect to source quality (it uses TagSoup internally, which was designed with real-life, bad HTML in mind). It doesn't support all HTML tags though, but it does come with a handler you can implement to react on tags it doesn't understand.
String tmpHtml = "<html>a whole bunch of html stuff</html>";
String htmlTextStr = Html.fromHtml(tmpHtml).toString();
We all know that programming have endless possibilities.There are numbers of solutions available for a single problem so i think all of the above solutions are perfect and may be helpful for someone but for me this one save my day..
So Code goes like this
private void getWebsite() {
new Thread(new Runnable() {
#Override
public void run() {
final StringBuilder builder = new StringBuilder();
try {
Document doc = Jsoup.connect("http://www.ssaurel.com/blog").get();
String title = doc.title();
Elements links = doc.select("a[href]");
builder.append(title).append("\n");
for (Element link : links) {
builder.append("\n").append("Link : ").append(link.attr("href"))
.append("\n").append("Text : ").append(link.text());
}
} catch (IOException e) {
builder.append("Error : ").append(e.getMessage()).append("\n");
}
runOnUiThread(new Runnable() {
#Override
public void run() {
result.setText(builder.toString());
}
});
}
}).start();
}
You just have to call the above function in onCreate Method of your MainActivity
I hope this one is also helpful for you guys.
Also read the original blog at Medium
Maybe you can use WebView, but as you can see in the doc WebView doesn't support javascript and other stuff like widgets by default.
http://developer.android.com/reference/android/webkit/WebView.html
I think that you can enable javascript if you need it.

Categories

Resources