Android: retrieve website html - not working - java

I have scoured the internet, and developed code that I thought would work to get the html of a website in readable form. However, I am still unable to make this work. Here is my code:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadTask task = new DownloadTask();
task.execute("http://www.cnn.com");
}
private class DownloadTask extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... urls) {
HttpResponse response = null;
HttpGet httpGet = null;
HttpClient mHttpClient = null;
String s = "";
try {
if(mHttpClient == null){
mHttpClient = new DefaultHttpClient();
}
httpGet = new HttpGet(urls[0]);
response = mHttpClient.execute(httpGet);
s = EntityUtils.toString(response.getEntity(), "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
return s;
}
#Override
protected void onPostExecute(String result){
final TextView textview1 = (TextView) findViewById(R.id.headline);
textview1.setText(result);
}
}
}
When I try this, the app crashes on startup, with the LogCat shown below:
07-26 16:13:42.561: W/dalvikvm(23584): threadid=12: thread exiting with uncaught exception (group=0x416dfda0)
07-26 16:13:42.561: E/AndroidRuntime(23584): FATAL EXCEPTION: AsyncTask #1
07-26 16:13:42.561: E/AndroidRuntime(23584): Process: com.app.firstapp, PID: 23584
07-26 16:13:42.561: E/AndroidRuntime(23584): java.lang.RuntimeException: An error occured while executing doInBackground()
I have no idea why this is happening, does anyone know how I can modify my code to make this work? Thanks in advance.

A library that might be helpful to you is jsoup.
Link: http://jsoup.org
To get a pages HTML in jsoup you just do:
Jsoup.connect("http://google.com").get();
And then from this HTML you can use Jsoup to parse whatever data from the HTML you need.
Link: http://jsoup.org/cookbook/extracting-data/dom-navigation
Edit: I miss read the question. I thought you were having trouble with getting the HTML instead of the fact that there was a problem in the backgrounding.

Make sure that you have included
<uses-permission android:name="android.permission.INTERNET"/>
in your Manifest file.

Related

Should JSON be downloaded in background?

After user press the button it fires up weather function. But it doesn't log any JSON data or any error. Should it be done in background? I've used gson libary to download JSON.
Edit: I edited my code but user must enter a city which is pasted to the link. So is it possible to run in background process when the button is tapped?
public class MainActivity extends AppCompatActivity {
public class Download extends AsyncTask<String,Void,String>{
#Override
protected String doInBackground(String... strings) {
try {
URL url = new URL("api.openweathermap.org/data/2.5/weather?q="+strings[0]+"&APPID=****");
URLConnection request = url.openConnection();
request.connect();
JsonParser jp=new JsonParser();
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent()));
JsonObject rootobj = root.getAsJsonObject();
String weather = rootobj.getAsString();
Log.i("weather:",weather);
}
catch (Exception e){
e.printStackTrace();;
}
return null;
}
}
public void weather(View view){
TextView textView=(TextView) findViewById(R.id.editText);
String city=textView.getText().toString();
Download download=new Download();
download.execute(city);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
All io operation should be executed in background , because all this operations are time consuming . which means you will block your main thread if you donot execute these codes in background and may cause Android Not Respond exception. IO operation in ui thread generally lead to bad user experience . so i strongly advice you do this in background.
You should definitely load your data in the background. The Main Thread i.e. the UI Thread is the thread that renders the UI components so no heavy operation should be done there. If heavy operation is done in the UI Thread, it will freeze the UI.
You should look at the AsyncTask class to perform your loading in the background.
Here is some good tutorials:
https://alvinalexander.com/android/asynctask-examples-parameters-callbacks-executing-canceling
https://www.journaldev.com/9708/android-asynctask-example-tutorial
https://www.tutorialspoint.com/android-asynctask-example-and-explanation

Java code won't execute after calling a classes function

I have created a program that will connect to a database through PHP and echo back a response. My android program then makes a request to the PHP file and reads the echo in.
public class Read_Author extends AsyncTask<String, Void, String> {
String authorName = "";
#Override
public String doInBackground(String... params) {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://localhost/scripts/read_information.php");
HttpResponse response = httpclient.execute(httppost);
authorName = String.valueOf(EntityUtils.toString(response.getEntity()));
String myStr = "ANSWER";
Log.v(myStr, authorName);
}
catch(Exception e){
}
return authorName;
}
public String returnAuthor(){
return authorName;
}
}
I successfully retrieve the echo string and put it in the author name string variable. But when I then try to call return author from my main activity I get no error but the code does not get run.
I call a function called "readValue" within my main activity and within that function, the execute function gets read and then what is supposed to happen is the returnauthor function is supposed to run. But instead, nothing happens
Main Activity Code:
public void returnAuthor(){
loadAuthor.execute();
String a = loadAuthor.returnAuthor();
Log.v("HIT ME", a);
}
If anyone has any suggestion on why this could be happening and how to fix it that will be very much appreciated!
You seem to have misconception about AsyncTask. The result of AsyncTask may not be available instantly, because the background task might not have been completed.
You need to override the method onPostExecute in your AsyncTask to perform some task after the background task has been completed.
First show a progressDialog before executing the AsyncTask
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading..");
progressDialog.setCancelable(false);
progressDialog.show();
Then in the onPostExecute:
#Override
protected void onPostExecute(String result) {
progressDialog.dismiss();
Log.d("author", result);
}

