How To Extract Table Data Via Android - java

I'm attempting to extract data from a table on a web page. Thus far I've been able to extract the data from the title tag - but not the table data. How can this be accomplished using the source shown below?
SOURCE:
public class MainActivity extends Activity {
TextView tv;
final String URL="http://example.com";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.TextView01);
new MyTask().execute(URL);
}
private class MyTask extends AsyncTask<String, Void, String> {
ProgressDialog prog;
String title = "";
#Override
protected void onPreExecute() {
prog = new ProgressDialog(MainActivity.this);
prog.setMessage("Loading....");
prog.show();
}
#Override
protected String doInBackground(String... params) {
try {
Document doc = Jsoup.connect(params[0]).get();
title = doc.title();
} catch (IOException e) {
e.printStackTrace();
}
return title;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
prog.dismiss();
tv.setText(result);
}
}
}
EDIT - In Response to Matej Spili's comment below:
public class MainActivity extends Activity {
TextView tv;
final String URL="http://example.com";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.TextView01);
new MyTask().execute(URL);
}
private class MyTask extends AsyncTask<String, Void, String> {
ProgressDialog prog;
String title = "";
#Override
protected void onPreExecute() {
prog = new ProgressDialog(MainActivity.this);
prog.setMessage("Loading....");
prog.show();
}
#Override
protected String doInBackground(String... params) {
try {
Document doc = Jsoup.connect(params[0]).get();
Element tableHeader = doc.select("tr").first();
for( Element element : tableHeader.children() )
{
// Here you can do something with each element
System.out.println(element.text());
tv.setText(element.text());
}
title = doc.title();
} catch (IOException e) {
e.printStackTrace();
}
return title;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
prog.dismiss();
tv.setText(result);
}
}
}
^- (causes error: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views)

Pass the view that you want to update as constructor argument for the MyTask like
new MyTask(tv).execute(URL);
Change your MyTask accordingly to accept this argument.

Related

java.lang.IllegalStateException: Fragment not attached to Activity issue in android

I am facing strange issue during call of my activity with Fragment usage. I am getting error like,
java.lang.IllegalStateException: Fragment ScoreFragment{ee2b833
id=0x7f0e0198} not attached to Activity
On line 146. My Fragment code which have error is line like below
if(mPageFlag.equalsIgnoreCase(getString(R.string.winners))){
And My full code for same is below,
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mPageFlag = getArguments().getString(ARG_PAGE_FLAG);
}
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser && !mIsPageLoaded){
mContext = getActivity();
mIsPageLoaded = true;
if(mPageFlag.equalsIgnoreCase(getString(R.string.winners))){
new getcontestscorewinners(mContext).execute();
}else{ //
new getcontestscorewinnersNew(mContext).execute();
}
}
}
public class getcontestscorewinners extends AsyncTask<String, Void, String> {
boolean response = false;
private Context mContext;
public getcontestscorewinners(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
progress = ProgressDialog.show(mContext, "Processing...",
"Please wait....");
}
#Override
protected String doInBackground(String... params) {
NetworkTask.getContestScoreWinners(winnerHandler);
return "";
}
#Override
protected void onPostExecute(String result) {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
Let me know if someone can help me for get out of it. Thanks.
Try using isAdded():
Return true if the fragment is currently added to its activity.
So your code should be like this :
if(isAdded() && mPageFlag.equalsIgnoreCase(getString(R.string.winners))){

Updating a TextView out an AsyncTask

I am trying the apply this example to my project but I am getting the following error:
Error:(26, 33) error: cannot find symbol method findViewById(int)
This is how my code looks like:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.AsyncTask;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView display = (TextView) findViewById(R.id.textView1);
display.setText("Hello Android!");
Connect myConnect = new Connect();
myConnect.execute();
}
}
class Connect extends AsyncTask<Void, Void, Integer> {
TextView Text1 = (TextView) findViewById(R.id.textView1);
#Override
protected void onPreExecute(){
}
#Override
protected Integer doInBackground(Void... params) {
return 0;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onPostExecute(0);
Text1.setText("Text Changed");
}
}
What am I missing here?
How can I reference the TextView through the AsyncTask?
This is incorrect :
class Connect extends AsyncTask<Void, Void, Integer> {
TextView Text1 = (TextView) findViewById(R.id.textView1);
findViewById is a method of Activity class. not AsyncTask
to fix it, use this:
Connect myConnect = new Connect(display);
and create constructor:
class Connect extends AsyncTask<Void, Void, Integer> {
TextView Text1;
public Connect(TextView tv) {
Text1 = tv;
}
and you have got the other error:
#Override
protected void onProgressUpdate(Void... values) {
super.onPostExecute(0);
Text1.setText("Text Changed");
}
change it into this:
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
Text1.setText("Text Changed");
}
SUMMARISE
//one file
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView display = (TextView) findViewById(R.id.textView1);
display.setText("Hello Android!");
Connect myConnect = new Connect(display);
myConnect.execute();
}
}
//possible the other file. but you can put the class below as nested - just move previous paranthesis to the end of the code
class Connect extends AsyncTask {
TextView Text1;
public Connect(TextView tv) {
Text1 = tv;
}
#Override
protected void onPreExecute(){
}
#Override
protected Integer doInBackground(Void... params) {
/*publish your progress here
publishProgress(...);
*/
return 0;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
Text1.setText("Text Changed");
}
}
Your text view is related to your MainActivity so create the global reference in activity class only and use it for sub class also.
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.AsyncTask;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView Text1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Text1 = (TextView) findViewById(R.id.textView1);
Text1.setText("Hello Android!");
Connect myConnect = new Connect();
myConnect.execute();
}
class Connect extends AsyncTask<Void, Void, Integer> {
#Override
protected void onPreExecute(){
}
#Override
protected Integer doInBackground(Void... params) {
return 0;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onPostExecute(0);
Text1.setText("Text Changed");
}
}
}
Use your view inside onCreate(). onProgressUpdate() will be called on the main application thread (a.k.a., UI thread). As said by CommansWare
Global
private TextView Text1;
use as:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView display = (TextView) findViewById(R.id.textView1);
Text1 = (TextView) findViewById(R.id.textView1); //here
.........
Set as it is
#Override
protected void onProgressUpdate(Void... values) {
super.onPostExecute(0);
Text1.setText("Text Changed");
}
findViewById() is not accessible inside AsyncTask, the method belongs to activity, so you cannot initialize view using id inside Asynctask. Initialize your view in activity inside onCreate and use the instance in async task
public class MainActivity extends AppCompatActivity {
TextView display;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
display = (TextView) findViewById(R.id.textView1);
display.setText("Hello Android!");
Connect myConnect = new Connect();
myConnect.execute();
}
class Connect extends AsyncTask<Void, Void, Integer> {
#Override
protected void onPreExecute(){
}
#Override
protected Integer doInBackground(Void... params) {
return 0;
}
#Override
protected void onProgressUpdate(Void... values) {
}
protected void onPostExecute(Long result) {
display.setText("Text Changed");
}
}}

