IllegalStateException: Content has been consumed - android

I got struck because of IllegalStateException in the following code. Can anybody please help me? Code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
import android.telephony.gsm.GsmCellLocation;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class Login extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
Button bt = (Button) findViewById(R.id.logbt);
final EditText user = (EditText) findViewById(R.id.loguser);
final EditText pw = (EditText) findViewById(R.id.logpw);
bt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (user.getText().toString() != "" && pw.getText().toString() != "") {
Thread t = new Thread() {
public void run() {
try {
HttpClient client = new DefaultHttpClient();
String postURL = "http://surfkid.redio.de/login";
HttpPost post = new HttpPost(postURL);
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", user.getText().toString()));
params.add(new BasicNameValuePair("password", md5(pw.getText().toString())));
UrlEncodedFormEntity ent = new UrlEncodedFormEntity(params, HTTP.UTF_8);
post.setEntity(ent);
HttpResponse responsePOST = client.execute(post);
HttpEntity resEntity = responsePOST.getEntity();
final JSONObject jObject = new JSONObject(EntityUtils.toString(resEntity));
Log.e("XXX", EntityUtils.toString(resEntity));
} catch (Exception e) {
Log.e("XXX", e.toString());
}
}
};
t.start();
// Log.e("XXX",s);
}
}
});
}
private String md5(String in) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance("MD5");
digest.reset();
digest.update(in.getBytes());
byte[] a = digest.digest();
int len = a.length;
StringBuilder sb = new StringBuilder(len << 1);
for (int i = 0; i < len; i++) {
sb.append(Character.forDigit((a[i] & 0xf0) >> 4, 16));
sb.append(Character.forDigit(a[i] & 0x0f, 16));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
}
Logcat message:
01-18 18:39:53.383: ERROR/XXX(7113):
java.lang.IllegalStateException:
Content has been consumed

You can consume Content only at once from an Entity
in the line :
final JSONObject jObject = new JSONObject(EntityUtils.toString(resEntity));
you have consumed content and again you are using the same at here:
Log.e("XXX",EntityUtils.toString(resEntity));
That why it is causing IllegalStateException: Content has been consumed
So the solution is here:
String _response=EntityUtils.toString(resEntity); // content will be consume only once
final JSONObject jObject=new JSONObject(_response);
Log.e("XXX",_response);

it's also happens if you are writing the consuming statement in the Expressions of the debugger!!!
(e.g if you are doing "watch" to something like EntityUtils.toString(resEntity))

First, this has to be a mistake that every single new android programmer makes and it's asked here every single day. You have
user.getText().toString()!= ""&& pw.getText().toString()!= ""
This doesn't do what you want it to. You need
!user.getText().toString().equals("")&& !pw.getText().toString().equals("")
Also, you need to print the stacktrace. In your exception, you need
e.printStackTrace()
instead of logging
e.toString()

I just dealt with a case of a null check on the entity causing it to be flagged as "consumed". Hope my headache will help someone else out there.
Vikas Patidar's answer helped me figure out the key to the riddle, so many thanks

Related

Error when trying to use toast in android application

