Put webpage text into a textview (Android) - java

I want to put a text from a webpage to a textview on Android 3.0. I have this code:
public class Biografie extends Activity {
private TextView outtext;
private String HTML;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_biografie);
outtext= (TextView) findViewById(R.id.textview1);
try {
getHTML();
} catch (Exception e) {
e.printStackTrace();
}
outtext.setText("" + HTML);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.biografie, menu);
return true;
}
private void getHTML() throws ClientProtocolException, IOException
{
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("http://artistone.appone.nl/api/biografie.php?dataid=998"); //URL!
HttpResponse response = httpClient.execute(httpGet, localContext);
String result = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = null;
while ((line = reader.readLine()) != null) {
result += line + "\n";
HTML = result;
}
}
}
My TextView returns "null" instead of the text from the page. Please help me to fix this. Thanks in regard.

Change your code to:
while ((line = reader.readLine()) != null) {
result += line + "\n";
}
HTML = result;
and try this:
outtext.setText(Html.fromHtml(HTML));
And instead of performing network action in main thread i will suggest you to do this in separate thread using AsyncTask

The problem is that you are getting NetworkOnMainThreadException
That is because you are downloading network content on the Main Thread (Activity's Thread).
Instead you need to use a background thread to download that content, or use AsynchTask.
A simple code that should fix this issue:
final Handler handler = new Handler();
Thread thread = new Thread() {
public void run() {
try {
getHTML();
handler.post(new Runnable() {
#Override
public void run() {
outtext.setText("" + HTML);
}
});
} catch (Exception e) {
e.printStackTrace();
handler.post(new Runnable() {
#Override
public void run() {
outtext.setText(e.toString());
}
}
}
};
thread.start(); // I forgot to start the thread. sorry !
Instead of :
try {
getHTML();
} catch (Exception e) {
e.printStackTrace();
}
outtext.setText("" + HTML);
Also take a look at this tutorial about android threads : Tutorial

Related

How can I delay a funtion call? [duplicate]

This question already has answers here:
How to call a method after a delay in Android
(35 answers)
Closed 4 years ago.
public class NotificationReceivedCheckDelivery extends NotificationExtenderService {
#Override
protected boolean onNotificationProcessing(OSNotificationReceivedResult receivedResult) {
OverrideSettings overrideSettings = new OverrideSettings();
overrideSettings.extender = new NotificationCompat.Extender() {
#Override
public NotificationCompat.Builder extend(NotificationCompat.Builder builder) {
// Sets the background notification color to Yellow on Android 5.0+ devices.
return builder.setColor(new BigInteger("FFFFEC4F", 16).intValue());
}
};
OSNotificationDisplayedResult displayedResult = displayNotification(overrideSettings);
Log.d("ONES",receivedResult.payload.title);
JSONObject AdditionalData = receivedResult.payload.additionalData;
Log.d("Adata",AdditionalData.toString());
String uuid= null;
try{
// {"uuid":"adddd"}
uuid = AdditionalData.getString("uuid");
}
catch (JSONException e){
Log.e("Error JSON","UUID",e);
}
// Create Object and call AsyncTask execute Method
new FetchNotificationData().execute(uuid);
return true;
}
private class FetchNotificationData extends AsyncTask<String,Void, String> {
#Override
protected String doInBackground(String... uuids) {
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String forecastJsonStr = null;
try {
URL url = new URL("http://test.com/AppDeliveryReport?uuid="+uuids[0]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
forecastJsonStr = buffer.toString();
return forecastJsonStr;
} catch (IOException e) {
Log.e("PlaceholderFragment", "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PlaceholderFragment", "Error closing stream", e);
}
}
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.i("json", s);
}
}
}
I want to delay calling the FetchNotificationData function with a random seconds.
This is a delivery report url request function. Whenever a notification from onesignal received at the app it will call the url. I don't want to blast the server with huge request at once. So I want to delay call with random seconds so that server will have to serve few calls on a given time.
You can use handler to delay call to function
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Toast.makeText(Splash.this, "I will be called after 2 sec",
Toast.LENGTH_SHORT).show();
//Call your Function here..
}
}, 2000); // 2000 = 2 sec
you can use Handler like this
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// your FetchNotificationData function
}
},timeInMiliSec);
just remember to import Handler as android.os, not java.util.logging
timer = new Timer();
final int FPS = 3;
TimerTask updateBall = new UpdateBallTask();
timer.scheduleAtFixedRate(updateBall, 0, 1000 * FPS);
class:
class UpdateBallTask extends TimerTask {
public void run() {
// do work
}
}
///OR
final Handler handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
handler.postDelayed(this, 100);
// do work
handler.removeCallbacksAndMessages(null);
}
};
handler.postDelayed(r, 100);

Android handler only sends one message

