I'm making an android application that downloads some text from a web page and puts it in a String, then it prints the string in a TextView. But the content of the web page can change every seconds, so i want TextView to update in real-time, showing the new String every seconds. To download text from the webpage and set TextView's text I used AsyncTask, and i called the execute() in onCreate() method, in main Activity. I don't know how update it, without make application crashed.
Sorry for bad English, that's my MainActivity:
package com.example.pack;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity
{
TextView textView;
URL url;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
url = null;
try
{
url = new URL("myURL");
}
catch (MalformedURLException e) {}
new VariabileLikeTask(textView).execute(url);
}
}
And that's my aSyncTask:
package com.example.pack;
import android.os.AsyncTask;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
public class VariabileLikeTask extends AsyncTask<URL, Void, CharSequence>
{
TextView textView;
public VariabileLikeTask(TextView textView)
{
this.textView = textView;
}
#Override
protected String doInBackground(URL... urls)
{
URL url = urls[0];
InputStream in = null;
int risposta = -1;
String text = "";
try
{
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("No connection");
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
risposta = httpConn.getResponseCode();
if (risposta == HttpURLConnection.HTTP_OK)
in = httpConn.getInputStream();
BufferedReader bf = new BufferedReader(new InputStreamReader(in));
text = bf.readLine();
in.close();
bf.close();
}
catch (Exception ex) {}
return text;
}
#Override
protected void onPostExecute(CharSequence text)
{
textView.setText(text);
}
}
Sorry if the format code is wrong, this is my first thread.
Isn't it a bad idea to run the AsyncTask frequently? This will make the app heavier in network operations.
If you mean the word real-time push notification or socket connection would be the best match. If you can't use a push notification because you are trying to fetch data from a Web page consider using a service class. Then simply make a timer task and run the AsyncTask after a small interval of time.
Here a simple demo of running the task after an interval of time,
private int m_interval = 5000; // 5 seconds by default, can be changed later
private Handle m_handler;
#Override
protected void onCreate(Bundle bundle)
{
...
m_handler = new Handler();
}
Runnable m_statusChecker = new Runnable()
{
#Override
public void run() {
//this function can change value of m_interval.
new VariabileLikeTask(textView).execute(url);
m_handler.postDelayed(m_statusChecker, m_interval);
}
}
void startRepeatingTask()
{
m_statusChecker.run();
}
void stopRepeatingTask()
{
m_handler.removeCallback(m_statusChecker);
}
In this post the user try to show dialog from AsyncTask, but the code it's the same to change txtBox in runtime, watch it!
Tell me if I helped you and good programming!
Related
I have an application with 3 or more AsycTask that are called sequentially. Because these asyntasks are all similar, I created a separated class and it works properly.
Now I would like to add a progress bar in order to show something when these asynctasks ask and process the result...but not work.
My application work as follow:
I open my camera and with ZXing library I decode a qrCode
using HttpRequest I ask to my server some informations and my application processes these informations
The point is that during the processing my application shows a black screen with the tipical viewfinder of ZXing library (I think that you understand what I mean). How can replace this view with another block with a progress bar?
I already tried to modified the progress bar visibility, on the event onPreExecute and onPostExecute, also I tried to use the event onProgressUpdate, but nothig is change. The viewfinder remains on the screen until the asyncTask is not finish.
Follow my code for execute the AsyncTask:
response = asynkTaskDeleteMissionQueue.execute().get();
and my AsyncTask class
package com.klainrobotics.lucalombardi.krmir;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.util.List;
import java.util.Vector;
/**
* Created by Luca Lombardi on 27/11/2017.
*/
public class MiRCall extends AsyncTask <String, Void, List<Object> >{
public AsyncResponse delegate = null;
private String url;
private String method;
private ProgressBar progress;
public MiRCall(Context v, ProgressBar prg, String...params){
method = params[0];
url = params[1];
progress = prg;
}
#Override
protected void onPreExecute(){
}
#Override
protected void onProgressUpdate(Void... v) {
super.onProgressUpdate(v);
}
#Override
protected List<Object> doInBackground(String... arg0) {
int result = -1;
publishProgress();
List<Object> response = new Vector<Object>();
String jsonResponse = "";
BufferedReader br;
try {
URL urlMissionQueue = new URL(url);
HttpURLConnection connection = (HttpURLConnection) urlMissionQueue.openConnection();
if (connection != null) {
connection.setRequestMethod(method);
connection.setRequestProperty(Costanti.headers, Costanti.StringaHeader());
connection.setRequestProperty(Costanti.contentType, Costanti.contentTypeJSon);
customBody(connection);
connection.connect();
result = connection.getResponseCode();
response.add(result);
if (200 <= result && result <= 299) {
br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} else {
br = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
}
for (String line; (line = br.readLine()) != null; jsonResponse += line);
response.add(jsonResponse);
}else {
Log.e("Url", "Connection is null");
}
} catch (Exception ex) {
Log.e("MiRCall", "doInBackgound: " + ex.toString());
}
return response;
}
#Override
protected void onPostExecute(List<Object> result) {
if (delegate != null) {
delegate.processFinish(result);
} else {
Log.e("MiRCall", "You have not assigned AsyncTask delegate");
}
}
public void customBody(HttpURLConnection connection) throws ProtocolException {
// Do nothing
}
}
Thanks in advance
response = asynkTaskDeleteMissionQueue.execute().get();
Pretty bad to use the .get() function on it. Do away with get(). Only start the task.
asynkTaskDeleteMissionQueue.execute();
Then in onPostExecute() handle the response.
Thanks for your suggestion. I execute
response = asynkTaskDeleteMissionQueue.execute().get();
because my asyncTask returns a list of object, so I don't know another way....
And about the original question? Any suggestions?
Thanks in any case for your time
I'am following this tutorial for calling a web service in android & it works great, http://androidexample.com/Restful_Webservice_Call_And_Get_And_Parse_JSON_Data-_Android_Example/index.php?view=article_discription&aid=101
yet when i try to call another webservice using this code, just replacing the serverURL, the app gets blocked in th pre-execute(), can anyone tell me what else should I change ? I thought there was a common code for all web services ?
mainActivity.java
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button GetData = (Button) findViewById(R.id.GetServerData);
GetData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// WebServer Request URL
String serverURL = "http://androidexample.com/media/webservice/JsonReturn.php";
// String serverURL = "http://hmkcode.appspot.com/rest/controller/get.json";
// String serverURL="http://gdata.youtube.com/feeds/api/videos?q=Android&v=2&max-results=20&alt=jsonc&hl=en";
// Use AsyncTask execute Method To Prevent ANR Problem
new LongOperation().execute(serverURL);
}
}
);
}
class LongOperation extends AsyncTask<String, Void, Void> {
private final HttpClient Client = new DefaultHttpClient();
private String Content;
private String Error = null;
private ProgressDialog Dialog = new ProgressDialog(MainActivity.this);
String data = "";
TextView uiUpdate = (TextView) findViewById(R.id.output);
TextView jsonParsed = (TextView) findViewById(R.id.jsonParsed);
protected void onPreExecute() {
// NOTE: You can call UI Element here.
//Start Progress Dialog (Message)
Dialog.setMessage("Please wait..");
Dialog.show();
}
// Call after onPreExecute method
protected Void doInBackground(String... urls) {
/************ Make Post Call To Web Server *********/
BufferedReader reader=null;
// Send data
try
{
// Defined URL where to send data
URL url = new URL(urls[0]);
// Send POST data request
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write( data );
wr.flush();
// Get the server response
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
// Read Server Response
while((line = reader.readLine()) != null)
{
// Append server response in string
sb.append(line + " ");
}
// Append Server Response To Content String
Content = sb.toString();
}
catch(Exception ex)
{
Error = ex.getMessage();
}
finally
{
try
{
reader.close();
}
catch(Exception ex) {}
}
/*****************************************************/
return null;
}
protected void onPostExecute(Void unused) {
// NOTE: You can call UI Element here.
// Close progress dialog
Dialog.dismiss();
if (Error != null) {
uiUpdate.setText("Output : " + Error);
} else {
// Show Response Json On Screen (activity)
uiUpdate.setText(Content);
//String OutputData = MainActivity.parse(Content);
//Show Parsed Output on screen (activity)
//jsonParsed.setText(OutputData);
}
}
}
}
I changed send PostRequest with this code: //SEND Get data reques HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET");& it works
I'm trying to connect to a servlet in localhost from my Android Emulator.
I created a project in Eclipse named SimpleHttpGetRequest with an activity named "HttpGetServletActivity".
I created in NetBeans a project named "HttpGetRequest" containing a servlet.
The code in my "HttpGetServletActivity" activity is :
package com.mobdev.simplehttprequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class HttpGetServletActivity extends Activity implements OnClickListener {
Button button;
TextView outputText;
public static final String URL = "http://10.0.2.2:8080/HttpGetRequest/HelloWorldServlet";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewsById();
button.setOnClickListener(this);
}
private void findViewsById() {
button = (Button) findViewById(R.id.button);
outputText = (TextView) findViewById(R.id.outputTxt);
}
public void onClick(View view) {
GetXMLTask task = new GetXMLTask();
task.execute(new String[]{ URL });
}
private class GetXMLTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String output = null;
for (String url : urls) {
output = getOutputFromUrl(url);
}
return output;
}
private String getOutputFromUrl(String url) {
StringBuffer output = new StringBuffer("");
try {
InputStream stream = getHttpConnection(url);
BufferedReader buffer = new BufferedReader(
new InputStreamReader(stream));
String s = "";
while ((s = buffer.readLine()) != null)
output.append(s);
} catch (IOException e1) {
e1.printStackTrace();
}
return output.toString();
}
// Makes HttpURLConnection and returns InputStream
private InputStream getHttpConnection(String urlString)
throws IOException {
InputStream stream = null;
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
try {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("get");
httpConnection.connect();
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
stream = httpConnection.getInputStream();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return stream;
}
#Override
protected void onPostExecute(String output) {
outputText.setText(output);
}
}
}
The source code of my servlet is :
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloWorldServlet extends HttpServlet {
public HelloWorldServlet() {
super();
}
#Override
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("Hello Android !!!!");
}
}
I deployed my servlet in Apache server (i'm using xampp);
I added permission for network connection
When I run my App and click on the button, the App crashes, and I don't know why !!
Can anybody help me, please ? Im' stuck.
I tried :
Wifi connection : I did run my App on a real device, instead of "10.0.2.2" I put the ip adress of my PC but it doesn't work ;
Access to project HttpGetrequest from Android Emulator browser, it worked ;
hi i am new learner of android and java.below this is my code. I having trouble to know where is the problem.
when i debug few times, it automatically enter debug mode after that. to fix that i have to restart the phone again. I check with other apps, it work just fine. just for the apps that i currently working on.
problem :
1. if i didn't enter data into the "dateTo" the program will stopped.
2. enter debug mode itself.
3. when i get the data from the array atList, then i key in another 'dateTo" to retrieve another data, but it doesn't replace the current data value. tq
package com.example.m2mai;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class RetrieveActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_retrieve);
}
public ArrayList<String> atList=new ArrayList<String>();
public ArrayList<String> dataList=new ArrayList<String>();
public void getStream(View v)
{
new MyAsyncTask().execute();
}
private class MyAsyncTask extends AsyncTask<String, Void, String>
{
protected String doInBackground(String... params)
{
return getData();
}
public long getDateTo()
{
EditText toText = (EditText)findViewById(R.id.dateTo);
String To = toText.getText().toString();
DateFormat dateFormatTo = new SimpleDateFormat("dd/MM/yyyy");
Date dateTo = null;
try {
dateTo = dateFormatTo.parse(To);
} catch (java.text.ParseException e) {
e.printStackTrace();
}
long timeTo = dateTo.getTime();
new Timestamp(timeTo);
return timeTo/1000;
}
protected String getData()
{
String toTS = ""+getDateTo();
String decodedString="";
String returnMsg="";
String request = "http://api.carriots.com/devices/{API_KEY}/streams/?order=-1&max=2&at_to="+toTS;
URL url;
HttpURLConnection connection = null;
try {
url = new URL(request);
connection = (HttpURLConnection) url.openConnection();
//establish the parameters for the http post request
connection.addRequestProperty("carriots.apikey", "somekey");
connection.addRequestProperty("Content-Type", "application/json");
connection.setRequestMethod("GET");
//create a buffered reader to interpret the incoming message from the carriots system
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((decodedString = in.readLine()) != null)
{
returnMsg+=decodedString;
}
in.close();
connection.disconnect();
JSONObject nodeRoot = new JSONObject(returnMsg);
JSONArray res = nodeRoot.getJSONArray("result");
for (int i = 0; i < res.length(); i++)
{
JSONObject childJSON = res.getJSONObject(i);
if (childJSON.get("data")!=null)
{
String value = childJSON.getString("data");
dataList.add(value);
JSONObject node=new JSONObject(value);
atList.add(node.get("temperature").toString());
}
}
}
catch (Exception e)
{
e.printStackTrace();
returnMsg=""+e;
}
//Log.d("returnMsg",returnMsg.toString());
return returnMsg;
}
protected void onPostExecute(String result)
{
//show the message returned from Carriots to the user
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
EditText myData1=(EditText)findViewById(R.id.editText1);
myData1.setText(atList.get(0));
EditText myData=(EditText)findViewById(R.id.editText2);
myData.setText(atList.get(1));
}
}
}
This line long timeTo = dateTo.getTime(); will throw a NullPointerException when the dateFormatTo.parse method throws a ParseException. This is going to happen when you come into the method with the To string not matching the specified format.
You're not exiting out of the flow so the long...getTime(); line runs, but dateTo is null resulting in a crash.
In the onPostExecute; you aren't verifying that atList has multiple elements. A JSON parse failure will leave atList empty and cause an index bounds exception for those 2 get calls.
These may not be the solutions to what you're seeing; but they will crash the app when these are hit in very likely situations; including the one you describe of an empty string for To.
As the comments mention; the logs will help see what's actually happening; but this is too big for a comment and those points are going to cause problems.
I'm new to android and I hope someone could help me here. I have an activity Faculty and a button.
This is my XML layout browse_faculty:
<Button
android:onClick="searchFSTEHandler"
android:id="#+id/bFSTE"
android:layout_width="220dp"
android:layout_height="80dp"
android:layout_alignLeft="#+id/bFBE"
android:layout_below="#+id/bFBE"
android:layout_marginTop="20dp"
android:text="#string/fste" />
and this is my Faculty Activity which displays the buttons:
I use Intent to view ListView
public class Faculty extends Activity{
#Override
protected void onCreate(Bundle BrowseFaculty) {
// TODO Auto-generated method stub
super.onCreate(BrowseFaculty);
setContentView(R.layout.browse_faculty);
}
//on the XML,this is the "searchFSTEHandler" i want to use to show ListView
public void searchFSTEHandler(View target){
Intent courseList = new Intent(this, HttpActivity.class);
startActivity(courseList);
}
}
and below is the "HttpActivity" class is the class that displays my ListView. This class read a php file which gets data from a MySQL server and converts to JSON data then parses it into a array list.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.ListActivity;
import android.widget.ArrayAdapter;
public class HttpActivity extends ListActivity {
public String f1 = "FSTE";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.faculty_course);
new getHttp().execute();
getHttp test =new getHttp();
String strJsonData = test.doInBackground(f1);
// Convert String JSON data to Java class
ArrayList<Courses> arrayCourse= test.parseJsonData(strJsonData);
//Create an ArrayAdapter which shows the ArrayList data
this.setListAdapter(new ArrayAdapter<Courses>(this,android.R.layout.simple_list_item_1,arrayCourse));
}
private class getHttp extends AsyncTask<String, Void, String> {
public getHttp() {
}
#Override
protected String doInBackground(String... faculty) {
InputStream is = null;
try {
URL url = new URL("http://10.0.2.2/sqlWebService.php?faculty=FSTE");
URLConnection con = url.openConnection();
con.setConnectTimeout(10000);
con.setReadTimeout(10000);
is = con.getInputStream();
BufferedReader br = new BufferedReader(
new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
String str;
while ((str = br.readLine()) != null) {
sb.append(str);
}
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
return "";
} finally {
try {
if (is != null)
is.close();
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
//------------------------------------------------------
private ArrayList<Courses> parseJsonData(String strJson) {
ArrayList<Courses> Course = new ArrayList<Courses>();
try {
// Generate JSONArray object by JSON String data
JSONArray arr = new JSONArray(strJson);
//from the JSONArray, get one element (row) of JSONData
for (int i = 0; i < arr.length(); i++) {
//Get JSON Object which is one element of the array
JSONObject ob = arr.getJSONObject(i);
Courses exam = new Courses();
//get the value by key, and set to exam class
exam.setCode(ob.optString("code"));
//save exam class to exam array list
Course.add(exam);
}
} catch (JSONException e) {
e.printStackTrace();
}
return Course;
}
}
}
The application crashes as soon as I click on the button and gives a error:
"android.os.NetworkOnMainThreadException"
Help Please !
The problem that you are having is network operation like what you are trying to do cannot and should not be performed on the main UI thread. Doing so will lead to an ANR (Android Not Responding), which is exactly the kind of error you are getting just now. What you want to do is move your code to a separate thread or to an AsyncTask that will perform this action in the background on a different thread using the doInBackground() method which does not have access to your views on the main UI thread. For example,
private class ExampleOperation extends AsyncTask<String, Void, String> {
public ExampleOperation() { //ctor }
#Override
protected void onPreExecute() {
//things that you want to initialize and maybe show dialog to user.
}
#Override
protected String doInBackground(String... params) {
//this is where you perform that network related operation.
}
#Override
protected void onPostExecute(String result) {
//this is where get the results from the network related task.
}
#Override
protected void onProgressUpdate(Void... values) {
//you can update your progressbar if any; otherwise omit method.
}
}
Then all you have to do is call the AsyncTask where ever you want to use it: new ExampleOperation().execute();
You can't make HTTP calls in the main thread, they take too long and would make the UI unresponsive. You need to do it in an AsyncTask.