in my application i am fetching json data from online server. and after that i am trying to display the data by toast. but the application stop working. if i commented the toast section then the application runs smoothly. so i think there is a problem in toast section. so guys plz help me to find out the reason for the problem
package com.example.getdata;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.app.Activity;
public class MainActivity extends Activity {
EditText password,username;
String pass,user;
//TextView output;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onConnect(View v) {
new Thread(){
public void run(){
HttpClient myClient = new DefaultHttpClient();
HttpPost post = new HttpPost("http://tusharinfotech.com/debasish/get_data.php");
try {
List<NameValuePair> myArgs = new ArrayList<NameValuePair>();
// myArgs.add(new BasicNameValuePair("username", user));
// myArgs.add(new BasicNameValuePair("password", pass));
post.setEntity(new UrlEncodedFormEntity(myArgs));
HttpResponse myResponse = myClient.execute(post);
BufferedReader br = new BufferedReader( new InputStreamReader(myResponse.getEntity().getContent()));
String line = "";
String data1 ="";
while ((line = br.readLine()) != null)
{
try {
JSONArray myarray = new JSONArray(line);
for(int i=0;i<myarray.length();i++){
JSONObject jsonObject = myarray.getJSONObject(i);
int id = Integer.parseInt(jsonObject.optString("FOOD_ID").toString());
String name = jsonObject.optString("FOOD_NAME").toString();
data1 += "Node"+i+" : \n id= "+ id +" \n Name= "+ name +" \n ";
}
//Log.d("mytag",data);
//this application stop working for this toast part.. if i commented it then the application run smoothly
Toast.makeText(getApplicationContext(),data1, Toast.LENGTH_LONG).show();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//EditText output1 = (EditText) findViewById(R.id.editText1);
// output1.setText(data);
Log.d("mytag", line);
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
}
I guess you are trying to show toast on a background thread, which is not allowed in android. you can use this code to show toast in background thread :
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Hello", Toast.LENGTH_SHORT).show();
}
});
You must display Toast only from UI thread, to workaround this you can get use of runOnUiThread() method or create new Handler and pass in constructor Looper.getMainLoopper()
You could use AsyncTask Framework to make background processing easier http://developer.android.com/reference/android/os/AsyncTask.html.
The method onPostExecute(Result) will be run on your UI thread there for you can change your UI element here.

Send data to server and delete the data that are successfully sent

I want to send the data from the sqlite database in android to the server and delete those data from the database that have been reached to the server successfully. I have successfully written the code to send data to the server. But could not delete the data form database. How to know which data is reached to the server.
package com.example.income;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.*;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.IntentService;
import android.content.Intent;
import android.database.Cursor;
import android.util.*;
public class Background extends IntentService
{
public Background()
{
super("This is the simple background class");
}
#Override
protected void onHandleIntent(Intent intent)
{
Log.v("message","This is simple background service");
Db db =new Db(Background.this,"simple",null,4);
Cursor c= db.getData();
if( c.moveToFirst())
{
List<Map<String, String>> contacts = new ArrayList<Map<String, String>>();
do
{
String num,dater;
int integer;
integer=c.getInt (c.getColumnIndex(Base.Identifier));
num = c.getString(c.getColumnIndex(Base.CONTACTS));
dater =c.getString(c.getColumnIndex(Base.DATE));
Map<String, String> contact = new HashMap<String, String>();
contact.put("date", dater);
contact.put("contact", num);
contact.put("id",String.valueOf(integer));
contacts.add(contact);
}
while (c.moveToNext());
try
{
sendData(contacts);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e)
{
e.printStackTrace();
}
}
}
public void sendData(List<Map<String, String>> contacts) throws ClientProtocolException, IOException, JSONException
{
Log.v("Let's C","Will it go here?");
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://192.168.10.115/android.php");
Log.v("p","this");
Log.d("Contacts", Integer.toString(contacts.size()));
JSONArray array= new JSONArray(contacts);
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("forward",array.toString()));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response= httpclient.execute(httppost);
HttpEntity entity=response.getEntity();
String result =EntityUtils.toString(entity);
JSONArray obj = new JSONArray(result);
for(int i =0;i<obj.length();i++)
{
JSONObject json=obj.getJSONObject(i);
String success =json.getString("id");
Log.i("success ",success);
}
/*
Runtime runtime1 = Runtime.getRuntime();
Process proc = runtime1.exec("ping -c 8 www.google.com");
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String input;
while((input=reader.readLine())!=null)
{
Log.i("message",input);
}*/
}
}
I want to implement this as soon as data is sent to server.
Make a class that compares the value of sqlite data you send to the server through JSON object/array and return a flag. If it is successful then delete local data, if not try resending your data again.
This link might help you achieve your goal.
how to send data to server from android when no internet is available

Android HTTPGET request error, values not goin to server when click on login button [duplicate]

This question already has answers here:
What is the way to run a new thread and a UI thread in Android? [closed]
(3 answers)
Closed 8 years ago.
I'm trying to write a code which signups a user. The php script is running fine. But code is android code is not working. Values not going on server.
package com.androidexample.httpgetexample;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class HttpGetAndroidExample extends Activity {
TextView content;
EditText fname,email,login,pass;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_http_get_android_example);
content = (TextView)findViewById(R.id.content);
fname = (EditText)findViewById(R.id.name);
email = (EditText)findViewById(R.id.email);
login = (EditText)findViewById(R.id.loginname);
pass = (EditText)findViewById(R.id.password);
Button saveme=(Button)findViewById(R.id.save);
saveme.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v)
{
//ALERT MESSAGE
Toast.makeText(getBaseContext(),
"Please wait, connecting to server.",
Toast.LENGTH_LONG).show();
try{
String loginValue = URLEncoder.encode(login.getText().toString(), "UTF-8");
String fnameValue = URLEncoder.encode(fname.getText().toString(), "UTF-8");
String emailValue = URLEncoder.encode(email.getText().toString(), "UTF-8");
String passValue = URLEncoder.encode(pass.getText().toString(), "UTF-8");
HttpClient Client = new DefaultHttpClient();
String URL = "http://nishtha.comze.com/log.php?user="+loginValue+"&name="+fnameValue+
"&email="+emailValue+"&pass="+passValue;
//Log.d("httpget", URL);
try
{
HttpGet httpget = new HttpGet(URL);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
HttpResponse response = Client.execute(httpget);
Log.d("Http Response:", response.toString());
String SetServerString = "";
SetServerString = Client.execute(httpget, responseHandler);
content.setText(SetServerString);
}
catch(Exception ex)
{
content.setText("Fail!");
}
}
catch(UnsupportedEncodingException ex)
{
content.setText("Fail22");
}
}
});
}
}
When I run the code it olways display "Fail"
You need to use AsyncTask<> or IntentService to handle your request.