Android AsyncTask sending message to a Handler on a dead thread

I am trying to make a program that should work something like a catalog - I have a JSON array that I loop through and parse the JSON objects into a string containing the image link, and two strings for descriptions for each object. Now, when downloading the images from the internet with the link, I run into a problem at the same image every time, image number 93. I checked the link, and it's working, just the same as the others.
This happens:
W/MessageQueue: Handler (android.os.Handler) {f95f6fe} sending message to a Handler on a dead thread
java.lang.IllegalStateException: Handler (android.os.Handler) {f95f6fe} sending message to a Handler on a dead thread
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:543)
at android.os.Handler.enqueueMessage(Handler.java:643)
at android.os.Handler.sendMessageAtTime(Handler.java:612)
at android.os.Handler.sendMessageDelayed(Handler.java:582)
at android.os.Handler.post(Handler.java:338)
at android.os.ResultReceiver$MyResultReceiver.send(ResultReceiver.java:57)
at com.android.internal.os.IResultReceiver$Stub.onTransact(IResultReceiver.java:58)
at android.os.Binder.execTransact(Binder.java:565)
This is how my AsyncTask looks:
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
This is how I call the AsyncTask:
new DownloadImageTask(imgProductPicture).execute(pictureLink);
layoutTest.addView(NewImgView);
In my code I make sure that no more than 5 of these are called at a time, and they all load without issue until reaching the object indexed 92. The object itself is fine, but the app shuts off at this point always. Does anyone have an idea why? I've tried downloading less images at a time (one by one) and it still fails at the same point. I'd appreciate any help.
AsyncTask uses handler of the main thread, to callback onPostExecute(). If the main thread is dead when to callback, system throws the exception. To avoid this, you have to keep the main thread alive until all the work completes.
I solved the problem by creating a new handler/runnable every time I called the DownloadImageTask. Thanks to all who have tried to help.

Android httpClient