I am trying to implement a REST interface in android and I need a Thread in the background sending "I am alive" messages to an ip address. To do so I created a Thread Called RestPostThread that runs in the background while I do stuff in my UI thread.
The problem is that after sending the first message to the RestPostThread I can't quit the looper or send a different message to it with another IP or something.
Here are the code for both the UI and the RestPostThread:
public class MainActivity extends AppCompatActivity{
Handler workerThreadHandler;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
final TextView text1 = (TextView) findViewById(R.id.text1);
final TextView text2 = (TextView) findViewById(R.id.text2);
setSupportActionBar(toolbar);
final RestPostThread RPT = new RestPostThread();
RPT.start();
while(workerThreadHandler == null ) {
workerThreadHandler = RPT.getThreadHandler();
}
Button buttonStop = (Button) findViewById(R.id.buttonStop);
buttonStop.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
try {
workerThreadHandler.getLooper().quit();
}catch(Exception e){
text1.setText(e.getMessage());
text2.setText( "Exception!");
}
}
});
Button buttonSend = (Button) findViewById(R.id.buttonSend);
buttonSend.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
try {
text1.setText(new RestGet().execute(editText.getText().toString()).get());
text2.setText("everything went well!");
}catch(Exception e){
text1.setText(e.getMessage());
text2.setText( "Exception!");
}
}
});
}
And here is the code for the RestPostThread:
public class RestPostThread extends Thread {
public Handler mHandler;
#Override
public void run(){
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
Log.d("MYASDASDPOASODAPO", "dentro mensaje");
while (!msg.obj.equals(null)) {
try {
Thread.sleep(1000);
URL url = new URL(msg.obj.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
String input = "<Instruction><type>put_me_in</type><room>Room 1</room></Instruction>";
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
// throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
String aux = new String();
while ((output = br.readLine()) != null) {
aux = aux + output;
}
conn.disconnect();
//return aux;
} catch(MalformedURLException e) {
e.printStackTrace();
//return null;
} catch(IOException e) {
e.printStackTrace();
//return null;
} catch(Exception e) {
}
}
Log.d("CLOSING MESSAGE", "Closing thread");
}
};
Looper.loop();
}
public Handler getThreadHandler() {
return this.mHandler;
}
Have a look at HandlerThread for dealing with a thread to handle just messages. Your Handler should not loop on a message like that, it won't work. It's the Looper's job to deal with new, incoming Message or Runnable objects sent to the Handler which is bound to the Looper.
Regardless, you should take a closer look at using a Loader to handle REST type APIs; or, explore a 3rd party library, such as retrofit, for dealing with REST.
I managed to solve the issue. The problem was that I was wrapping everything inside this:
while (!msg.obj.equals(null)) {}
I implemented handlers in both this thread and the UI thread and now I have communication back and forth between the both, my RestPostThread looks like this now:
public class RestPostThread extends Thread {
public Handler mHandler,uiHandler;
public RestPostThread(Handler handler) {
uiHandler = handler;
}
#Override
public void run(){
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
try {
//Thread.sleep(1000);
URL url = new URL(msg.obj.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
String input = "<Instruction><type>put_me_in</type><room>Room 1</room></Instruction>";
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
// throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
String aux = new String();
while ((output = br.readLine()) != null) {
aux = aux + output;
}
conn.disconnect();
Message msg2 = uiHandler.obtainMessage();
msg2.obj = aux;
uiHandler.sendMessage(msg2);
}catch(MalformedURLException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}catch(Exception e){
}
}
};
Looper.loop();
}
public Handler getThreadHandler() {
return this.mHandler;
}
}
And in my MainActivity I have this handler that allows me to "loop" (basically is just going back and forth between the RestPostThread and the UIThread) my Post message until I decide to stop from the MainActivity changing the boolean loop:
public Handler uiHandler = new Handler() {
public void handleMessage(Message inputMessage) {
Log.d("FROM UI THREAD",inputMessage.obj.toString());
if(loop) {
Message msg = workerThreadHandler.obtainMessage();
String url = "http://192.168.1.224:9000/xml/android_reply";
msg.obj = url;
workerThreadHandler.sendMessageDelayed(msg,1000);
}
}
};

Java: Can't convert string to array