How to handle - Application has stopped working in Android

So I am trying to create an Android app which basically reads out the twitter feed according to the search query inside a UI. The feed that I need to display form the parsed JSON is the user name, handle, profile picture and the tweet.
Now I have created the whole thing and my code compiles but as soon as I run it the app opens and I write something in the search feed and hit enter - " Unfortunately, AppName has stopped working " I am attaching my logcat and my source code for reference.
*Solved the issue by removing set text from DoInBackground and then giving adequate permission for Android to access internet. The issue now is that as I try and display the profile picture, the URL gets displayed, not the image.
Source code :
package com.example.twittersearchactivity;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class TwitterSearchActivity extends Activity {
private TextView tweetDisplay;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_twitter_search);
tweetDisplay = (TextView)findViewById(R.id.tweet_txt);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.twitter_search, menu);
return true;
}
public void searchTwitter(View view){
EditText searchTxt = (EditText)findViewById(R.id.search_edit);
String searchTerm = searchTxt.getText().toString();
if(searchTerm.length()>0){
try{
String encodedSearch = URLEncoder.encode(searchTerm, "UTF-8");
String searchURL = "http://search.twitter.com/search.json?q="+encodedSearch;
new GetTweets().execute(searchURL);
Log.i("1", "entered the searchterm");
}
catch(Exception e){
tweetDisplay.setText("Whoops - something went wrong!");
e.printStackTrace();
}
}
else
tweetDisplay.setText("Enter a search query!");
}
private class GetTweets extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... twitterURL) {
StringBuilder tweetFeedBuilder = new StringBuilder();
for (String searchURL : twitterURL) {
HttpClient tweetClient = new DefaultHttpClient();
try {
HttpGet tweetGet = new HttpGet(searchURL);
HttpResponse tweetResponse = tweetClient.execute(tweetGet);
StatusLine searchStatus = tweetResponse.getStatusLine();
if (searchStatus.getStatusCode() == 200) {
HttpEntity tweetEntity = tweetResponse.getEntity();
Log.i("2", "entered gettweets");
InputStream tweetContent = tweetEntity.getContent();
InputStreamReader tweetInput = new InputStreamReader(tweetContent);
BufferedReader tweetReader = new BufferedReader(tweetInput);
String lineIn;
while ((lineIn = tweetReader.readLine()) != null) {
tweetFeedBuilder.append(lineIn);
Log.i("3", "entered while in dobackground");
}
}
else {Log.i("error", "error");}
//tweetDisplay.setText("Whoops - something went wrong!");
}
catch(Exception e) {
Log.e("DEBUGTAG", "Remote Image Exception", e);
//tweetDisplay.setText("Whoops - something went wrong!");
e.printStackTrace();
}}
return tweetFeedBuilder.toString();
}
protected void onPostExecute(String result) {
StringBuilder y;
StringBuilder tweetResultBuilder = new StringBuilder();
try {
Log.i("tag", "entered try block");
JSONObject resultObject = new JSONObject(result);
JSONArray tweetArray = resultObject.getJSONArray("results");
for (int t=0; t<tweetArray.length(); t++) {
Log.i("tag", "entered the json stream");
JSONObject tweetObject = tweetArray.getJSONObject(t);
tweetResultBuilder.append(tweetObject.getString("from_user")+": ");
tweetResultBuilder.append(tweetObject.getString("from_user_name")+": ");
tweetResultBuilder.append(tweetObject.get("text")+"\n\n");
String imageURL = (String) tweetObject.get(("profile_image_url")+": ");
Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageURL).getContent());
#SuppressWarnings("deprecation")
Drawable d =new BitmapDrawable(bitmap);
d.setAlpha(255);
TextView.setCompoundDrawablesWithIntrinsicBounds(0,0,1,0);
}
}
catch (Exception e) {
tweetDisplay.setText("Whoops - something went wrong!");
e.printStackTrace();}
if(tweetResultBuilder.length()>0)
tweetDisplay.setText(tweetResultBuilder.toString());
else
tweetDisplay.setText("Sorry - no tweets found for your search!");
}
}}
You can't call view functions like setText on another thread like an AsyncTask doInBackground function. You need to do it in onPostExecute.