I am hitesh my problem is ,i work on httpclient in andriod i gave internet permission to my application and i run my application and click on button the tehy gave unfortunately stopped. please help me there my code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText user=(EditText) findViewById(R.id.username);
final EditText pass=(EditText) findViewById(R.id.password);
Button login=(Button) findViewhere`ById(R.id.login);
login.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
String u=user.getText().toString();
String p=pass.getText().toString();
HttpClient httpClient=new DefaultHttpClient();
HttpPost httppost=new HttpPost("http://202.164.53.122");
BasicNameValuePair usernameBaseNameValuePair=new BasicNameValuePair("id",u);
BasicNameValuePair passBaseNameValuePair=new BasicNameValuePair("pass",p);
List<NameValuePair> nameValuePairList=new ArrayList<NameValuePair>();
nameValuePairList.add(usernameBaseNameValuePair);
nameValuePairList.add(passBaseNameValuePair);
try {
UrlEncodedFormEntity urlEncodedFormEntity=new
UrlEncodedFormEntity(nameValuePairList,HTTP.UTF_8);
httppost.setEntity(urlEncodedFormEntity);
try {
HttpResponse httpResponse=httpClient.execute(httppost);
} catch (ClientProtocolException e) {
} catch (IOException e) {
user.setText(e.getMessage());
}
}catch(UnsupportedEncodingException uee){
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
dont work with network on main thread(or get android.os.NetworkOnMainThreadException). use thread class or AsyncTask class.
AsyncTask
Thread
If you are using this code in android 4.0+ you get exception android.os.NetworkOnMainThreadException. Use AsyncTask to provide any http communication.
Firstly, create a separate class for getting the Request and use Asynctask to perform all your actions. Use a String to pass the URI and then pass the URI in the Asynctask. This method won't block your Main UI Thread.
Refer to this link for how to use Asynctask.
http://developer.android.com/reference/android/os/AsyncTask.html
For network operation you should use different thread rather than using main thread because using network on main thread will cause to application UI unresponsive to avoid this you should AyncTask
For Example of AsyncTask use this Link
First of all, you should use a different thread for sending a request. Or, the best way is to use volley requests with post method. It is faster and more efficient.

Why does this give a NetworkOnMainThreadException?

I'm trying to get the details of a product from a MySQL database but when I compile the code I get a NetworkOnMainThreadException error even if I use the class GetProductDetails as AsyncTask when I call it to execute . I don't really understand why this happens since I was following a tutorial to do it and I don't see any error.
This is the code that i'm using:
public class ListClubs extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_clubs);
new GetProductDetails().execute();
(...some code...)
}
class GetProductDetails extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(ListClubs.this);
pDialog.setMessage("Loading product details. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
/**
* Getting product details in background thread
* */
protected String doInBackground(String... params) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
// Check for success tag
int success;
try {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("pid", Integer.toString(1)));
// getting product details by making HTTP request
// Note that product details url will use GET request
JSONObject json = jsonParser.makeHttpRequest(url_product_detials, "GET", params);
// check your log for json response
Log.d("Single Product Details", json.toString());
// json success tag
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// successfully received product details
JSONArray productObj = json.getJSONArray(TAG_PRODUCT); // JSON Array
// get first product object from JSON Array
JSONObject product = productObj.getJSONObject(0);
}else{
// product with pid not found
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog once got all details
pDialog.dismiss();
}
}
And this is the log:
FATAL EXCEPTION: main
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
at java.net.InetAddress.getAllByName(InetAddress.java:214)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
at com.goout.JSONParser.makeHttpRequest(JSONParser.java:62)
at com.goout.ListClubs$GetProductDetails$1.run(ListClubs.java:464)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5227)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
at dalvik.system.NativeStart.main(Native Method)
Thanks!
Take this stuff out of doInbackground() and see what happens
runOnUiThread(new Runnable() {
public void run() {
The point of an AsyncTask is to run network stuff or any heavy lifting in doInBackground() then use the other methods to update the UI if needed. So you don't want to do the opposite of its purpose to tell its background code(doInbackground()) to run on the UI Thread with runOnUiThread().
Also, really good information on AsyncTask Here
You are marshalling all your code at once from the AsyncTask into the main UI again, that's why right now it's as if the AsyncTask didn't exist, everything is ran from the UI Thread.
Extract your network code to run in the doInBackground method and return a meaningful (To your application) type from it, then override the onPostExecute method with the code that updates the UI with the result of doInBackground. onPostExceute is ALWAYS run from the Ui thread, you don't need to manage the threading yourself if you use it correctly.
More info: http://developer.android.com/reference/android/os/AsyncTask.html
Adding runOnUiThread in your doInBackground method is causing your background thread to queue a runnable to your main thread, so everything inside of that runnable (which includes your networking tasks) is being run on the main thread. In Android (Honeycomb+) this causes your exception to be thrown.
If you find that you have trouble with AsyncTasks, and in-particluar network requests, consider looking into a library to help simplify things - such as droidQuery and Android Volley.

Categories