my app sends a POST request to a server and gets a response using JSON format.
Sometimes my JSON response is "null" (if the request goes in time out).
In that case I need to notify the user about the timeout (dialog or toast) and avoid the app to crash.
How do I handle correctly the JSONException and avoid the app crash?
Thank you!
Marco
to avoid the crach of your app while parsing your json , try this :
if (jsonResponse == null) {
// notify user
} else {
try {
// parse json here.
} catch (JSONException e) {
Toast.makeText(this,"Error on the response", 3000).show();
}
}
check if your json response is null. only then parse the json.
if (jsonResponse == null) {
// notify user
} else {
// parse json here.
}
get full exception :
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
jsonString = out.toString();
}
}catch(ConnectException e){
// handle your exception here, maybe something like
Toast.makeText(context,"Error!",5000).show();
finish();
} catch (URISyntaxException e1) {
e1.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Related
I have some code that converts my HTTPResponse Object into a JSONObject, which works fine most of the time:
public static JSONObject httpResponseToJson(HttpResponse response) {
if (response != null) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(),
"UTF-8"));
String json = reader.readLine();
if (json != null) {
JSONObject jsonObject = new JSONObject(json);
printStatus(jsonObject);
return jsonObject;
}
} catch (JSONException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
However, sometimes it throws a the Android NetworkOnMainThread exception. I cannot figure out why, because the response is already finished and there should not be any more network IO involved in that call. For test reasons, if I allow NetworkOnMainThread, this method works fine all the time.
Note that all the HTTPResponse is fetched with an AsyncTask and this is working fine.
I am very interested in any suggestions.
Reading the response from a HttpResponse object also involves a Network Operation. Simply process that also in the doInBackground() method and modify your AsyncTask to pass to the onPostExecute() the real result once processed.
its mean you are performing some network operation on main thread.The point here is Unless the stream is not closed, you are still performing network operation so move that part into doInBackGround() too.
I'm using the following code to post to a Google Form. If the HTTP response is not successful then the record is not marked as sent from the sqlite database and is resent during the next sync operation. The problem is I see frequent double posts because a response is not received even though the post was successful.
Is there a better way to confirm the post without creating double posts to the form?
Thanks for your help.
private Boolean performPost(String...data){
prefs = UserData.getPrefs(mContext);
spreadsheetKey = prefs.getString(UserData.PREF_SPREADSHEET_KEY,"");
ArrayList<BasicNameValuePair> results = new ArrayList<BasicNameValuePair>();
HttpPost post = new HttpPost("https://spreadsheets.google.com/spreadsheet/formResponse?hl=en_US&formkey=" + spreadsheetKey);
int counter = 0;
for (String s : data){
results.add(new BasicNameValuePair("entry." + counter + ".single", s));
counter ++;
}
try {
post.setEntity(new UrlEncodedFormEntity(results));
} catch (UnsupportedEncodingException e) {
// Auto-generated catch block
Log.e(TAG, "An error has occurred", e);
}
try {
//client.execute(post);
HttpResponse response = client.execute(post);
StatusLine statusLine = response.getStatusLine();
returnCode = statusLine.getStatusCode();
Log.d(TAG, statusLine+ "\n"+ returnCode + " " + String.valueOf(post.getEntity()));
response.getEntity().consumeContent();
} catch (ClientProtocolException e) {
// Auto-generated catch block
Log.e(TAG, "client protocol exception", e);
} catch (IOException e) {
// Auto-generated catch block
Log.e(TAG, "io exception", e);
}
if (returnCode == 200){
return true;
}else{
resultTxt = SYNC_UNSUCCESSFUL_HTTP_ERROR;
Log.e(TAG,"post unsuccessful, http code :" + String.valueOf(returnCode));
sendBroadcast();
return false;
}
}
Update 1
main.java file
//how would i return those errors on the main.java file? so that i can display on the UI.
directory_listings = obj.get_webpage_source();
end
I am new to Android mobile application development. I would like to know, how can I handle the exception like HttpConnection related exceptions or any other important exceptions.
i am thinking of top of my head:
server is down
file not exists
no data found
my code is here:
the below code is in its own java class and i am calling this code from main.java
public class Get_Webpage {
public String get_webpage_source(){
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(parsing_url);
HttpResponse response = null;
...............
...............
...............
}
}
you need to catch all the below exception when reading file from the web.
try
{
}
catch (SocketTimeoutException e) {
e.printStackTrace();
return "error";
}
catch (ConnectTimeoutException e)
{
e.printStackTrace();
return "error";
}
catch (ClientProtocolException e)
{
e.printStackTrace();
return "error";
}
catch (IOException e)
{
e.printStackTrace();
return "error";
}
finally {
client.getConnectionManager().shutdown();
}
my HttpGet request is calling my indexAction, instead of getAction. What's going on?
Here are my codes:
public function getAction() {
$id = $this->_getParam('id');
if(!$id)
{
$this->getResponse()
->setHttpResponseCode(400)
->setBody("no id");
return;
}
try
{
$q = Doctrine_Query::create()
->from('Milotin_Model_Locations l')
->where ('l.id=?', $id);
$result = $q->fetchArray();
if(count($result) == 1)
{
$this->getResponse()
->setHttpResponseCode(200)
->setBody(json_encode($result));
}
}
catch(Exception $e)
{
$this->getResponse()
->setHttpResponseCode(500)
->setBody($e->getMessage());
}
}
public function indexAction() {
}
And here is my code in Android:
private static void getLoc()
{
final HttpResponse response;
final HttpGet getRequest = new HttpGet(LOCATION_URI + "?geolat=" + geoLat + "&geolong=" + geoLong);
try {
response = mHttpClient.execute(getRequest);
if(response.getStatusLine().getStatusCode() == 200)
{
//do something
}
} catch (ClientProtocolException e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
}
}
My HttpPost is working correctly (it calls postAction), Any explanation?
Thanks.
I found the answer. It's actually the behavior of Zend Framework. If the 'id' element is not found in the GET request, it will redirect to indexAction, instead of getAction.
Example:
'GET localhost/student' will redirected to indexAction, while
'GET localhost/student/23' will redirected to getAction. (23 is the id)
Found it in Zend Framework: A beginner's guide, by Vikram Vaswani.
I'm trying to connect to a webservice offered by my heating at home. Putting the request URL into Chrome results in a complete XML file.
Subsequently I tried to do the same programmatically with an Android application, which unfortunately only replies about the half of the XML file.
I already tried several attempts, amongst others a simple HttpConnection:
private void androidHttpConnect() {
HttpURLConnection urlConnection=null;
try {
URL url = new URL("http://10.0.0.140:8080/user/menu");
urlConnection = (HttpURLConnection) url.openConnection();
BufferedInputStream in = new BufferedInputStream(
urlConnection.getInputStream());
Log.i("myapp",convertStreamToString(in));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
urlConnection.disconnect();
}
}
private String convertStreamToString(InputStream is) {
return new Scanner(is).useDelimiter("\\A").next();
}
and the Android Http Client ...
HttpClient httpclient = AndroidHttpClient.newInstance("Android");
HttpGet httpget = new HttpGet("http://10.0.0.140:8080/user/menu");
HttpResponse response;
try {
response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null) {
long len = entity.getContentLength();
Log.d("myapp", "content length "+len);
if (len != -1) {
try {
Log.d("myapp", EntityUtils.toString(entity));
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
// Stream content out
}
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Interestingly those attempts cut the result on different positions, even though they only differ in about 5 characters. At this position there is no special character and the XML is quite short.
Anyone any idea? I also tried to run it in a ASyncTask to ensure no interrupt by the UI thread, but without success.
Thanks for your help.
Finally found the solution by myself! The problem wasn't the request but the output in the LogCat. Logging every line separately obtained the desired full response!