I can't convert a string to an array!
String text = "";
String[] textsplit = {};
//Stuff
The app set the content of an online txt file in a string:
The online txt file contain: hello,my,name,is,simone
[...] //Downloading code
text = bo.toString(); //Set the content of the online file to the string
Now the string text is like this:
text = "hello,my,name,is,simone"
Now i have to convert the string to an array that must be like this:
textsplit = {"hello","my","name","is","simone"}
so the code that i use is:
textsplit = text.split(",");
But when i try to use the array the app crash! :(
For example:
textview.setText(textsplit[0]); //The text of the textview is empity
textview.setText(textsplit[1]); //The app crash
textview.setText(textsplit[2]); //The app crash
etc...
where am I wrong? thanks!
EDIT: This is the code:
new Thread() {
#Override
public void run() {
String path ="http://www.luconisimone.altervista.org/ciao.txt";
URL u = null;
try {
u = new URL(path);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.connect();
InputStream in = c.getInputStream();
final ByteArrayOutputStream bo = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
in.read(buffer); // Read from Buffer.
bo.write(buffer); // Write Into Buffer.
runOnUiThread(new Runnable() {
#Override
public void run() {
text = bo.toString();
testo.setText("(" + text + ")");
try {
bo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
// Here all variables became empity
textsplit = text.split(",");
datisplittati.setText(textsplit[0]);
Try :
String text = "hello,my,name,is,simone";
String[] textArr = text.split(Pattern.quote(","));
You can get string using AsyncTask
private class GetStringFromUrl extends AsyncTask<String, Void, String> {
ProgressDialog dialog ;
#Override
protected void onPreExecute() {
super.onPreExecute();
// show progress dialog when downloading
dialog = ProgressDialog.show(MainActivity.this, null, "Downloading...");
}
#Override
protected String doInBackground(String... params) {
// #BadSkillz codes with same changes
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(params[0]);
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(entity);
InputStream is = buf.getContent();
BufferedReader r = new BufferedReader(new InputStreamReader(is));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line + "\n");
}
String result = total.toString();
Log.i("Get URL", "Downloaded string: " + result);
return result;
} catch (Exception e) {
Log.e("Get Url", "Error in downloading: " + e.toString());
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// TODO change text view id for yourself
TextView textView = (TextView) findViewById(R.id.textView1);
// show result in textView
if (result == null) {
textView.setText("Error in downloading. Please try again.");
} else {
textView.setText(result);
}
// close progresses dialog
dialog.dismiss();
}
}
and use blow line every time that you want:
new GetStringFromUrl().execute("http://www.luconisimone.altervista.org/ciao.txt");
You're using new thread to get data from an url. So in runtime, data will be asynchronous.
So when you access text variable (split it), it's still not get full value (example reason: network delay).
Try to move the function split after text = bo.toString(); , I think it will work well.

How to get out an httpGet response from a Thread Android

I have this Thread on a Fragment
Thread trd = new Thread(new Runnable(){
#Override
public void run(){
HttpClient hc = new DefaultHttpClient();
HttpGet post = new HttpGet("http://www.no798.eu/notizie.php");
HttpResponse rp = null;
try {
rp = hc.execute(post);
} catch (IOException e) {
e.printStackTrace();
}
if (rp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
// Server is unavailable
}
try {
String str=EntityUtils.toString(rp.getEntity());
} catch (IOException e) {
e.printStackTrace();
}
}
});
trd.start();
How i can get out of Thread the EntityUtils String?
If a try java whant a Final one-element array String...
Create a Handler in your Activity or Fragment, and pass the result of the HTTP call to it.
In your Activity/Fragment:
private final static int HANDLER_FROM_HTTP = 1;
private final Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
final int what = msg.what;
switch(what) {
case HANDLER_FROM_HTTP: {
Bundle b = msg.getDate();
if (b != null) {
String s = b.getString("result");
doSomething(s);
}
}
}
}
};
Then, in the run() method of your Thread above:
String str=EntityUtils.toString(rp.getEntity());
Message msg = pThreadHandler.obtainMessage(HANDLER_FROM_HTTP);
Bundle b = new Bundle();
b.putString("result", str);
msg.setData(b);
msg.sendToTarget();
This will allow you to execute doSomething() on the main UI thread to update a View, or perform some other action.

Start AsyncTask inside of a Thread [duplicate]

This question already has answers here:
Start Async Task within a worker thread
(5 answers)
Closed 8 years ago.
I want to start a simple process of getting the HTML code of a webpage from inside an AsyncTask, because when it's from the new Thread the UI freezes for few moments, how can I do it?
public void loadHTML(View vL) {
final String ss = (et.getText().toString());
new Thread(new Runnable() {
#Override
public void run() {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(new HttpGet(ss));
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
final String responseString = out.toString();
tvW.post(new Runnable() {
#Override
public void run() {
tvW.setText(responseString);
}
});
Log.v("DYRA BYRA", responseString);
} else {
response.getEntity().getContent().close();
}
} catch (Exception e) {
}
}
}).start();
}
I want this part tvW.post(new Runnable() {
#Override
public void run() {
tvW.setText(responseString);
}
});
to be in AsyncTask
Uh i don't think you need an asynctask but a run on ui thread
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
tvW.setText(responseString);
}
});
You have to sync your Thread with the UI-Thread. Because all UI relevant operations like writing to an TextView have to be done on the UI-Thread. Therefor you should use the Handler class.
Handler myHandler = new Handler();
Now replace this code:
tvW.post(new Runnable() {
#Override
public void run() {
tvW.setText(responseString);
}
});
With this one:
myHandler.post(new Runnable() {
#Override
public void run() {
tvW.setText(responseString);
}
});
Note that your Handler class have to be declared on the UI-Thread to get connected.
That's what I wanted to do
public void loadHTML(View vL) {
new getCode().execute();
}
private class getCode extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
final String ss = (et.getText().toString());
try {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(new HttpGet(ss));
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
Log.v("DYRA BYRA", responseString);
} else {
response.getEntity().getContent().close();
}
} catch (Exception e) {
}
return null;
}
protected void onPostExecute(String result) {
tvW.setText(responseString);
}
}
the UI still freezes for like half second, but perhaps that's because the received HTML is extremely long

Categories