Android app stopped working - servlets and Httpget - android

I have a problem. I am starting my adventure with servlets and Android and I designed a simple servlet which writes "Hello world". Now I want to receive this message in my Android app. My code:
public class MyServlet extends Activity implements OnClickListener{
Button button;
TextView outputText;
public static final String URL = "http://10.0.2.2:8080/ServletExample/HelloServletExample";
#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) {
String output = null;
HttpClient httpclient = new DefaultHttpClient();
try {
HttpResponse response = httpclient.execute(new HttpGet(URL));
HttpEntity httpEntity = response.getEntity();
output = EntityUtils.toString(httpEntity);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
//} catch (IOException e) {
// TODO Auto-generated catch block
//}
outputText.setText(output);
}
My servlet:
#WebServlet("/HelloServletExample")
public class HelloServletExample extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public HelloServletExample() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("Hello World");
}
}
I don't know why but my app crashes. I tried commenting out some lines and it turns out that what is the problem is this line:
HttpEntity httpEntity = response.getEntity();
Why?

if you are using API level >= 9 then no need to use AsyncTask for making network request from Ui Thread just add StrictMode.ThreadPolicy in Activity onCreate method as:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().
permitAll().build();
StrictMode.setThreadPolicy(policy);

Related

Trying to use AsyncTask to update server periodically

