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.
Related
this is the code:
public class MainActivity extends AppCompatActivity {
ListView listView;
ProgressBar progressBar;
String HTTP_JSON_URL = "http://10.0.2.2/positivity/all_subjects.php";
EditText editText;
List SubjectArrayList = new ArrayList();
ArrayAdapter arrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listview1);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
editText = (EditText) findViewById(R.id.edittext1);
// Calling Method to Parese JSON data into listView.
new GetHttpResponse(MainActivity.this).execute();
// Calling EditText addTextChangedListener method which controls the EditText type sequence.
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//Updating Array Adapter ListView after typing inside EditText.
MainActivity.this.arrayAdapter.getFilter().filter(charSequence);
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
}
});
// Adding On item click listener on ListView.
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
String Item = parent.getItemAtPosition(position).toString();
// Showing ListView click item using Toast message on screen.
Toast.makeText(MainActivity.this, Item, Toast.LENGTH_LONG).show();
}
});
}
// Creating GetHttpResponse message to parse JSON.
public class GetHttpResponse extends AsyncTask<Void, Void, Void> {
// Creating context.
public Context context;
// Creating string to hold Http response result.
String ResultHolder;
// Creating constructor .
public GetHttpResponse(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
// Sending the Http URL into HttpServicesClass to parse JSON.
HttpServicesClass httpServiceObject = new HttpServicesClass(HTTP_JSON_URL);
try {
httpServiceObject.ExecutePostRequest();
// If the server response code = 200 then JSON parsing start.
if (httpServiceObject.getResponseCode() == 200) {
// Adding Http response into ResultHolder string.
ResultHolder = httpServiceObject.getResponse();
// If there is response present into ResultHolder.
if (ResultHolder != null) {
// Creating JSONArray and set it to null.
JSONArray jsonArray = null;
try {
// Adding ResultHolder into JSONArray.
jsonArray = new JSONArray(ResultHolder);
// Creating JSONObject.
JSONObject jsonObject;
// Starting for loop at the end of jsonArray length.
for (int i = 0; i < jsonArray.length(); i++) {
// Adding JSON array object .
jsonObject = jsonArray.getJSONObject(i);
// Adding the JSON parse object into SubjectArrayList.
SubjectArrayList.add(jsonObject.getString("subject_Name").toString());
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else {
// If something goes wrong then showing the error message on screen.
Toast.makeText(context, httpServiceObject.getErrorMessage(), Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
// This block will execute after done all background processing.
#Override
protected void onPostExecute(Void result) {
// Hiding the progress bar after done loading JSON.
progressBar.setVisibility(View.GONE);
// Showing the ListView after done loading JSON.
listView.setVisibility(View.VISIBLE);
// Setting up the SubjectArrayList into Array Adapter.
arrayAdapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_2, android.R.id.text1, SubjectArrayList);
// Passing the Array Adapter into ListView.
listView.setAdapter(arrayAdapter);
}
}
}
In your activity, where you defined your listview
you write
public class MainActivity extends AppCompatActivity {
ListView listView;
ProgressBar progressBar;
String HTTP_JSON_URL = "http://10.0.2.2/positivity/all_subjects.php";
EditText editText;
List SubjectArrayList = new ArrayList();
ArrayAdapter arrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listview1);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
editText = (EditText) findViewById(R.id.edittext1);
// Calling Method to Parese JSON data into listView.
new GetHttpResponse(MainActivity.this).execute();
// Calling EditText addTextChangedListener method which controls the EditText type sequence.
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
//Updating Array Adapter ListView after typing inside EditText.
MainActivity.this.arrayAdapter.getFilter().filter(charSequence);
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
}
});
// Adding On item click listener on ListView.
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
//ItemClicked item = parent.getItemAtPosition(position);
if(position==0)
{
Intent intent = new Intent(MainActivity.this,one.class);
//based on item add info to intent
startActivity(intent);
}
}
});
}
// Creating GetHttpResponse message to parse JSON.
public class GetHttpResponse extends AsyncTask<Void, Void, Void> {
// Creating context.
public Context context;
// Creating string to hold Http response result.
String ResultHolder;
// Creating constructor .
public GetHttpResponse(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
// Sending the Http URL into HttpServicesClass to parse JSON.
HttpServicesClass httpServiceObject = new HttpServicesClass(HTTP_JSON_URL);
try {
httpServiceObject.ExecutePostRequest();
// If the server response code = 200 then JSON parsing start.
if (httpServiceObject.getResponseCode() == 200) {
// Adding Http response into ResultHolder string.
ResultHolder = httpServiceObject.getResponse();
// If there is response present into ResultHolder.
if (ResultHolder != null) {
// Creating JSONArray and set it to null.
JSONArray jsonArray = null;
try {
// Adding ResultHolder into JSONArray.
jsonArray = new JSONArray(ResultHolder);
// Creating JSONObject.
JSONObject jsonObject;
// Starting for loop at the end of jsonArray length.
for (int i = 0; i < jsonArray.length(); i++) {
// Adding JSON array object .
jsonObject = jsonArray.getJSONObject(i);
// Adding the JSON parse object into SubjectArrayList.
SubjectArrayList.add(jsonObject.getString("subject_Name").toString());
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else {
// If something goes wrong then showing the error message on screen.
Toast.makeText(context, httpServiceObject.getErrorMessage(), Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
// This block will execute after done all background processing.
#Override
protected void onPostExecute(Void result) {
// Hiding the progress bar after done loading JSON.
progressBar.setVisibility(View.GONE);
// Showing the ListView after done loading JSON.
listView.setVisibility(View.VISIBLE);
// Setting up the SubjectArrayList into Array Adapter.
arrayAdapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_2, android.R.id.text1, SubjectArrayList);
// Passing the Array Adapter into ListView.
listView.setAdapter(arrayAdapter);
}
}
}
Try this one example, actually its same as anywhere else
mListview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intentToYoklamaAl = new Intent(CurrentActivity.this, SecondActivity.class);
// intentToYoklamaAl.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intentToYoklamaAl);
// overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
// finish();
}
});
How can i retrieve data from my db and push it to my listview ?
i want use an asynctask for this.
I have used this code but my app crached every time when i run this.
idk why because when i push data to my db then it works fine. But when i retrieve then i get errors.
public class GetAsync extends AsyncTask<Void,ArrayList<Task>,String> {
private Context context;
private ListView listView;
ArrayAdapter<Task> tasks;
public GetAsync(Context context,ListView listview) {
this.context = context;
this.listView = listview;
}
#Override
protected String doInBackground(Void... voids) {
TaskDbHelper db = new TaskDbHelper(context);
tasks.addAll(db.getTasks());
return "werkt";
}
#Override
protected void onPreExecute() {
tasks = (ArrayAdapter<Task>) listView.getAdapter();
}
#Override
protected void onPostExecute(String aVoid) {
super.onPostExecute(aVoid);
}
}
lvItems = (ListView) findViewById(R.id.lvItems);
new GetAsync(this,lvItems).execute();
Try
public class GetAsync extends AsyncTask<Void,ArrayList<Task>,List<Task>> {
private Context context;
private ListView listView;
ArrayAdapter<Task> tasks;
public GetAsync(Context context, ListView listview) {
this.context = context;
this.listView = listview;
}
#Override
protected List<Task> doInBackground(Void... voids) {
TaskDbHelper db = new TaskDbHelper()
return db.getTasks();
}
#Override
protected void onPreExecute() {
tasks = (ArrayAdapter<Task>) listView.getAdapter();
}
#Override
protected void onPostExecute(List<Task> tasks) {
tasks.addAll(tasks);
}
}
It's because you are not on the UI thread whilst modifying the view. So you want to update the adapter in onPostExecute as that runs on the thread that started the AsyncTask (which I'm assuming is the UI thread)
I want to pull a h2 class that contains multiple variations of it. The posttitle h2 class contains every post title.
<h2 class="posttitle">
Text
</h2>
I want to pull each individual into my application using jsoup. I have already been able to pull all the texts from the "postitle" class.
#Override
protected Void doInBackground(Void... voids) {
try {
Document doc = Jsoup.connect("https://uhsswordandshield.com").get();
Feed = doc.select("h2.posttitle a[href]").text();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
The context is that it is my School's new website and I would like to pull the title of news articles. The title of each articles are part of the posttitle class.
This is what it looks like right now:
Title 1 Title 2 Title 3 Title 4....
What I want:
Title 1
Title 2
Title 3
Title 4
...
I am able to put it into a textview, but it all shows up as a big clump where all the titles are just put together. I would like to put each individual posttitle into an array list. Could someone please tell me if this is possible and how I would go about doing this. Thanks!
EDIT
I changed the code a little bit and I no longer get any errors.
public class MainActivity extends AppCompatActivity {
public static ArrayList<String> titles;
//Declare Listview
public ListView lv ;
//Array Adapter
public ArrayAdapter<String> arrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, titles);
lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(arrayAdapter);
//call AsyncTask
new Feed().execute();
}
//Async Test
private class Feed extends AsyncTask<String,Void,ArrayList<String>>{
//Get post title class
#Override
protected ArrayList<String> doInBackground(String... voids) {
try {
Document doc = Jsoup.connect("https://uhsswordandshield.com").get();
Elements e = doc.select("h2.posttitle");
for (Element el:e) {
titles.add(el.text());
}}
catch (IOException e) {
e.printStackTrace();
}
return titles;
}
}
}
However, this causes me to get a null pointer exception error and my app crashes everytime.
EDIT
So I was able to figure out why I got null pointer exception. I was calling my array list before I declared it. However, I still have not been able to get the posttitle to be added to the array list. This is my main activity right now.
public class MainActivity extends AppCompatActivity {
public ArrayList<String> titles = new ArrayList<String>();
//Declare Listview
//Array Adapter
public ArrayAdapter<String> arrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv = (ListView) findViewById(R.id.lv);
arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, titles);
lv.setAdapter(arrayAdapter);
//Declare Button
new Feed().execute();
}
//call AsyncTask
//Async Test
private class Feed extends AsyncTask<Void,Void,ArrayList<String>>{
//Get post title class
#Override
protected ArrayList<String> doInBackground(Void... voids) {
try {
Document doc = Jsoup.connect("https://uhsswordandshield.com").get();
Elements e = doc.select("h2.posttitle");
for (Element el:e) {
titles.add(el.text());
}}
catch (IOException e) {
e.printStackTrace();
}
return titles;
}
}
}
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
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.