doInBackground error when using Jsoup in Android - android

I'm trying to learn Android and when I was trying to parse HTML by using Jsoup, I get an error and my app stops. I have a button in my layout and when I click it I want the app to update the TextView and write HTML Page's title. Here is the code (necessary parts):
public void onClick(View arg0) {
// TODO Auto-generated method stub
new Title().execute(new String[] {url}); // I have url of an html address as a string above
}
}
class Title extends AsyncTask <String, Void, String> {
String pageTitle;
protected String doInBackground(String... params) {
try {
Document doc = Jsoup.connect(params[0]).get();
pageTitle = doc.title();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return pageTitle;
}
protected void onPostExecute (String... params) {
MainActivity.title.setText(params[0]);
}
}
When I click the button, it says "Unfortunately, App has stopped."
Can anybody tell me what I am doing wrong?

try this in doInBackground() :
{
String pageTitle;
Element ele;
protected String doInBackground(String... params) {
try {
Document doc = Jsoup.connect(params[0]).get();
t =doc.select("title");
pageTitle = t.text();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return pageTitle;
}

Related

error cannot convert from AsyncTask<String,String,String> to String

I want to load a data using JSON from php and then parsing it in android. I'm trying to implement asynctask in this process. And the return is in string. I got an error in
"Type mismatch : cannot convert from AsyncTask<String,String,String> to String in
ProsesTampil p = new ProsesTampil();
xResult = p.execute(urltampil);
The xResult is supposed to be the string value I got from php.
Here's the complete codes :
public void tampilkanData() {
try {
String nama = URLEncoder.encode(Login.usernameP, "utf-8");
urltampil += "?" + "&nama=" + nama;
txtNama.setText("");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ProsesTampil p = new ProsesTampil();
xResult = p.execute(urltampil);
try {
parse();
} catch (Exception e) {
e.printStackTrace();
}
}
private void parse() throws Exception {
//jObject = new JSONObject(xResult);
JSONArray menuitemArray = new JSONArray(xResult);
jObject=menuitemArray.getJSONObject(0);
String sret="";
txtBerat.setText(jObject.getString("berat_badan"));
txtNama.setText(jObject.getString("username"));
// txtUsia.setText(jObject.getString("usia"));
txtTinggi.setText(jObject.getString("tinggi_badan"));
//System.out.println(jObject.getString("jenis_kelamin").equalsIgnoreCase("female"));
if(jObject.getString("jenis_kelamin").equalsIgnoreCase("female")){
radioFemale.setSelected(true);
radioMale.setSelected(false);
}else{
radioMale.setSelected(true);
radioFemale.setSelected(false);
}
}
public String getRequestData(String UrlTampil){
String sret="";
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(UrlTampil);
try{
HttpResponse response = client.execute(request);
sret =request(response);
}catch(Exception ex){
Toast.makeText(this,"Gagal "+sret, Toast.LENGTH_SHORT).show();
}
System.out.println(sret);
return sret;
}
class ProsesTampil extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... params) {
return getRequestData(params[0]);
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
I'm sorry for my bad english. thanks in advance
The propose of an AsyncTask is execute some code in a separate thread (different from UI thread), but the result from that code, when ready, will be delivered in onPostExecute.i.e. The method execute returns the AynscTask itself,not String so change your code as
ProsesTampil p = new ProsesTampil();
xResult = p.execute(urltampil);
to
ProsesTampil p = new ProsesTampil();
p.execute(urltampil);
And get xResult in onPostExecute method as
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
xResult = result;
}
First Thing You can not return value from onPostExecute() because return type is void
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
Second Your class doesn't Return any value...
So if you want to get value of result try to get value from onPostExecute().
I mean to say do as follow..
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
xResult = result;
super.onPostExecute();
}
You can't do it because AsyncTask works in background thread.
Your result will come in UI thread after background has done self work:
#Override
protected void onPostExecute(String result) {
//String result - that what you need
}
execute() doesn't return a string. So you can't assign it like that. AsyncTasks are asynchronous- they don't finish until later. Any code you'd want to run on the result of an AsyncTask should be placed in the onPostExecute() function of the AsyncTask.
Yo can use
String results = yourAsyntask.get() instead of using yourAsyntask.execut()e method, it will return you result. same as Result get you in onPostExecute method;
But it will block your main thread.

How to parse json in the class which extends Application in android

I have an AsyncTask class which parse json data and inserts into an object, when I call it in normal activity classes it shows that data have been parsed but when I execute this on a class which extends Application then it gives zero result. Here is my class
public class AppGlobalData extends Application {
public ArrayList<YoutubeItem> gotItem= new ArrayList<YoutubeItem>();
private YouTubeParser parser;
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
new ParserLoader().execute();
}
public class ParserLoader extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
Log.i("Succeed?", "Yes");
parser = new YouTubeParser(
"http://powergroupbd.com/youtube/getyoutubejson.php");
try {
gotItem = parser.parseInitiator();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
public ArrayList<YoutubeItem> getGotItem() {
return gotItem;
}
public void setGotItem(ArrayList<YoutubeItem> gotItem) {
this.gotItem = gotItem;
}
}
I cant figure out the problem, can anyone help?
please be noted that this class runs and logs my String but doesnt parse data.
I think what might happen is that when new ParserLoader().execute(); it doing the work asynchronously. When your Activity load and call the getGotItem() the Asynctask might not have finished

JSON Parsing in Android for pulling Boolean/Integer values

I am new to JSON and I was wondering how I would pull some info and put it into a JSON Object and then read some of the values. The json info looks like this,
{
"photos":{
"page":1,
"pages":1802,
"perpage":100,
"total":"180134",
"photo": [
{
"id":"8711964781",
"owner":"21156896#N07",
"secret":"3e24e45977",
"server":"8553",
"farm":9,
"title":"Old Harbor",
"ispublic":1,
"isfriend":0,
"isfamily":0
},
{
"id":"8712680696",
"owner":"21156896#N07",
"secret":"fe82f8387b",
"server":"8122",
"farm":9,
"title":"Rockefeller Plaza",
"ispublic":1,
"isfriend":0,
"isfamily":0
},
....
It photo array goes on for quite a while. How would I get the values of "isPublic"? "Secret" is a String because of the "" and isPublic is an integer or boolean? I basically have to put them into a URL link and download the image.
public class ReadString extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... FlickrString) {
try {
json = getValue();
return json.getString(FlickrString[0]);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
tvTest.setText(result);
}
This works for all the strings. How would I get the farm, isfriend, isfamily, and ispublic converted to a string? I tried something else now to get the Int values, I made a whole new class for reading the ints. But it isnt getting the correct int value. I have it download the int and I convert it to a string and then I change a textview to the string of the int using String.valueOf(x); What am i doing wrong?
public class ReadInt extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... FlickrString) {
try {
json = getValue();
int x = json.getInt(FlickrString[0]);
String y = String.valueOf(x);
return y;
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
tvTest.setText(result);
}
}
Thanks!
JSONObject jobj = result.getJSONObject("photo");
jobj.getBoolean("ispublic");
jobj.getInt("isfriend");
The variable result is of typeJsonObject that should contain the entire object have pasted above in your code
Java is not like C++.In C++ 0 is false and other integers are true
I think you should create a function like this
private void boolean convertIntToBool(int value) {
if(value==0) {
return false;
} else {
return true;
}
}
and use it in the JSON parsing like this for example
boolean isfamily = convertIntToBool(jsonPhotoObject.getInt("isfamily"));
I guess you already know about the JSON parsing so I won't give so much example, but if you have another question about my answer feel free to ask in the comment :)
we assume the jsonString is your json result. You can get the your values like this:
protected String doInBackground(String... FlickrString) {
try {
JSONObject result = new JSONBOject(jsonString);
JSONObject photots = (JSONObject)result.get("photos");
JSONArray photosArray = (JSONArray) result.get("photo");
for(int i = 0; i < photosArray.length(); i++) {
JSONObject item = potosArray.get(i);
//ispublic
int ispublic = item.getInt("ispublic");
//isfriend
int isfriend = item.getInt("isfriend");
//isfamily
int isfamily = item.getInt("isfamily");
}
json = getValue();
return json.getString(FlickrString[0]);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
I would recommend that you try either Jackson or Gson and convert the JSON into some POJOs. I find that it's easier and less error prone to work with java objects instead of JSONObject, JSONArray and such. Here's an example of how it would work using Jackson. First we create the Objects that map to the JSON data:
public class Photos {
#JsonProperty
private int page;
#JsonProperty
private int pages;
...
#JsonProperty("photo")
public List<Photo> photoList;
}
public class Photo {
#JsonProperty
private String id;
#JsonProperty
private String owner;
...
#JsonProperty("ispublic")
public boolean isPublic;
#JsonProperty("isfriend")
public boolean isFriend;
#JsonProperty("isfamily")
public boolean isFamily;
}
Once we've created our pojos we can convert the JSON data into objects using the ObjectMapper. AT least when it comes to Jackson it automatically tries to convert integers to boolean (0 = false, anything else = true) and Strings to booleans ("true" and "false").
ObjectMapper mapper = new ObjectMapper();
Photos photos = mapper.readValue(json, Photos.class);
for(Photo photo : photos.photoList) {
if(photo.isPublic) {
// do something
}
}
PS I've made some of the properties of the pojos public to make the example shorter. You may wish to add getters and keep the properties private.

onPostExecute not being called by ASyncTask execute()

I can't explain why onPostExecute is not being called in my code. I have successfully used almost this exact code with a different app before. It prints 'onPreExecute' and the successful result of the JSON fetch from doInBackground just before return result; but then onPostExecute doesn't print anything - with the super call or not - and moreover doesn't return my string to the UI thread. Any ideas?
public class PrivateLoadFromServer extends AsyncTask<String, Integer, String> {
InputStream is = null;
String result = null;
String error_text="";
JSONObject j = null;
String url;
SQLiteOpenHelper helper;
CustomActivity activity;
private Context context;
private ProgressDialog dialog;
private int count;
String employee;
String text;
public PrivateLoadFromServer(CustomActivity activity,String employee,String url){
this.url=url;
this.employee=employee;
this.activity=activity;
}
#Override
protected void onPreExecute() {
system.out.println("onPreExecute");
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
System.out.println("onPostExecute");
activity.setJSONResult(result);
/*
if(result!=null){
System.out.println("Task reported successful");
taskHandler.taskSuccessful(this.result);
activity.setJSONResult(this.result);
} else {
taskHandler.taskFailed();
}
*/
//return;
}
#Override
protected String doInBackground(String... params) {
System.out.println("Running aSyncTask");
// Successful code to get JSON result string from server omitted.
System.out.println("Raw at doInBackground: " + result);
return result;
EDIT: Should've posted this originally, I call it as an inner class in CustomActivity like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
helper=new DBHelper(this);
loadBasicData();
}
private void loadBasicData() {
// If you can encode all of these into one JSON Object, cool.
String url="*****" //Omitted URL.
String employee=null;
PrivateLoadFromServer syncTask = new PrivateLoadFromServer(this,employee,url);
syncTask.execute();
try {
syncTask.get(15000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("JSONResult at Activity:"+jsonResult); // jsonResult is null
}
}
public void setJSONResult(String result){
System.out.println("setJSONResult"+result);
this.jsonResult=result; // jsonResult is a field in the Activity.
}
Because you are calling get, the JSON result is also returned from this method (see the source code of AsyncTask.java. So you can call your method directly on the output.
try {
setJSONResult(syncTask.get(15000, TimeUnit.MILLISECONDS));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
Check if your are explicitly cancelling AsyncTask somewhere in the code before it could postExecute.
onPostExecute() is called on the main UI thread. If its not getting called, it means your UI thread is blocked doing something else.

How to display jsoup parsed data

I'm trying to parse from an HTML page that only has a body and in the body is a pre tag but thats it. I need to get the info from it and put it in my android app that is using phonegap. I know javascript pretty well. I heard Jsoup will work well but I'm not sure how to output the data pulled using Jsoup as text that I can display.
Thank you for help in advance!
You could try like this.
try {
Document doc = Jsoup.connect(url).get();
Element element = doc.select("input[name=username]").first();
String get_value = element.attr("value");
Log.e(Tag, get_value);
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e(Tag, e.toString());
}
if the html is like:
<........
...........>
<........>
<input name='username' value='fantastic' type='text' .... />
<........
...........>
<........>
the output will be fantastic
Edited
for your case:
new Thread( new Runnable() {
#Override
public void run() {
try {
Document doc = Jsoup.connect(url).get();
Element element = doc.select("body").first();
String get_value = element.text();
Log.e(Tag, get_value);
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e(Tag, e.toString());
}
}
}).start();
N.B: i have not run this code. but u should try this.
how to use it:
public class MainActivity extends FacebookActivity {
private TextView textview;
private String get_value;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textview = (TextView)findViewById(R.id.your_textview_id);
new Thread( new Runnable() {
#Override
public void run() {
try {
// marked for your use
Document doc = Jsoup.connect(url).get();
Element element = doc.select("body").first();
get_value = element.text();
// marked for your use
textview.setText(get_value);
Log.e(Tag, get_value);
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e(Tag, e.toString());
}
}
}).start();
// textview.setText(get_value);
}
}

Categories

Resources