I have a method that need to update its status periodically to the server.
I am using AsyncTask to run the HTTP call in background.
PROBLEM: In onPostExecute method upon checking AsyncTask.getStatus, It show the previous task still running which is causing the error.
ERROR: java.lang.IllegalStateException: Cannot execute task: the task is already running.
DIFFERENT STRATEGIES USED TO SOLVE THE PROBLEM BUT NONE IS WORKING
1. Before Relaunching AsyncTask, checked the status, it is showing the thread is RUNNING.
2. Called the AsyncTask.cancel(true), immediately before calling the AsyncTask.execute if it is still running. It turns out AsyncTask still RUNNING and taking more than 3 mins to get cancel.
NOTE: I have checked many similar questions here, but haven't found helpful.
I would really appredicae if any one of you guys give me an example to solve this issue, Thanks a Million in advance......
public class MainActivity extends Activity implements AsyncResponse{
ConnectServer asyncTask =new ConnectServer();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
asyncTask.delegate = this;
setContentView(R.layout.activity_main);
//Start updating server using below method
loop();
}
public void processFinish(String output){
//this you will received result fired from async class of onPostExecute(result) method.
//Log.v(TAG, output);
if(output != null){
//not using this at this point
}
}
//Method that will call Async method to reach server
public void loop(){
TextView b = (TextView) findViewById(R.id.mField);
String str;
try {
str = asyncTask.execute(true).get();
b.setText(str);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// START SERVER CONNECTION
class ConnectServer extends AsyncTask<Boolean, String, String> {
public AsyncResponse delegate=null;
public int i = 0;
private Activity activity;
public void MyAsyncTask(Activity activity) {
this.activity = activity;
}
#Override
protected String doInBackground(Boolean... params) {
String result = null;
StringBuilder sb = new StringBuilder();
try {
// http post
HttpClient httpclient = new DefaultHttpClient();
HttpGet httppost = new HttpGet("http://192.168.0.21:8080");
HttpResponse response = httpclient.execute(httppost);
if (response.getStatusLine().getStatusCode() != 200) {
Log.d("GPSApp", "Server encountered an error");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF8"));
sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
result = sb.toString();
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
return result;
}
#Override
protected void onPostExecute(String result) {
TextView mField = (TextView) findViewById(R.id.mField);
mField.setText(result+i);
try {
Thread.sleep(10000);
//asyncTask =new ConnectServer();
i++;
String str = asyncTask.execute(true).get();
mField.setText(str+i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void onPreExecute() {}
}
}
Call getStatus() to get the status of AsyncTask. If the status is AsyncTask.Status.RUNNING, cancel it.

getting FATAL EXCEPTION in MAIN when doing a callback,asyntask android

After reading over android asynctask sending callbacks to ui My goal is :
dialog box will show when you are waiting for the authentication from
the server and as long as the process is done, a call back will be
invoked and dialog box will be dismissed.
My structure is ( asyntask and log in activity are separated classes )
Log in activity
Class A extends Aysnctask
A call back interface.
Partial of my codes :
public class SpalshScreenActivity extends Activity implements LogInCallBack{
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
logInButton = (Button) findViewById(R.id.btnLogin);
logInButton.setBackgroundDrawable(getResources() .getDrawable(R.drawable.button));
logInButton .setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog = new ProgressDialog(SpalshScreenActivity.this);
dialog.setMessage("waiting......");
dialog.show();
Service client = new Service(new SpalshScreenActivity(), email.getText().toString(), password.getText().toString());
String logInURL = "my url goes here";
client.execute(logInURL);
}
});
}
}
#Override
public void successfullyLogIn() {
Log.d("SPLASH","successfullyLogIn");
dialog.dismiss(); // **<--------crash is at here**
}
#Override
public void failedToLogIn() {
}
}
Service.java :
public class Service extends AsyncTask<String, Integer, String> {
private LogInCallBack callBack;
String userName;
String password;
public Service(LogInCallBack callBack, String userName, String password) {
this.callBack = callBack;
this.userName = userName;
this.password = password;
}
// Handling ssl connection
protected String doInBackground(String... arg) {
// validation and accept all type of self signed certificates
SimpleSSLSocketFactory simpleSSLFactory;
String logInURL = arg[0];
try {
simpleSSLFactory = new SimpleSSLSocketFactory(null);
simpleSSLFactory .setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
// Enable HTTP parameters
params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
// Register the HTTP and HTTPS Protocols. For HTTPS, register our
// custom SSL Factory object.
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory .getSocketFactory(), 80));
registry.register(new Scheme("https", simpleSSLFactory, 443));
// Create a new connection manager using the newly created registry
// and then create a new HTTP client
// using this connection manager
ccm = new ThreadSafeClientConnManager(params, registry);
} catch (KeyManagementException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (UnrecoverableKeyException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (NoSuchAlgorithmException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (KeyStoreException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// TODO Auto-generated method stub
HttpClient client = new DefaultHttpClient(ccm, params);
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(2);
nameValuePair.add(new BasicNameValuePair("user_session[email]", "lenanguyen#hotmail.ca"));
nameValuePair.add(new BasicNameValuePair("user_session[password]","2congato"));
// Create http GET method
HttpPost logIn = new HttpPost(logInURL);
try {
logIn.setEntity(new UrlEncodedFormEntity(nameValuePair));
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// Fire a request
try {
HttpResponse response = client.execute(logIn);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
this.result = convertStreamToString(is);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("ClientProtocolException is ", e.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("IOException is ", e.toString());
}
return result;
}
// called after doInBackground finishes
protected void onPostExecute(String result) {
Log.e("result, yay!", this.result);
this.callBack.successfullyLogIn();
}
}
and my call back interface is
public interface LogInCallBack {
void successfullyLogIn ();
void failedToLogIn();
}
However after the dialog shows up for a few seconds, my app is crashing and FATAL Exception in MAIN is thrown in the cat log. Any ideas about this guys.
PS :
log cat i here
Change
Service client = new Service(new SpalshScreenActivity(), email.getText().toString(), password.getText().toString());
into
Service client = new Service(SpalshScreenActivity.this, email.getText().toString(), password.getText().toString());
and
public FlipGiveClient(LogInCallBack callBack, String userName, String password) {
this.callBack = callBack;
this.userName = userName;
this.password = password;
}
into
public FlipGiveClient(Activity activity, String userName, String password) {
this.callBack = (LogInCallBack) activity;
this.userName = userName;
this.password = password;
}

Android Strict Mode

I have written a simple code on JSON Parsing using AsyncTask. I'm just displaying the response in TextView. I don't know whether it is right or wrong. Its working on GingerBread and showing NetworkOnMainThreadException on JellyBean. If I use StrictMode, its working on JellyBean and getting force close on GingerBread. How to write the code which support above Android 3.0 and below Android 3.0.
public class MainActivity extends Activity {
TextView tv;
Button b;
InputStream is = null;
DefaultHttpClient client;
HttpGet get;
HttpResponse response;
HttpEntity entity;
StringBuffer buffer;
#SuppressLint("NewApi")
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
// StrictMode.setThreadPolicy(policy);
tv = (TextView) findViewById(R.id.texty);
b = (Button) findViewById(R.id.buttonGET);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyOperation mytask = new MyOperation();
mytask.execute();
}
});
}
private class MyOperation extends AsyncTask<String, Void, String> {
ProgressDialog dialog = new ProgressDialog(MainActivity.this);
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
dialog.setMessage("Loading...");
dialog.show();
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
client = new DefaultHttpClient();
get = new HttpGet("http://www.google.com");
try {
response = client.execute(get);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
entity = response.getEntity();
try {
is = entity.getContent();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialog.dismiss();
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
StringBuffer buffer = new StringBuffer();
String line = null;
do {
try {
line = reader.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
buffer.append(line);
} while (line != null);
tv.setText(buffer);
}
}
}
public class MainActivity extends Activity {
TextView tv;
Button b;
InputStream is = null;
DefaultHttpClient client;
HttpGet get;
HttpResponse response;
HttpEntity entity;
StringBuffer buffer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//StrictMode.ThreadPolicy policy = new
// StrictMode.setThreadPolicy(policy);
tv = (TextView) findViewById(R.id.texty);
b = (Button) findViewById(R.id.buttonGET);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyOperation mytask = new MyOperation();
mytask.execute();
}
});
}
private class MyOperation extends AsyncTask<String, Void, String> {
ProgressDialog dialog = new ProgressDialog(MainActivity.this);
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
dialog.setMessage("Loading...");
dialog.show();
}
#Override
protected String doInBackground(String... params) {
StringBuffer buffer = new StringBuffer();
// TODO Auto-generated method stub
client = new DefaultHttpClient();
get = new HttpGet("http://www.google.com");
try {
response = client.execute(get);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
entity = response.getEntity();
try {
is = entity.getContent();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
String line = null;
do {
try {
line = reader.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
buffer.append(line);
} while (line != null);
return buffer.tostring();
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialog.dismiss();
tv.setText(result);
}}
}
otherwise you are running the read line operation in main thread
Make the InputStream is and Entity entity local field variables in the doInBackground() as return as result the string that you wanna set on the TextView...and on the onPostExecute() you just get the result (the string) and set it in the TextView straight on.
You should read inputStream data in doInBackground function, not in the onPostExecute. So construct StringBuffer in doInBackground append all lines to it and return StringBuffer.toString as result. In onPostExecute you will get what string as parameter.

In case of exception in asynctask, how do i post the error message on UI?

I am trying to hit a url through asynctask class and some times, url might not be reachable, in such cases application crashes, how do i prevent this from happening, I would like to display an error message/Toast on UI..I tried to implement runOnUiThread(), but was not successful.
This is my asynctask class: In this case I will be gettin IOException.
public class SelectedEmployeeAsyncTask extends AsyncTask<String, Void, ArrayList<Employee>>{
private CaptureActivity captureActivity;
public SelectedEmployeeAsyncTask(CaptureActivity activity) {
this.captureActivity = activity;
}
#Override
protected ArrayList<Employee> doInBackground(String... url) {
ArrayList<Employee> employees = null;
for(String employeeUrl : url){
employees = fetch(employeeUrl);
}
return employees;
}
private ArrayList<Employee> fetch(String url) {
ArrayList<Employee> employees = null;
String response = null;
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
employees = EmployeeXMLParser.selectedEmployeeParser(response);
System.out.println("Size in fetch "+employees.size());
//System.out.println("Employee Name :: " + employees.get(0).getFirstName() + " " + employees.get(0).getLastName());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} /*catch (XmlPullParserException e) {
// TODO Auto-generated catch block
System.out.println("Error parsing the response :: " + response);
e.printStackTrace();
}*/
return employees;
}
#Override
public void onPostExecute(ArrayList<Employee> employees){
super.onPostExecute(employees);
System.out.println("in post execxute "+employees.size());
//progressDialog.dismiss();
captureActivity.display(employees);
//activity.showEmployees(employees);
//activity.setContentView(R.layout.activity_capture);
}
}
This is my activity class, where asynctask would be called:
public class CaptureActivity extends Activity {
//private String url = "http://192.168.3.140:8080/EmployeeXmlDemo/EmployeeList.xml";
private String url = "http://192.168.2.223:8680/capture/clientRequest.do?r=employeeList&cid=0";
FetchEmployeeAsyncTask employeeAsyncTask;
private ArrayList<Employee> employees = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("");
//if(employees!=null){
employeeAsyncTask = new FetchEmployeeAsyncTask(this);
//selectedEmployeeAsyncTask = new SelectedEmployeeAsyncTask(this);
employeeAsyncTask.execute(url);
setContentView(R.layout.activity_capture);
System.out.println("Status "+employeeAsyncTask.getStatus());
//}
}
try this,
catch (final Exception e) {if (e != null) {
e.printStackTrace();
Temes.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show();
}
});
}