In AsyncTask on onPostExecute the textview value is not setting

Textview value is crashing with null pointer exception
Below is the code which i am using. Is there any issue in the code.
public class MainActivity extends Activity {
Button btn;
int i =0;
SharedPreferences.Editor preferences;
TextView txt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.button1);
preferences = PreferenceManager.getDefaultSharedPreferences(MainActivity.this).edit();
txt = (TextView) findViewById(R.id.textView1);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
new LongOperation().execute("");
}
});
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
txt.setText("Executed ----------------------- ");
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
}
After it is coming to onPostExecute the textview value is not setting the value.
Please help me. Thanks in advance.
Textview value is not setting because the value of id may be null. check it.

how to parsing with jsoup using asynctask

I have to parse a web page and store the content of some tag in a ListView.
Now, I have this code:
public class MainActivity extends Activity
{
private MyTask myTask;
ListView listView;
final String URL = "http://en.wikipedia.org";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list);
myTask = new MyTask();
myTask.execute(URL);
}
class MyTask extends AsyncTask<String, Void, String>
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String url = params[0];
Document doc;
Elements table = null;
try {
doc = Jsoup.connect(url).get();
table = doc.select("table").select("tbody");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return table.toString();
}
protected void onPostExecute(String result)
{
super.onPostExecute(result);
listView = (ListView) findViewById(R.id.list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, R.layout.riga);
listView.setAdapter(adapter);
}
}
}
but the execution return always a white screen. What can I do??
I'm sure that the error is in the postExecute method but I can't see it.

The constructor MainActivity.MyTask(TextView) is undefined

