How to display jsoup parsed data - android

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);
}
}

Related

Why AsyncTask make infinity loop

i always found the answer to my Questions in StackoverFlow but not this time, so i'm trying to ask it, and i hope that you can help me, and Thanks even if you coudn't.
I'm trying to use the mysql query
Select * From `Table`
and returning a resultset from asynctask using .get() the problem is that after executing the query and getting the returned value when the asynctask tries to get back in the program he loop infinity,
PS:when i use other query like "Select * From Table Where something = other thing" it works perfectly.
here 2 methodes in my class DataBaseManager which got 2 params: Conn type connexion and member type ResultSet
/* asynctask pour la connexion*/public void Selmem(String ...a){
final class Select_member extends AsyncTask<String, Integer, ResultSet> {
#Override
protected ResultSet doInBackground(String... params) {
try {
ResultSet member2;
String myDriver = "com.mysql.jdbc.Driver";
Class.forName(myDriver).newInstance();
conn = DriverManager.getConnection(params[0], "root", "");
if(params.length==6)
member2=select_member(params[1],params[2],params[3],params[4],params[5]);
else
member2=select_member(params[1],params[2],params[3]);
conn.close();
return(member2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.i("printf","NOT SELECTED");
return null;
}
// TODO Auto-generated method stub
}
}
try {
if(a.length==6)
member=new Select_member().execute(a[0],a[1],a[2],a[3],a[4],a[5]).get();
else
member=new Select_member().execute(a[0],a[1],a[2],a[3]).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public ResultSet select_member(String ...a){
String sql;
PreparedStatement prest;
try {
if(a.length==5)
{
sql="SELECT * FROM `"+a[0]+"` WHERE "+a[1]+" = '"+a[2]+"' and `"+a[3]+"` = '"+a[4]+"'";
prest= conn.prepareStatement(sql);
}
else if (a[2].equals(""))
{
sql="SELECT * FROM `"+a[0]+"`";
prest= conn.prepareStatement(sql);
}
else
{
sql="SELECT * FROM `"+a[0]+"` WHERE `"+a[1]+"` = '"+a[2]+"'";
prest= conn.prepareStatement(sql);
}
prest= conn.prepareStatement(sql);
ResultSet member1;
member1 = prest.executeQuery();
ResultSet member2=member1;
if(member1.next())
return member2;
else
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
this is where i Call my Class to try to Select from my database, ps: the program dosen't even get to my loop (so i don't think that my loop is the problem i used the debugger to see where is the problem)
public class Deniere_Op extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_deniere__op);
Intent activite=getIntent();
DataBaseManager base=new DataBaseManager();
String login=activite.getExtras().getString("login");
base.Selmem("jdbc:mysql://10.0.2.2:3306/db_app",login , "", "");
if(base.member==null)
{
Toast.makeText(getApplicationContext(), "Aucune Transaction",Toast.LENGTH_LONG).show();
}
else
{int i=0;
do{i++;
for(int j=1;j<=6;j++)
{String concat=new String();
concat=concat.valueOf(i)+concat.valueOf(j);
String message;
try {
message = base.member.getString(j);
String a="textview"+concat;
int resID=getResources().getIdentifier(a, "id",getPackageName());
TextView text=(TextView) findViewById(resID);
text.setText(message);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
base.member.next();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}while(base.member!=null);
}
}
I hope that this can make you understand my problem and helps you to help me :D :D.
the logcat hope it will help

doInBackground error when using Jsoup in 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;
}

Android character sizes

I have a client socket which sends some lines (ANSI encoding) which forms a shape. The problem is that in the log cat, when i print out the lines, they form a complete shape, but in my Layout, textviews are not forming the shape even when they have the same length. I can see that the problem lies with the byte size of the space character. But since i can see it on the log cat, there must be a way to set the textviews to form a complete shape. I tried to replace all the space characters with and set the texts as an html form but still no luck. Is there a way that I'm missing?
class ClientThread implements Runnable {
private BufferedReader input;
#Override
public void run() {
// TODO Auto-generated method stub
try {
InetAddress servAddress = InetAddress.getByName(SERVER_IP);
socked = new Socket(servAddress, SERVERPORT);
input = new BufferedReader(new InputStreamReader(socked.getInputStream(), "windows-1252"));
while(!Thread.currentThread().isInterrupted()) {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class updateUIThread implements Runnable {
String msg;
public updateUIThread (String str) {
this.msg = str;
}
#Override
public void run() {
// TODO Auto-generated method stub
TextView tv = new TextView(cont);
tv.setTextColor(Color.WHITE);
// tv.setText(makeTextWithColors(msg));
// tv.setText(msg + "count: " + msg.length());
tv.setText(msg);
screen.addView(tv);
scroller.post(new Runnable() {
public void run() {
scroller.smoothScrollTo(0, screen.getBottom());
}
});
}
}
It seems
tv.setTypeface(Typeface.MONOSPACE);
did the trick. It is a font that makes all characters with the same width.
TextView tb;
tb.setTextSize(20);
tb = Text View it will get floating point value of size you can put there integral type value

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.

Android ListView loading before data has been downloaded - have to restart view

I am using a New Runnable httprequest data loading in one of my classes. I use that class to populate a ListView in one of my Activities, but the thing is that the views are loading before the data has been loaded.. I tried moving my initialize method, which initializes all views, but nothing happened. Every time I load the app, I have to reload the main view because there are no entries in the ListView. LoadReportList() is the method that makes an instance of the class holding the http request method.
public class HomeActivity extends Activity {
private ArrayList<Report> reportList = null;
ListView listview;
private final boolean DEBUG = true;
private MyCustomArrayAdapter adapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
}
#Override
protected void onResume()
{
super.onResume();
loadReportList();
initialize();
}
/**
* This method initializes all the components needed for the activity
*/
private void initialize()
{
/* Get a reference of the listview in our xml view */
listview = (ListView) findViewById(R.id.reportsList);
adapter = new MyCustomArrayAdapter(this, R.layout.single_listview_row);
try{
// Populate the list, through the adapter
for(final List_Item entry : getListEntries()) {
adapter.add(entry);
if(DEBUG)Log.i("HomeActivity","in adding List_Item entries to the adapter");
}
}catch(Exception e){
Log.i("In initialize() HomeActivity","Could not load the list with entries");
loadReportList();
}
listview.setAdapter(adapter);
listview.setOnItemClickListener(new OnItemClickListener(){
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
/* Class to assist us in loading the activity */
Class editClass = null;
try {
editClass = Class.forName(".DetailsActivity");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/* create bundle to pass the ID of the deck that was clicked */
Bundle reportPassed = new Bundle();
//reportPassed.putInt("Report", reportList.get(4).getId());
reportPassed.putSerializable("report", reportList.get(position));
/* Start the new intent and also pass a bundle that will contain the name of the card that was clicked */
Intent ourIntent = new Intent(HomeActivity.this, editClass);
ourIntent.putExtras(reportPassed);//passing the bundle to the activity
//start the activity
startActivity(ourIntent);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.home, menu);
return true;
}
/* Create the list of objects of type List_Item, in our case it will be Decks */
private List<List_Item> getListEntries(){
/* Create an ArrayList of List_Items */
final ArrayList<List_Item> entries = new ArrayList<List_Item>();
if(reportList == null || reportList.isEmpty())
loadReportList();
/* Create the rows for the ListView by adding them into the ArrayList "entries".
* reportList is a global ArrayList<Report> that we populate by a method call to the class JsonParser.
* Look above.
* */
for(int i = 0; i < reportList.size(); i++) {
if(DEBUG)Log.i("getListEntries HomeActivity","Passing through reportlistEntries");
entries.add(
new List_Item(((Report)reportList.get(i)).getType(), Integer.toString(((Report)reportList.get(i)).getId()), ((Report)reportList.get(i)).getId())
);
}
return entries;
}
//This method loads the reportList arraylist with all Report objects
void loadReportList(){
try {
reportList = new JsonParser().getArrayList();
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
Here is my HTTP request:
//The constructor simply calls the getHttpResponse()
public JsonParser() throws UnsupportedEncodingException, IllegalStateException, IOException, JSONException
{
getHttpResponse();
}
/*
* This method returns an HttpResponse
*/
public void getHttpResponse(){
Log.i("getHttpResponse", "Right after declaring HttpResponse response");
new Thread(new Runnable() {
public void run() {
runRequest();
}
}).start();
}
void runRequest()
{
HttpResponse response = null;
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
try {
request.setURI(new URI("http://....../report_data.json"));
response = client.execute(request);
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(response!= null)
Log.i(response.toString(), "testing response.toString()");
//call to populate the list
try {
populateList(response);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException 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();
}
}
Instead of using a java thread you can take advantage of the AsyncTask class of the Android SDK. You can show a progress dialog onPreExecute method, do all the heavy work(in your case the http stuff) in the doInBackground method and populate your list and dismiss the progress dialog in the onPostExecute method. You can create an inner class e.g Task which extends the AsyncTask method and call it from onCreate or onResume ,whatever suits you, like this.
new Task().execute();
AsyncTask has given the name"Painless threading" because it is there to make our life easier. It is consider good practice to reuse already implemented code which is intended for such tasks.
You can find many threads regarding AsyncTasks use in StackOverflow e.g progressDialog in AsyncTask
So what you need to do is call initialize() after your runRequest code completes.
I agree with the above poster that an AsyncTask will make this easy. Get rid of the threading code in your JsonParser class. AsyncTask will take care of that for you.
Here's a snippet.
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
myparser = new JSONParser();
myparser.runRequest()
}
#Override
protected void onPostExecute(Void aVoid) {
initialize();
}
}.execute();

Categories

Resources