Json MySql get Two Integers and a String

Here is the class where i get JSON objects. In this code I get only one object and I don't really know how to return from the method, there is a Protected Void method where it is a settext method called and there is where the only JSON object goes.
public class ConnectMySql extends Activity {
TextView httpStuff;
HttpClient client;
JSONObject json;
final static String URL = "http://79.114.48.119/RadarsMySql.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
httpStuff = (TextView) findViewById(R.id.tvHttp);
client = new DefaultHttpClient();
new Read().execute("latitude");
}
public JSONObject lastTweet(String username) throws ClientProtocolException, IOException,JSONException{
StringBuilder url = new StringBuilder(URL);
url.append(username);
HttpGet get = new HttpGet(url.toString());
HttpResponse r = client.execute(get);
int status = r.getStatusLine().getStatusCode();
//if(status == 200){
HttpEntity e = r.getEntity();
String data = EntityUtils.toString(e);
data = data.substring(data.indexOf("["));
JSONArray timeline = new JSONArray(data);
JSONObject last = timeline.getJSONObject(0);
return last;
//}else{
//Toast.makeText(ConnectMySql.this, "error", Toast.LENGTH_LONG);
//return null;
//}
}
public class Read extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
try {
json = lastTweet("");
return json.getString(params[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
public void onPostExecute(String result) {
// TODO Auto-generated method stub
httpStuff.setText(result);
int myNum = 0;
try {
myNum = Integer.parseInt(result);
httpStuff.setText(myNum);
} catch(NumberFormatException nfe) {
System.out.println("Could not parse " + nfe);
}
}
}
}
What I want to do is to have an array where i could store three kind of objects (exemple Latitude[1], Longitude [1], Description[1]; Latitude[2] etc... I would like the latitude and longitude to be as integers ). After this I will use a for loop to call a function with this 3 parameters. Could anyone help me or could give me some tips ?
Thank you!
Dont use AsyncTask, as it executes in background, and this is why it causes some problems for you.
And when you have your twitter arser working, integrate it in a AsyncTask. Code below is not tested.
public class ConnectMySql extends Activity {
TextView httpStuff;
HttpClient client;
int i;
JSONObject json;
final static String URL = "http://localhost/RadarsMySql.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
httpStuff = (TextView) findViewById(R.id.tvHttp);
client = new DefaultHttpClient();
for(i=0;i<2;i++){
new Read().execute("latitude");
try {
json = lastTweet("",i);
String result = json.getString(params[i]);
httpStuff.setText(result);
int myNum = 0;
try {
myNum = Integer.parseInt(result);
httpStuff.setText(myNum);
} catch(NumberFormatException nfe) {
System.out.println("Could not parse " + nfe);
}
} 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();
}
}
}
public JSONObject lastTweet(String username,int i) throws ClientProtocolException, IOException,JSONException{
StringBuilder url = new StringBuilder(URL);
url.append(username);
HttpGet get = new HttpGet(url.toString());
HttpResponse r = client.execute(get);
int status = r.getStatusLine().getStatusCode();
//if(status == 200){
HttpEntity e = r.getEntity();
String data = EntityUtils.toString(e);
data = data.substring(data.indexOf("["));
JSONArray timeline = new JSONArray(data);
JSONObject last = timeline.getJSONObject(i);
return last;
//}else{
//Toast.makeText(ConnectMySql.this, "error", Toast.LENGTH_LONG);
//return null;
//}
}
}

Categories

Resources