How to resolve Jsoup Array Index Out Of Bounds Exception? - android

Trying to get data from website through HTML parsing.
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
Why is the array empty?
I included only the class that contains Jsoup because im sure the error is in it. And also i included the HTML part of the website in case you guys wanna take a look at it.
Jsoup Class
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
public class contentExcluding {
public String[] createData(final String [] text, final String [] pictures)
{
Runnable rMain = new Runnable() {
#Override
public void run() {
try {
Document doc = Jsoup.connect("http://egyptianstreets.com/").get();
Element content = doc.getElementById("featured-multi-main-img");
Elements headlines = content.getElementsByTag("img");
Elements img = content.getElementsByAttribute("src");
String x = img.toString();
pictures[0] = x;
text[0] = x;
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread t = new Thread(rMain);
t.start();
return pictures;
}
}
HTML
<div id="head-wrap" class="left relative">
<div class="head-wrap-out">
<div class="head-wrap-in">
<div id="featured-multi-wrap" class="left relative">
<div id="featured-multi-main" class="left relative">
<a href="http://egyptianstreets.com/2016/08/06/egyptian-rowers-nadia-negm-and-abdel-khalek-elbana-reach-quarter-finals-at-olympics/" rel="bookmark">
<div id="featured-multi-main-img" class="left relative">
<img width="1000" height="512" src="http://egyptianstreets.com/wp-content/uploads/2016/08/pablo-2-1000x512.png" class="unlazy reg-img wp-post-image" alt="pablo (2)" /> <img width="400" height="240" src="http://egyptianstreets.com/wp-content/uploads/2016/08/pablo-2-400x240.png" class="unlazy mob-img wp-post-image" alt="pablo (2)" />

It looks like pictures or text are 0 length arrays.
Check that you initialized them (before call createData method) with a higher size of 0.
Example:
String[] pictures = contentExcluding.createData(new String[1], new String[1]);

Related

Get Only One Div (By Class) in WebView via JSoup

I am trying to get only one div (by class) to my webview. I don't know anything about PHP or CSS so i can't realize what should I do when i parse them by class name. I want to take
<div class="container_wrap container_wrap_first main_color fullsize">
part here but its so complicated so i really don't know what to write on doc.select(div. "HERE"). Thanks in advice.
Divs I Must Parse:
<div id="wrap_all">
<div class="mobil-logo">
<div id="main" data-scroll-offset="88">
<!--- header icerik sonu--->
<div class="container_wrap container_wrap_first main_color fullsize">
<div class="container">
And this is what I tried in Main.java:
// webview settings here
loadJsoup();
public void loadJsoup(){
try {
doc = Jsoup.connect("http://isvecehliyet.se/mobil").timeout(10000).get();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Element ele = doc.select("div.entry-content-wrapper").first();
String html = ele.toString();
String mime = "text/html";
String encoding = "utf-8";
mWebview.loadData(html, mime, encoding);
}
This works for me:
String url = "http://isvecehliyet.se/mobil/";
Document doc = Jsoup.connect(url).get();
Elements e = doc.select("div.container").first().parents();
System.out.println(e);
Part of output:
<div class="container_wrap container_wrap_first main_color fullsize">
<div class="container">
<main class="template-page content av-content-full alpha units" role="main" itemprop="mainContentOfPage">
<article class="post-entry post-entry [...]

how to upgrade a phonegap plugin from 1.6.x to 2.7?

The code is aim for grap content by using jsoup, and i'm try to upgrade the code
Here is my code so far:
package com.phonegap.g7.plugin;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.apache.cordova.api.CordovaPlugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class UrlFeedJava extends CordovaPlugin {
//#Override
public PluginResult execute(String action, JSONArray data, String callbackId) {
PluginResult.Status status = PluginResult.Status.OK;
PluginResult r=null;
try
{
String target = data.getString(0);
String selector = data.getString(1);
Document doc = Jsoup.connect(target).get();
Element masthead = doc.select(selector).first();
String content=masthead.toString();
String title = doc.title();
r=new PluginResult(status,content);
}
catch(Exception ee)
{
System.out.print("ee:"+ee.getMessage());
}
return r;
}
}
the PhonegapPlugin.js file
UrlFeed.prototype = {
send: function(success, error, url, selector){
cordova.exec(success, error, "UrlFeedJava", "send", [url, selector]);
}
};
PhoneGap.addConstructor(function() {
PhoneGap.addPlugin('urlfeed', new UrlFeed());
});
the index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<script type='text/javascript' src='jquery-1.8.3.min.js'></script>
<script type='text/javascript' src='cordova-2.7.0.js'></script>
<script type='text/javascript' src='PhonegapPlugin.js'></script>
<script type='text/javascript'>
$(function(){
var onSend = function(){
var success = function(data){
$('#show').html(data);
};
var error = function(e){
alert(e);
};
var url = 'http://sports.163.com/12/0618/09/8496QLNG00051C8V.html';
var selector = $('#selector').val();
window.plugins.urlfeed.send(success, error, url, selector);
};
$('#send').bind('click', onSend);
});
</script>
</head>
<body>
<div id='messageDiv'>
<input type='text' id='selector'></input>
<div id='show'></div>
<button type='button' id='send'>Send Me</button>
</div>
</body>
</html>
Especially i don't understand the function of the constructor.
With newer phonegap releases you define the constructor in javascript like this:
var UrlFeed = function(){};
cordova.addConstructor(function() {
if (!window.plugins) {
window.plugins = {};
}
window.plugins.UrlFeed = new UrlFeed();
});
It makes the urlfeed object available to your entire application, you access it anywhere like
window.plugins.UrlFeed.doSomething();
Adding methods to your plugin:
UrlFeed.prototype.doSomething = function(arguments){
//do stuff
//send to phonegap
return PhoneGap.exec(
successCallback,
failureCallback,
'UrlFeed',
null,
[arguments]
);
};
You have to change your java plugin like this:
public class UrlFeedJava extends CordovaPlugin {
//#Override
public boolean execute(String action, JSONArray args,
final CallbackContext callbackContext) throws JSONException {
//your code
return true;
}
}
So basic change is that you do not return a plugin result anymore, but a simple boolean. So remove all plugin result code from your java code.
Please have a look at the simple toast plugin. It shows you how a phonegap plugin is developed https://github.com/giver/cordova-android-toast-plugin
Ref: http://docs.phonegap.com/en/2.8.0/guide_plugin-development_index.md.html#Plugin%20Development%20Guide

Parsing specific texts using Jsoup

I have a cities.txt file placed in my res/raw folder. Inside it contains the following.
<div class="state">Alabama</div>
<ul><li>auburn</li>
<li>birmingham</li> </ul>
<div class="state">Alaska</div>
<ul><li>anchorage</li>
<li>fairbanks</li></ul>
<div class="state">Arizona</div>
<ul><li>flagstaff</li>
<li>mohave county</li></ul>
I want to grab the cities for the state Alabama and display it on a ListView. The ouput should be like this.
auburn
birmingham
My current code grabs all the six cities and displays them on the ListView instead. This is my code.
package com.example.readfile;
import java.io.InputStream;
import java.util.ArrayList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import android.app.Activity;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class Cities extends Activity {
ListView listUSCities;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.city_layout);
listUSCities = (ListView) findViewById(R.id.listcities);
new MyTask().execute();
}
class MyTask extends AsyncTask<Void, Void, ArrayList<String>> {
ArrayList<String> arr_linkText = new ArrayList<String>();
#Override
protected ArrayList<String> doInBackground(Void... params) {
Document doc;
try {
Resources res = getResources();
InputStream in_s = res.openRawResource(R.raw.cities);
byte[] b = new byte[in_s.available()];
in_s.read(b);
// Parsing using Jsoup starts here
doc = Jsoup.parse(new String(b));
// Parsing the states
Elements links = doc.select("div");
for (Element link : links) {
if (link.text().contains("Alabama")) {
// Extracting the cities
Elements cities = doc.select("a");
for (Element city : cities) {
arr_linkText.add(city.text());
}
}
}
} catch (Exception e) {
// e.printStackTrace();
}
return arr_linkText; // << retrun ArrayList from here
}
#Override
protected void onPostExecute(ArrayList<String> result) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
Cities.this, android.R.layout.simple_list_item_1,
android.R.id.text1);
for (String temp_result : result) {
adapter.add(temp_result);
}
listUSCities.setAdapter(adapter);
}
}
}
How can I extract the cities only for that specified state?
How do I stop parsing the file after I extracted the cities to optimize speed?
The actual cities.txtcontains more information, I only provided a sample. I will appreciate your help. Thank you!
// Parsing the states
Elements links = doc.select("div");
for (Element link : links) {
if (link.text().contains("Alabama")) {
// Extracting the cities
Elements cities = link.select("a");//<- 'doc' is the whole doc, link is your state.
for (Element city : cities) {
arr_linkText.add(city.text());
}
break;//breaks off the loop, since you have found what you want.
}
}
That is an odd structure for an HTML document. The <div> is used just for the header, and the list is off by itself. Seeing as you trimmed the actual document, this may or may not work. The elements you are after are in the ul element following your div, so you need to go to the next sibling and search there. This will only work if there are no other elements between your div and ul elements.
Elements links = doc.select("div");
for (Element link : links) {
if (link.text().contains("Alabama")) {
// Extracting the cities in the list that is next in the DOM
Elements cities = link.nextElementSibling().select("a");
for (Element city : cities) {
arr_linkText.add(city.text());
}
}
}

