0

I'm using google to get the currency and using json I should get the value of the currency but I get an error. "Unfortunately, xxx has stopped."

String result = null;

my Asynktask

private class usdjson extends AsyncTask<URL, Void, JSONObject> {

       @Override
        protected JSONObject doInBackground(URL... urls) {
               DefaultHttpClient   httpclient = new DefaultHttpClient(new BasicHttpParams());
               HttpPost httppost = new HttpPost("http://www.google.com/ig/calculator?hl=en&q=2GBP=?USD");
               httppost.setHeader("Content-type", "application/json");
                            InputStream inputStream = null;
                            try {
                                HttpResponse response = httpclient.execute(httppost);           
                                HttpEntity entity = response.getEntity();

                                inputStream = entity.getContent();
                                // json is UTF-8 by default
                                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
                                StringBuilder sb = new StringBuilder();

                                String line = null;
                                while ((line = reader.readLine()) != null)
                                {
                                    sb.append(line + "\n");
                                }
                                result = sb.toString();
                               Log.e("Log", result);
                            } catch (Exception e) { 
                                // Oops
                            }
                            finally {
                                try{if(inputStream != null)inputStream.close();}catch(Exception squish){}
                            }

                            JSONObject object = null;
                            try {
                                object = new JSONObject(result);
                            } catch (JSONException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            JSONArray Jarray = null;
                            try {
                                Jarray = object.getJSONArray("lhs");
                            } catch (JSONException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            JSONObject Jasonobject = null;
                            for (int i = 0; i < Jarray.length(); i++) {
                            try {
                                Jasonobject = Jarray.getJSONObject(i);
                            } catch (JSONException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            }
                        return Jasonobject;

        }

       @Override
        protected void onPostExecute(JSONObject jsonData) {
           value.setText(result);
        }
    }

my button click

.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            new usdjson().execute();
                            }
                    });

the logcat:

08-30 21:21:51.769: E/AndroidRuntime(28903): FATAL EXCEPTION: AsyncTask #1
08-30 21:21:51.769: E/AndroidRuntime(28903): java.lang.RuntimeException: An error occured while executing doInBackground()
08-30 21:21:51.769: E/AndroidRuntime(28903):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
08-30 21:21:51.769: E/AndroidRuntime(28903):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
08-30 21:21:51.769: E/AndroidRuntime(28903):    at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
08-30 21:21:51.769: E/AndroidRuntime(28903):    at java.util.concurrent.FutureTask.run(FutureTask.java:239)
08-30 21:21:51.769: E/AndroidRuntime(28903):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
08-30 21:21:51.769: E/AndroidRuntime(28903):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
John Jared
  • 790
  • 3
  • 16
  • 40

3 Answers3

3

Use AsyncTask to do network operations as Android API Level-10 and higher don't support network operations on the main UI thread. Create a subclass (make it extend AsyncTask) of your Activity and then move on code to the doInBackground and onPostExecute methods of the subclass. In the onClickListener call the subclass using the execute method . Also instead of using multiple try catch blocks use on try block and write multiple catch statements for them. The android documentation for AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html.

setOnClickListener(new View.OnClickListener() {     
       @Override 
       public void onClick(View v) {
                new FetchData().execute(); // here FetchData is the name of the subclass
                 }
             });

The code for the class FetchData is

class FetchData extends AsyncTask<String, String, String>
{
      JSONObject object = null;
      JSONArray JArray = null;
      protected String doInBackground(String...params)
       {
       try { 
        DefaultHttpClient   httpclient = new DefaultHttpClient(new BasicHttpParams());
                        HttpPost httppost = new HttpPost("http://www.google.com/ig/calculator?hl=en&q=2GBP=?USD");
                        httppost.setHeader("Content-type", "application/json");
        InputStream inputStream = null;
                            HttpResponse response = httpclient.execute(httppost);           
                            HttpEntity entity = response.getEntity();

                            inputStream = entity.getContent();
                            // json is UTF-8 by default 
                            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
                            StringBuilder sb = new StringBuilder();

                             String line = null;
                            while ((line = reader.readLine()) != null)
                            { 
                                sb.append(line + "\n");
                            } 
                            result = sb.toString();
                            object = new JSONObject(result);
                            Jarray = object.getJSONArray("lhs");
                          } catch (Exception e) { 
                            e.printStackTrace();
                        } catch(JSONException e){
                            e.printStackTrace():
                         }
                       }
protected void onPostExecute(String url){
      try{
      for (int i = 0; i < Jarray.length(); i++) 
                           {
                               JSONObject Jasonobject = Jarray.getJSONObject(i);//you can access all your data using this JSONObject
                          }
    } catch(JSONException e){
      e.printStackTrace();
     }
  }
 }
}

I also think you have some unhandled InputStreamException which may cause your application to crash.

tanay tandon
  • 243
  • 3
  • 19
1

As mentioned by Selvin, you are trying to perform network operations on the main thread, which is causing an error. To avoid that, you need to do these network operations in another thread.

The most common way to achieve that is to use a class that extends AsyncTask : http://developer.android.com/reference/android/os/AsyncTask.html