I'm getting an error stating: The constructor MainActivity.MyTask(TextView) is undefined after following a suggestion from another SO user as to how to fix my Android based web scraper:
How To Extract Table Data Via Android
I've attempted to create a constructor:
public MyTask(TextView tv) {
// TODO Auto-generated constructor stub
}
however that does not seem to resolve the issue (the error goes away - but the textview is never updated.)
ERROR:
The constructor MainActivity.MyTask(TextView) is undefined
SOURCE:
public class MainActivity extends Activity {
TextView tv;
final String URL = "http://news.google.com";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.TextView01);
new MyTask(tv).execute(URL);
}
private class MyTask extends AsyncTask<String, Void, String> {
ProgressDialog prog;
String title = "";
#Override
protected void onPreExecute() {
prog = new ProgressDialog(MainActivity.this);
prog.setMessage("Loading....");
prog.show();
}
#Override
protected String doInBackground(String... params) {
try {
Document doc = Jsoup.connect(params[0]).get();
Element tableHeader = doc.select("tr").first();
for (Element element : tableHeader.children()) {
// Here you can do something with each element
System.out.println(element.text());
tv.setText(element.text());
}
title = doc.title();
} catch (IOException e) {
e.printStackTrace();
}
return title;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
prog.dismiss();
tv.setText(result);
}
}
}
EDIT IN RESPONSE TO Raghunandan's ANSWER:
public class MainActivity extends Activity {
Context context;
TextView tv;
final String URL = "http://news.google.com";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.TextView01);
new MyTask().execute(URL);
}
private class MyTask extends AsyncTask<String, Void, String> {
ProgressDialog prog;
String title = "";
#Override
protected void onPreExecute() {
prog = new ProgressDialog(MainActivity.this);
prog.setMessage("Loading....");
prog.show();
}
#Override
protected String doInBackground(String... params) {
try {
Document doc = Jsoup.connect(params[0]).get();
Element tableHeader = doc.select("tr").first();
for (Element element : tableHeader.children()) {
// Here you can do something with each element
// System.out.println(element.text());
// tv.setText(element.text());
// //cannot update ui here.
// use Log.i instead of System.out.println
}
title = doc.title();
} catch (IOException e) {
e.printStackTrace();
}
return value;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
prog.dismiss();
// tv.setText(result);
Document doc = Jsoup.connect(params[0]).get();
Element tableHeader = doc.select("tr").first();
for (Element element : tableHeader.children()) {
// Here you can do something with each element
System.out.println(element.text());
tv.setText(element.text());
// cannot update ui here.
}
}
}
}
You have this
new MyTask(tv).execute(URL);
But in your asycntask you does not have constructor like
public MyTask(TextView tv)
{
}
There is not need to pass textview to the constructor if your asynctask is an inner class of your activity class coz you have textview declared as a activity class member.
You can set the text in onPostExecute. But you are setting text in doInbackground.
doInbackground is invoked on a background thread. So you cannot set text there. You need to update ui on the ui thread.
If asynctask is not an inner class then use a interface
Can't post response from AsyncTask to MainActivity
public class MainActivity extends Activity {
Context context;
TextView tv;
final String URL = "http://news.google.com";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.textView1);
new MyTask().execute(URL);
}
private class MyTask extends AsyncTask<String, Void, String> {
ProgressDialog prog;
String title = "";
#Override
protected void onPreExecute() {
prog = new ProgressDialog(MainActivity.this);
prog.setMessage("Loading....");
prog.show();
}
#Override
protected String doInBackground(String... params) {
try {
Document doc = Jsoup.connect(params[0]).get();
Element tableHeader = doc.select("tr").first();
for (Element element : tableHeader.children()) {
// Here you can do something with each element
//System.out.println(element.text());
//tv.setText(element.text());
//cannot update ui here.
// use Log.i instead of System.out.println
}
title = doc.title();
} catch (IOException e) {
e.printStackTrace();
}
return title;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
prog.dismiss();
tv.setText(result);
}
}
}
For more info on asynctask
http://developer.android.com/reference/android/os/AsyncTask.html
Edit:
public class MainActivity extends Activity {
Context context;
ArrayList<String> aa = new ArrayList<String>();
ListView lv;
final String URL = "http://news.google.com";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv= (ListView) findViewById(R.id.listView1);
new MyTask().execute(URL);
}
private class MyTask extends AsyncTask<String, Void, String> {
ProgressDialog prog;
String title = "";
#Override
protected void onPreExecute() {
prog = new ProgressDialog(MainActivity.this);
prog.setMessage("Loading....");
prog.show();
}
#Override
protected String doInBackground(String... params) {
try {
Document doc = Jsoup.connect(params[0]).get();
Element tableHeader = doc.select("tr").first();
for (Element element : tableHeader.children()) {
aa.add(element.text().toString());
}
title = doc.title();
} catch (IOException e) {
e.printStackTrace();
}
return title;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
prog.dismiss();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,aa);
lv.setAdapter(adapter);
}
}
}
activtiy_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
</RelativeLayout>
Snap shot

Categories