How to open contents of a html page which contains Google api for charts in Android emulator

I want to open the contents of a html file which I have saved in my assets folder. The html file contains the chart api provided by the Google graphs.
Content of the HTML file are:
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi">
</script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart()
{
var data = google.visualization.arrayToDataTable([ ['Task', 'Hours per Day'],
['Work', 11],
['Eat', 2],
['Commute', 2],
['Watch TV', 2],
['Sleep', 7]
]);
var options = {title: 'My Daily Activities'};
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
I have written my main activity class as:
package com.example.webapptest;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.webkit.WebSettings;
import android.webkit.WebView;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webview = new WebView(this);
WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);
setContentView(webview);
InputStream fin;
try {
fin = getAssets().open("web_page_test.html");
byte[] buffer = new byte[fin.available()];
fin.read(buffer);
fin.close();
webview.loadData(new String(buffer), "text/html", "UTF-8");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
But it is showing that web page is down or not available error.

Android - Automate HTML Checkbox and Submit

I want my app to automatically access a webpage, check or uncheck a box and click submit
I have tried many codes given here with no success.
eg:
html snippet:
<tr>
<td align="center"><input type="checkbox" name="Yes" ></td>
</tr>
</table>
<p> </td>
<td width="112" height="27" align="right">
<input type="submit" value="SubmitForm" style="float: left"></td>
I want my code to toggle the "yes" and then click the submit button "SubmitForm"
thanks!
usually something like this http://kspace.in/blog/2008/05/30/submit-html-form-using-java/
package post;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpPostForm
{
public static void main(String[] args)
{
try
{
URL url = new URL( "http://www.aaaa.com/xyz.asp" );
HttpURLConnection hConnection = (HttpURLConnection)
url.openConnection();
HttpURLConnection.setFollowRedirects( true );
hConnection.setDoOutput( true );
hConnection.setRequestMethod("POST");
PrintStream ps = new PrintStream( hConnection.getOutputStream() );
ps.print("param1=abcd&param2=10341");
ps.close();
hConnection.connect();
if( HttpURLConnection.HTTP_OK == hConnection.getResponseCode() )
{
InputStream is = hConnection.getInputStream();
OutputStream os = new FileOutputStream("output.html");
int data;
while((data=is.read()) != -1)
{
os.write(data);
}
is.close();
os.close();
hConnection.disconnect();
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}

Categories

Resources