When extending AsyncTask, you will have to override a couple of methods, in particular doInBackground()and onPostExecute(). The first one will be used to do the network operations the background, and the second will process the results that you will return in the first one.

In your case, the network operations start after DefaultHttpClient httpclient..... until value.setText(result); (not included). This will have to be done in doInBackground. Don't forget to return the result variable.

The rest of your code, in fact the line value.setText(result); will have to be moved to onPostExecute(). There you will retrieve resultand do your processing.

EDIT

Regarding your other question, you should have that :

private class usdjson extends AsyncTask<URL, Void, JSONObject> {

   @Override
    protected JSONObject doInBackground(URL... urls) {

           DefaultHttpClient   httpclient = new DefaultHttpClient(new BasicHttpParams());
           HttpPost httppost = new HttpPost(urls[0]);
           httppost.setHeader("Content-type", "application/json");

                        InputStream inputStream = null;
                        try {
                            HttpResponse response = httpclient.execute(httppost);           
                            HttpEntity entity = response.getEntity();

                            inputStream = entity.getContent();
                            // json is UTF-8 by default
                            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
                            StringBuilder sb = new StringBuilder();

                            String line = null;
                            while ((line = reader.readLine()) != null)
                            {
                                sb.append(line + "\n");
                            }
                            result = sb.toString();
                        } catch (Exception e) { 
                            // Oops
                        }
                        finally {
                            try{if(inputStream != null)inputStream.close();}catch(Exception squish){}
                        }

                        JSONObject object = null;
                        try {
                            object = new JSONObject(result);
                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        JSONArray Jarray = null;
                        try {
                            Jarray = object.getJSONArray("lhs");
                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        JSONObject Jasonobject;
                        for (int i = 0; i < Jarray.length(); i++) {
                        try {
                            Jasonobject = Jarray.getJSONObject(i);
                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        }
                    return Jasonobject 

    }

   @Override
    protected void onPostExecute(JSONObject jsonData) {
         value.setText(result);
    }
}
jbihan
  • 3,053
  • 2
  • 24
  • 34
  • Well I guess you will have to debug your code step by step, I can't answer for these errors. But you are almost there I think. Add some log into your code to check the url and the data that you receive, it wil indicate you where the error is. – jbihan Aug 30 '13 at 18:15
  • `new usdjson().execute();` --> you need to pass the URL => `new usdjson().execute(requestUrl);` `requestUrl` being `URL requestUrl = new URL("http://www.google.com/ig/calculator?hl=en&q=1USD=?GBP");`, then is the doInBackground don't forget to use `urls[0]` as in my code – jbihan Aug 30 '13 at 18:25
  • but I'm not using different method than other answer. I'm using your current answer only – John Jared Aug 30 '13 at 18:27
  • please edit your answer that you mean, because now I have no requestURL – John Jared Aug 30 '13 at 18:28
  • I know, but in your update you wrote `new usdjson().execute();`, which is wrong because you are supposed to pass a URL in the `execute`. Update that with my answer above – jbihan Aug 30 '13 at 18:28
  • In button click, do `URL requestUrl = new URL("http://www.google.com/ig/calculator?hl=en&q=1USD=?GBP");`, then `new usdjson().execute(requestUrl);` – jbihan Aug 30 '13 at 18:29
  • still closes the app. umm in the logcat I checked, this line is what missin my app around object = new JSONObject(result); – John Jared Aug 30 '13 at 18:30
  • I really don't understand your comment sorry. HttpPost is used in `doInBackground`, and use the url you send in parameter, check my code. What I just wrote above is used in the `onClick` method – jbihan Aug 30 '13 at 18:33
  • `HttpPost httppost = new HttpPost(urls[0]);` – jbihan Aug 30 '13 at 18:34
  • Sorry buddy, I can't help you more right now, I am going to have a baby in a few hours, so I really have to go :) Good luck with you app, and don't forget to reward me if it works ;) – jbihan Aug 30 '13 at 18:35
  • The constructor HttpPost(URL) is undefined – John Jared Aug 30 '13 at 18:36
  • 1
    sorry for troubling you x.x .. Good luck, and welcome to your new baby :DD – John Jared Aug 30 '13 at 18:36
  • Use urls[0].toString(). Sorry now I really have to go now... Thanks! – jbihan Aug 30 '13 at 18:38
1

AsyncTask is not the best way in this case, try:

private void convert() {
    new Thread(new Runnable() {

        @Override
        public void run() {
            String url = "http://www.google.com/ig/calculator?hl=en&q="+amount+"GBP=?USD";

            String request = "THE RESULT OF YOUR HTTP REQUEST";

            try {
                JSONObject jsonObject = new JSONObject(request);

                final String result = jsonObject.getString("rhs");

                handler.post(new Runnable() {

                    @Override
                    public void run() {
                        value.setText(result);
                    }

                });

            } catch (JSONException e) {
                e.printStackTrace();
            }

        }

    }).start();
}
Ali Alnoaimi
  • 2,278
  • 2
  • 21
  • 31