ProgressDialog is invisible

Hy!!
I have a problem with the progressdialog.
My used code:
package com.android.skiptvad;
import java.io.InputStreamReader;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.graphics.LightingColorFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.android.skiptvad.*;
public class Login extends Activity {
/** Called when the activity is first created. */
TextView tvuser;
String sessionid;
ProgressDialog pd = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
tvuser = (TextView) findViewById(R.id.tvuser);
TextView tvpw = (TextView) findViewById(R.id.tvpw);
final EditText etuser = (EditText) findViewById(R.id.etuser);
final EditText etpw = (EditText) findViewById(R.id.etpw);
Button btlogin = (Button)findViewById(R.id.btlogin);
btlogin.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (etuser.getText() != null && etpw.getText()!= null)
{
runOnUiThread(new Runnable() {
#Override
public void run() {
pd = ProgressDialog.show(Login.this,"","Loading. Please wait...", true);
pd.show();
Thread t = new Thread() {
public void run(){
download(etuser.getText().toString(), md5(etpw.getText().toString()));
pd.dismiss();
}
};
t.run();
}
});
}
}
});
}
public void download (final String user, final String pw)
{
try{
HttpClient client = new DefaultHttpClient();
String postURL = "link_deleted";
HttpPost post = new HttpPost(postURL);
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", user));
params.add(new BasicNameValuePair("password", pw));
UrlEncodedFormEntity ent = new UrlEncodedFormEntity(params,HTTP.UTF_8);
post.setEntity(ent);
HttpResponse responsePOST = client.execute(post);
HttpEntity resEntity = responsePOST.getEntity();
final JSONObject jObject = new JSONObject(EntityUtils.toString(resEntity));
JSONObject menuObject = jObject.getJSONObject("responseData");
if (jObject.getInt("responseStatus")== 200 && jObject.get("responseDetails")!= null)
{
sessionid = menuObject.getString("session_id");
finish();
}
else
{
//dismissDialog(DIALOG_LOADING);
if (jObject.getInt("responseStatus")== 500)
{
throw new Exception("Server Error");
}
else if (jObject.getInt("responseStatus")== 400)
{
throw new Exception("Wrong User/Password");
}
else
{
throw new Exception();
}
}
//pd.dismiss();
} catch (Exception e) {
//dismissDialog(DIALOG_LOADING);
Toast toast ;
toast = Toast.makeText(getApplicationContext(), e.getMessage(), 500);
toast.show();
}
}
private String md5(String in) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance("MD5");
digest.reset();
digest.update(in.getBytes());
byte[] a = digest.digest();
int len = a.length;
StringBuilder sb = new StringBuilder(len << 1);
for (int i = 0; i < len; i++) {
sb.append(Character.forDigit((a[i] & 0xf0) >> 4, 16));
sb.append(Character.forDigit(a[i] & 0x0f, 16));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) { e.printStackTrace(); }
return null;
}
}
No error occurs in the Dalvik Debug Monitor.
Please help
I would recommend to use AsyncTask for this case. So in your AsyncTask.onPreExecute() you call Activity.showDialog(int id), do your networking job in AsyncTask.doInBackground() and Activity.dismissDialog(int id) the dialog in AsyncTask.onPostExecute().
I think that's the most correct way of doing such "under-popup" things.

Categories

Resources